ICU-2655 update with code review comments

X-SVN-Rev: 12125
This commit is contained in:
Ram Viswanadha 2003-05-27 23:38:29 +00:00
parent bd9ba07fe7
commit ac20b8cf38
2 changed files with 197 additions and 154 deletions

View file

@ -6,7 +6,7 @@
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/localeconverter/CalculateCRC32.java,v $
* $Date: 2003/05/19
* $Revision: 1.1 $
* $Revision: 1.2 $
*
******************************************************************************
*/
@ -15,7 +15,8 @@ package com.ibm.icu.dev.tool.localeconverter;
import java.math.*;
/* The code is from http://www.theorem.com/java/CRC32.java
/*
* The code is from http://www.theorem.com/java/CRC32.java
* Calculates the CRC32 - 32 bit Cyclical Redundancy Check
* <P> This check is used in numerous systems to verify the integrity
* of information. It's also used as a hashing function. Unlike a regular

View file

@ -6,7 +6,7 @@
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/localeconverter/XLIFF2ICUConverter.java,v $
* $Date: 2003/05/19
* $Revision: 1.1 $
* $Revision: 1.2 $
*
******************************************************************************
*/
@ -14,24 +14,14 @@
package com.ibm.icu.dev.tool.localeconverter;
import com.ibm.icu.dev.tool.UOption;
import com.ibm.icu.dev.tool.xmlcomparator.XMLComparator;
// DOM imports
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
// SAX2 imports
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
// Needed JAXP classes
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@ -39,7 +29,6 @@ import java.io.*;
import java.util.*;
public class XLIFF2ICUConverter {
// Command-line options set these:
protected String sourceDir;
protected String fileName;
protected String encoding;
@ -56,19 +45,17 @@ public class XLIFF2ICUConverter {
private static final int DESTDIR = 3;
private static final int ENCODING = 4;
private static final int FILENAME = 5;
private static final UOption[] options = new UOption[] {
UOption.HELP_H(),
UOption.HELP_QUESTION_MARK(),
UOption.SOURCEDIR(),
UOption.DESTDIR(),
UOption.ENCODING(),
UOption.DEF( "fileName", 'f', UOption.REQUIRES_ARG),
};
private static int tabCount = 0;
private static PrintWriter[] writer2;
private static OutputStreamWriter[] os;
private static ArrayList[] buf;
private static ArrayList bundleLang;
private static ArrayList bundleName;
private static ArrayList bundleList;
@ -98,9 +85,12 @@ public class XLIFF2ICUConverter {
private static final String EXTERNALFILE = "external-file";
private static final String CRC = "crc";
private static final String LINESEP = System.getProperty("line.separator");
private static final String BOM = "\uFEFF";
public static void main(String[] args) {
XLIFF2ICUConverter convert = new XLIFF2ICUConverter();
convert.processArgs(args);
XLIFF2ICUConverter cnv = new XLIFF2ICUConverter();
cnv.processArgs(args);
}
private void processArgs(String[] args) {
@ -117,53 +107,44 @@ public class XLIFF2ICUConverter {
if(options[ENCODING].doesOccur) {
encoding = options[ENCODING].value;
}
if(options[FILENAME].doesOccur){
fileName = options[FILENAME].value;
} else {
System.out.println("\nPlease use \"-f filename\" to specify the file.");
usage();
System.exit(0);
}
for (int i = 0; i < remainingArgc; i++) {
tabCount = 0;
convert(args[i]);
}
}
private void convert(String fileName) {
xmlfileName = getFullPath(false,fileName);
bundleName = new ArrayList();
bundleLang = new ArrayList();
bundleList = new ArrayList();
createRB(xmlfileName);
bundleLen = bundleList.size();
if(bundleLen == 0) {
boolean b;
b = bundleList.add(getFullPath(true, fileName));
if(b==false){
throw new RuntimeException("Could add "+fileName + "to bundleList");
}
int lastIndex = fileName.lastIndexOf('.', fileName.length());
b = bundleName.add(fileName.substring(0, lastIndex));
if(b==false){
throw new RuntimeException("Could add "+fileName.substring(0, lastIndex) + "to bundleList");
}
bundleLen++;
}
os = new OutputStreamWriter[bundleLen];
writer2 = new PrintWriter[bundleLen];
try {
for(int s = 0; s < bundleLen; s++) {
os[s] = new OutputStreamWriter(new FileOutputStream((String)bundleList.get(s)), "UTF-8");
writer2[s] = new PrintWriter((OutputStreamWriter)os[s]);
}
} catch(Exception e) {
e.printStackTrace();
buf = new ArrayList[bundleLen];
for(int s = 0; s < bundleLen; s++) {
buf[s] = new ArrayList();
}
doc = parse(xmlfileName);
for(int s = 0; s < bundleLen; s++){
try{
writer2[s].close();
os[s].close();
} catch(Exception e) {
e.printStackTrace();
}
}
wirteAll();
}
private void usage() {
@ -174,27 +155,24 @@ public class XLIFF2ICUConverter {
"Options:\n"+
"-s or --sourcedir source directory for files followed by path, default is current directory.\n" +
"-d or --destdir destination directory, followed by the path, default is current directory.\n" +
"-f file name e.g. myResources.xml" +
"-h or -? or --help this usage text.\n"+
"example: XLIFF2ICUConverter -s xxx -d yyy -f myResources.xml");
"example: XLIFF2ICUConverter -s xxx -d yyy myResources.xml");
}
/*true: The file returned is txt*/
/*false:The file returned is xml*/
private String getFullPath(boolean fileType, String fName){
String str;
int lastIndex = fName.lastIndexOf('.', fName.length());
if (fileType == true) {
if (destDir != null && fName != null) {
str = destDir + "\\" + fName.substring(0, lastIndex) + ".txt";
str = destDir + File.separator + fName.substring(0, lastIndex) + ".txt";
} else {
str = System.getProperty("user.dir") + "\\" + fName.substring(0, lastIndex) + ".txt";
str = System.getProperty("user.dir") + File.separator + fName.substring(0, lastIndex) + ".txt";
}
} else {
if(sourceDir != null && fName != null) {
str = sourceDir + "\\" + fName.substring(0, lastIndex) + ".xml";
str = sourceDir + File.separator + fName.substring(0, lastIndex) + ".xlf";
} else {
str = System.getProperty("user.dir") + "\\" + fName.substring(0, lastIndex) + ".xml";
str = System.getProperty("user.dir") + File.separator + fName.substring(0, lastIndex) + ".xlf";
}
}
return str;
@ -241,8 +219,8 @@ public class XLIFF2ICUConverter {
Node attribute = attributes.item(i);
if (attribute.getNodeName().equals(RESTYPE)) {
resType = attribute.getNodeValue();
if (resType.equals(ARRAYS)) {
isIntvector = checkIV(doc);
if (resType.equals(INTVECTOR)) {
isIntvector = true;
}
} else if (attribute.getNodeName().equals(RESNAME)) {
resName = attribute.getNodeValue();
@ -251,27 +229,23 @@ public class XLIFF2ICUConverter {
} else if (attribute.getNodeName().equals(CRC)) {
crc = attribute.getNodeValue();
}
}
}
if(doc.getNodeName().equals(GROUPS) && doc.getParentNode().getNodeName().equals(BODY)) {
transID = -1;
for(int s = 0; s < bundleLen; s++){
Calendar c = Calendar.getInstance();
Date d = c.getTime();
writer2[s].print('\uFEFF');
/*Output the information about which tool generates the file,
/*when it file is generated and from which source it is generated*/
writer2[s].println("// ***************************************************************************");
writer2[s].println("// *");
writer2[s].println("// * Tool: com.ibm.icu.dev.tool.localeconverter.XLIFF2ICUConverter.java");
writer2[s].println("// * Date & Time: " + c.get(Calendar.YEAR) + "/" + (c.get(Calendar.MONTH)+1) + "/" + c.get(Calendar.DAY_OF_MONTH) + " " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE));
writer2[s].println("// * Source File: " + fileName);
writer2[s].println("// *");
writer2[s].println("// ***************************************************************************");
writer2[s].println("");
writer2[s].println("");
writer2[s].println((String)bundleName.get(s) + "{");
writer2[s].flush();
buf[s].add("// ***************************************************************************" + LINESEP);
buf[s].add("// *" + LINESEP);
buf[s].add("// * Tool: com.ibm.icu.dev.tool.localeconverter.XLIFF2ICUConverter.java" + LINESEP);
buf[s].add("// * Date & Time: " + c.get(Calendar.YEAR) + "/" + (c.get(Calendar.MONTH)+1) + "/" + c.get(Calendar.DAY_OF_MONTH) + " " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE)+ LINESEP);
buf[s].add("// * Source File: " + fileName + LINESEP);
buf[s].add("// *" + LINESEP);
buf[s].add("// ***************************************************************************" + LINESEP);
buf[s].add(LINESEP);
buf[s].add(LINESEP);
buf[s].add((String)bundleName.get(s) + "{" + LINESEP);
}
} else if (doc.getNodeName().equals(GROUPS)){
transID = -1;
@ -279,15 +253,13 @@ public class XLIFF2ICUConverter {
writeTabs();
tabCount++;
for(int s = 0; s < bundleLen; s++){
writer2[s].println(resName + ":" + resType + "{");
writer2[s].flush();
buf[s].add(resName + ":" + resType + "{" + LINESEP);
}
} else {
writeTabs();
tabCount++;
for(int s = 0; s < bundleLen; s++){
writer2[s].println(resName + ":" + INTVECTOR + "{");
writer2[s].flush();
buf[s].add(resName + ":" + INTVECTOR + "{" + LINESEP);
}
}
} else if (doc.getNodeName().equals(TRANSUNIT)||doc.getNodeName().equals(BINUNIT)){
@ -300,20 +272,17 @@ public class XLIFF2ICUConverter {
if (resType.equals(STRINGS)||resType.equals(BIN)) {
for(int s = 0; s < bundleLen; s++){
writer2[s].print(resName + ":" + resType + "{\"");
writer2[s].flush();
buf[s].add(resName + ":" + resType + "{\"");
}
} else if (resType.equals(INTS) && isIntvector){
} else {
for(int s = 0; s < bundleLen; s++){
writer2[s].print(resName + ":" + resType + "{");
writer2[s].flush();
buf[s].add(resName + ":" + resType + "{");
}
}
} else if (doc.getNodeName().equals(EXTERNALFILE)) {
for(int s = 0; s < bundleLen; s++){
writer2[s].print("\"" + resValue + "\"");
writer2[s].flush();
buf[s].add("\"" + resValue + "\"");
}
}
@ -328,25 +297,21 @@ public class XLIFF2ICUConverter {
tabCount--;
writeTabs();
for(int s = 0; s < bundleLen; s++){
writer2[s].println("}");
writer2[s].flush();
buf[s].add("}" + LINESEP);
}
isIntvector = false;
}else if (doc.getNodeName().equals(TRANSUNIT)||doc.getNodeName().equals(BINUNIT)){
if (resType.equals(STRINGS)||resType.equals(BIN)) {
for(int s = 0; s < bundleLen; s++){
writer2[s].println("\"}");
writer2[s].flush();
buf[s].add("\"}" + LINESEP);
}
} else if (resType.equals(INTS)&&isIntvector){
for(int s = 0; s < bundleLen; s++){
writer2[s].println(",");
writer2[s].flush();
buf[s].add("," + LINESEP);
}
} else {
for(int s = 0; s < bundleLen; s++){
writer2[s].println("}");
writer2[s].flush();
buf[s].add("}" + LINESEP);
}
}
}
@ -378,22 +343,11 @@ public class XLIFF2ICUConverter {
if (transID == -1) {
//CRC32 check
if (!crc.equals("")){
if ((int)(resValue.charAt(0))!= 10){
if(Integer.parseInt(crc, 10) != CalculateCRC32.computeCRC32(resValue)) {
System.out.println("crc error! Please check.");
for(int s = 0; s < bundleLen; s++){
try{
writer2[s].close();
os[s].close();
} catch(Exception e) {
e.printStackTrace();
}
new File((String)bundleList.get(s)).delete();
}
System.exit(0);
System.exit(1);
} else {
crc = "";
}
@ -401,14 +355,12 @@ public class XLIFF2ICUConverter {
}
for(int s = 0; s < bundleLen; s++){
if ((int)(resValue.charAt(0))!= 10){
writer2[s].print(resValue);
writer2[s].flush();
buf[s].add(resValue);
}
}
} else {
if ((int)(resValue.charAt(0))!= 10){
writer2[transID].print(resValue);
writer2[transID].flush();
buf[transID].add(resValue);
transID++;
}
}
@ -417,52 +369,81 @@ public class XLIFF2ICUConverter {
default:
System.err.println("Unrecongized node type");
}
}
}
//check intvector
private boolean checkIV(Node doc){
NodeList nList = doc.getChildNodes();
int len = nList.getLength();
boolean flag = true; //true for intvector, false for others
String resType = "";
String resName = "";
if(len == 1 && nList.item(0).getNodeType()==Node.TEXT_NODE){
flag = false;
} else {
for (int i = 0; i < len; i++) {
Node n = nList.item(i);
if(n.getNodeType() == Node.ELEMENT_NODE) {
NamedNodeMap attributes = n.getAttributes();
int attrCount = attributes.getLength();
for (int j = 0; j < attrCount; j++) {
Node attribute = attributes.item(j);
if (attribute.getNodeName().equals(RESTYPE)) {
resType = attribute.getNodeValue();
}
if (attribute.getNodeName().equals(RESNAME)) {
resName = attribute.getNodeValue();
}
}
if(resType.equals(INTS)&&resName.equals("")) {
flag = flag & true;
} else {
flag = flag & false;
}
}
}
/**
* Utility method to translate a String filename to URL.
*
* Note: This method is not necessarily proven to get the
* correct URL for every possible kind of filename; it should
* be improved. It handles the most common cases that we've
* encountered when running Conformance tests on Xalan.
* Also note, this method does not handle other non-file:
* flavors of URLs at all.
*
* If the name is null, return null.
* If the name starts with a common URI scheme (namely the ones
* found in the examples of RFC2396), then simply return the
* name as-is (the assumption is that it's already a URL)
* Otherwise we attempt (cheaply) to convert to a file:/// URL.
*
* @param String local path\filename of a file
* @return a file:/// URL, the same string if it appears to
* already be a URL, or null if error
*/
private static String filenameToURL(String filename)
{
// null begets null - something like the commutative property
if (null == filename)
return null;
// Don't translate a string that already looks like a URL
if (filename.startsWith("file:")
|| filename.startsWith("http:")
|| filename.startsWith("ftp:")
|| filename.startsWith("gopher:")
|| filename.startsWith("mailto:")
|| filename.startsWith("news:")
|| filename.startsWith("telnet:")
)
return filename;
File f = new File(filename);
String tmp = null;
try
{
// This normally gives a better path
tmp = f.getCanonicalPath();
}
return flag;
catch (IOException ioe)
{
// But this can be used as a backup, for cases
// where the file does not exist, etc.
tmp = f.getAbsolutePath();
}
// URLs must explicitly use only forward slashes
if (File.separatorChar == '\\') {
tmp = tmp.replace('\\', '/');
}
// Note the presumption that it's a file reference
// Ensure we have the correct number of slashes at the
// start: we always want 3 /// if it's absolute
// (which we should have forced above)
if (tmp.startsWith("/"))
return "file://" + tmp;
else
return "file:///" + tmp;
}
private void createRB(String docsrc) {
boolean tag = false;
String urls = XMLComparator.filenameToURL(docsrc);
String urls = filenameToURL(docsrc);
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
dfactory.setNamespaceAware(true);
// This is used to suppress validation warnings
ErrorHandler nullHandler = new ErrorHandler() {
public void warning(SAXParseException e) throws SAXException {/*System.err.println("Warning: " + e.getMessage());*/}
public void error(SAXParseException e) throws SAXException {System.err.println("Error: " + e.getMessage());}
@ -472,13 +453,10 @@ public class XLIFF2ICUConverter {
};
try {
// First, attempt to parse as XML (preferred)...
DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
docBuilder.setErrorHandler(nullHandler);
doc = docBuilder.parse(new InputSource(urls));
//if (ts == null), it indicates that there is no transltion in the xml file. use "original" as the name of the output file.
//if (ts != null), it indicates that there are translation items in the xml file. use "package_xx_YY" as the name of the output file.
String pkg = "";
String f = "";
String lg = "";
@ -503,9 +481,18 @@ public class XLIFF2ICUConverter {
if(pkg.equals("")) {
boolean b;
b = bundleLang.add(lg);
if(b==false){
throw new RuntimeException("Could not add "+lg+" to bundleLang");
}
int lastIndex = f.lastIndexOf('.', f.length());
b = bundleName.add(f.substring(0, lastIndex));
if(b==false){
throw new RuntimeException("Could not add "+f.substring(0, lastIndex)+" to bundleName");
}
b = bundleList.add(getFullPath(true,f));
if(b==false){
throw new RuntimeException("Could not add "+getFullPath(true,f)+" to bundleList");
}
} else {
NodeList nlist = doc.getElementsByTagName(TRANSUNIT);
for(int i = 0; i < nlist.getLength(); i++) {
@ -531,8 +518,17 @@ public class XLIFF2ICUConverter {
String name = pkg + "_" + lang;
boolean b;
b = bundleLang.add(lang);
if(b==false){
throw new RuntimeException("Could not add "+lang+" to bundleLang");
}
b = bundleName.add(name);
if(b==false){
throw new RuntimeException("Could not add "+name+" to bundleName");
}
b = bundleList.add(getFullPath(true, name + ".txt"));
if(b==false){
throw new RuntimeException("Could not add "+getFullPath(true, name + ".txt")+" to bundleList");
}
tag = true;
}
}
@ -549,7 +545,7 @@ public class XLIFF2ICUConverter {
}
private Document parse(String docsrc) {
String urls = XMLComparator.filenameToURL(docsrc);
String urls = filenameToURL(docsrc);
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
dfactory.setNamespaceAware(true);
@ -568,19 +564,65 @@ public class XLIFF2ICUConverter {
writeRB(doc);
}
catch (Throwable se) {
System.out.println("ERROR :" + se.toString());
}
return doc;
}
//Utilities
private static void writeTabs(){
int i=0;
for(;i<=tabCount;i++){
for(int s = 0; s < bundleLen; s++){
writer2[s].print(" ");
writer2[s].flush();
buf[s].add(" ");
}
}
}
private static void wirteAll() {
FileOutputStream file = null;
BufferedOutputStream buffer = null;
for(int s = 0; s < bundleLen; s++){
try {
file = new FileOutputStream((String)bundleList.get(s));
buffer = new BufferedOutputStream(file);
} catch (Exception ie) {
System.out.println("ERROR :" + ie.toString());
return;
}
writeBOM(buffer, "UTF-8");
for(int t = 0; t < buf[s].size(); t++){
WriteLine(buffer, (String)(buf[s].get(t)), "UTF-8");
}
try {
buffer.flush();
buffer.close();
file.close();
} catch (IOException ie) {
System.err.println(ie);
return;
}
}
}
private static void WriteLine(BufferedOutputStream buffer, String line, String charSet) {
try {
byte[] bytes = line.getBytes(charSet);
buffer.write(bytes, 0, bytes.length);
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
}
private static void writeBOM(BufferedOutputStream buffer, String charSet) {
try {
byte[] bytes = BOM.getBytes(charSet);
buffer.write(bytes, 0, bytes.length);
} catch(Exception e) {
System.err.println(e);
System.exit(1);
}
}
}