/* TokODDListResourceBundle */
package com.company.g11n.ExtSamp.tokenizer;
import com.g11ntoolkit.levblock.TokContext;
import com.g11ntoolkit.levblock.XLEntry;
import com.g11ntoolkit.strfile.EmptyStrFile;
import com.g11ntoolkit.strfile.StrFile;
import com.g11ntoolkit.token.MalformedToken;
import com.g11ntoolkit.token.Token;
import com.g11ntoolkit.tokenizer.FileTokenizerError;
import com.g11ntoolkit.tokenizer.FileTokRunError;
import com.g11ntoolkit.tokenizer.TokListResourceBundle;
import com.g11ntoolkit.tokfile.TokFile;
import com.g11ntoolkit.util.Arguments;
import gnu.regexp.RE;
import gnu.regexp.REException;
import gnu.regexp.REMatch;
import gnu.regexp.RESyntax;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.text.StringCharacterIterator;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
//------------------------------------------------------------
/** Tokenizes the specified input file as though it were a ListResourceBundle
file with the slightly strange coding.
*
It uses the super class to do most of the work. The main reason for this class is to handle the parsing to find the contents
section of the file.
Normally, the contents of a ListResourceBundle
is defined as a static variable in the class. Just to be different, the ODD folks decided to make life difficult by defining the getContents
method so that it checks to see if the static variable is null and, if it is, calls a buildContents
method to assign the static information to the contents
variable.
In doing this the original static contents
variable is set to null then later assigned the values. So here we need to check if the static variable is assigned a null. Then go looking for the real assignment.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
*This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*See License Agreement.
*/ //------------------------------------------------------------ public class TokODDListResourceBundle extends TokListResourceBundle { /** The log used for all messages from this class.**/ private static Logger log = Logger.getLogger(TokODDListResourceBundle.class.getPackage().getName()); /** The locale for the target language.**/ private static Locale targetLocale = null; /** The tokenized skeleton of the input file.**/ private static TokFile tokFile = null; /** The translatable strings extracted from the input file.**/ private static StrFile strFile = null; /** The locale for the input file.**/ private static String localeString = null; //-------------------------------------------------------------- /** Allows this tool to be run from the command line. *Sets up the environment then uses the tokenize
method to extract the strings.
It uses the super class setupTok
method to do the common work of reading the file into a string buffer.
This gets rid of all the comments in the file and only keeps the code. The file should be a syntactically correct file when finished.
* @param aFileBuffer a StringBuffer object specifying the string buffer in which to find the processing buffer * @return a StringBuffer object representing the processing buffer */ protected static StringBuffer getProcessingBuffer(StringBuffer aFileBuffer) { log.logp(Level.FINE, "TokODDListResourceBundle", "getProcessingBuffer", "Begin."); StringBuffer processingBuffer = new StringBuffer(aFileBuffer.length()); boolean inLineComment = false; boolean inBlockComment = false; boolean inQuotedString = false; StringBuffer quotedString = new StringBuffer(); char lineCommentStart1 = '/'; char lineCommentStart2 = '/'; char lineCommentEnd = '\n'; char blockCommentStart1 = '/'; char blockCommentStart2 = '*'; char blockCommentEnd1 = '*'; char blockCommentEnd2 = '/'; char quoteDelim = '"'; StringCharacterIterator ci = new StringCharacterIterator(aFileBuffer.toString()); char c = ci.first(); scan: for (char nc = ci.next(); nc != StringCharacterIterator.DONE; nc = ci.next()) { if (inQuotedString) { // Accumulate the characters in the quoted string and process it when the end is reached. if (c == '\\') { quotedString.append(c); quotedString.append(nc); nc = ci.next(); } else { quotedString.append(c); // Add character to quoted string. if (c == quoteDelim) { // This is the end of the quoted string. inQuotedString = false; processingBuffer.append(quotedString.toString()); // Add quoted string to processing buffer. } } c = nc; continue scan; } // end quoted string if (inLineComment) { // Ignore comments, but, check to see when we get to the end. if (c == lineCommentEnd) { // End of line comment. inLineComment = false; processingBuffer.append(c); } else { // Still in the line comment. } c = nc; continue scan; } // end line comment if (inBlockComment) { // Ignore comments, but, check to see when we get to the end. if (c == blockCommentEnd1 && nc == blockCommentEnd2) { // At end of block comment. Stop throwing stuff away. inBlockComment = false; nc = ci.next(); } else { // Still in the block comment. } c = nc; continue scan; } // end block comment // We are not in any of the special blocks. switch (c) { case '/': if (nc == '/') { inLineComment = true; } else if (nc == '*') { inBlockComment = true; } else { processingBuffer.append(c); processingBuffer.append(nc); } nc = ci.next(); break; case '"': quotedString = new StringBuffer(); quotedString.append(c); inQuotedString = true; quoteDelim = '"'; break; case '\'': quotedString = new StringBuffer(); quotedString.append(c); inQuotedString = true; quoteDelim = '\''; break; case '\\': processingBuffer.append(c); processingBuffer.append(nc); nc = ci.next(); break; default: processingBuffer.append(c); } c = nc; } // end scan processingBuffer.append(c); log.logp(Level.FINE, "TokODDListResourceBundle", "getProcessingBuffer", "processingBuffer: [" + processingBuffer + "]"); return processingBuffer; } //------------------------------------------------------------ /** Locates the contents section of aListResourceBundle
and returns its starting offset in the specified string.
* In order to find the contents section of the LRB we need to know what it might be called. To find this we look for the method that is called to return the contents. The object that it returns is the name of the contents section.
* @param buf a String specifying the processing buffer that contains the content section * @param start an int specifying the starting offset where to begin looking for the content section * @return an int representing the offset to the content section or -1 if no content section is found * @throws TokODDFileError when something goes wrong */ protected static int contentSectionStart(String buf, int start) throws TokODDFileError { log.logp(Level.FINE, "TokODDListResourceBundle", "contentSectionStart", "Begin"); RE exp1 = null; RE exp2 = null; RE exp2a = null; RE exp2b = null; RE exp2c = null; RE exp2d = null; RE exp2e = null; REMatch m1 = null; REMatch m2 = null; RE connull = null; int idxop = 0; int idxcl = 0; String type = ""; RESyntax res = new RESyntax(RESyntax.RE_SYNTAX_AWK); res = res.set(RESyntax.RE_CHAR_CLASSES); // Look for the getContents method to find out what the name of the contents will be. Must honor case for this search. try { exp1 = new RE("[[:space:]]+getContents()", 0, res); } catch (REException e) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "contentSectionStart", e.getMessage()); e.printStackTrace(); throw new TokODDFileError(mrb.getString("errormsg.badexpression")); } m1 = exp1.getMatch(buf, start); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "Look for getContents results in m1[" + m1 + "]"); if (m1 == null) { throw new TokODDFileError(mrb.getString("errormsg.contentsmethodnotfound")); } else { int xx = m1.getEndIndex(); try { // Look for return object; exp1 = new RE("return[[:space:]]+([^;[:space:]]*)([;[:space:]])", 0, res); // Look for return (object); exp2 = new RE("return[[:space:]]*\\([[:space:]]*([^\\)[:space:]]*)[:space:]]*\\)", 0, res); } catch (REException e) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "contentSectionStart", e.getMessage()); e.printStackTrace(); throw new TokODDFileError(mrb.getString("errormsg.badexpression")); } m2 = exp2.getMatch(buf, xx); // Look for return (object); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "Look for return (object); results in m2[" + m2 + "]"); m1 = exp1.getMatch(buf, xx); // Look for return object; log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "Look for return object; results in m1[" + m1 + "]"); if (m2 == null && m1 == null) { throw new TokODDFileError(mrb.getString("errormsg.returncontentsnotfound")); } else { if (m2 == null) { type = buf.substring(m1.getStartIndex(1),m1.getEndIndex(1)); } else { type = buf.substring(m2.getStartIndex(1),m2.getEndIndex(1)); } } // Limit this to only the name of the contents section. Some people have a habit of coding it as this.contents. if (type.lastIndexOf(".") >= 0) { type = type.substring(type.lastIndexOf(".") + 1); } log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "type[" + type + "]"); } // At this point we know what to look for to find the contents section of the LRB. if (type.toUpperCase().compareTo("NEW") == 0) { // Special case for some contents sections. idxop = buf.indexOf("{", m1.getEndIndex()); } else { // Now look for the contents section using the information from the previous search. For this one we do not need to honor case. If the return value is not found as the label of the contents section, default to "contents" and try again. If still not found, Houston we have a problem. try { // Look for static final [] ...type...=... exp2 = new RE("static[[:space:]]+final.*\\[\\].*" + type + ".*=", RE.REG_ICASE, res); // Look for static ...[]...type...=... exp2a = new RE("static[[:space:]]+.*\\[\\].*" + type + ".*=", RE.REG_ICASE, res); // Look for static final...type...[]...= exp2b = new RE("static[[:space:]]+final.*" + type + ".*\\[\\].*=", RE.REG_ICASE, res); // Look for static ...type...[]...=... exp2c = new RE("static[[:space:]]+.*" + type + ".*\\[\\].*=", RE.REG_ICASE, res); // Look for ...type []...=... exp2d = new RE(".*" + type + "[[:space:]]*\\[\\].*=", RE.REG_ICASE, res); // Look for ...[] type =... exp2e = new RE(".*\\[\\][[:space:]]*" + type + "[[:space:]]*=", RE.REG_ICASE, res); } catch (REException e) { // There was something wrong with the type that caused a bad expression to be built. We will now try to use just plain old contents for the search. type = "contents"; try { // Look for static final [] ...type...=... exp2 = new RE("static[[:space:]]+final.*\\[\\].*" + type + ".*=", RE.REG_ICASE, res); // Look for static ...[]...type...=... exp2a = new RE("static[[:space:]]+.*\\[\\].*" + type + ".*=", RE.REG_ICASE, res); // Look for static final...type...[]...= exp2b = new RE("static[[:space:]]+final.*" + type + ".*\\[\\].*=", RE.REG_ICASE, res); // Look for static ...type...[]...=... exp2c = new RE("static[[:space:]]+.*" + type + ".*\\[\\].*=", RE.REG_ICASE, res); // Look for ...type []...=... exp2d = new RE(".*" + type + "[[:space:]]*\\[\\].*=", RE.REG_ICASE, res); // Look for ...[] type =... exp2e = new RE(".*\\[\\][[:space:]]*" + type + "[[:space:]]*=", RE.REG_ICASE, res); } catch (REException e2) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "contentSectionStart", e.getMessage()); e2.printStackTrace(); throw new TokODDFileError(mrb.getString("errormsg.badexpression")); } } m2 = exp2.getMatch(buf, start); REMatch m2a = exp2a.getMatch(buf, start); REMatch m2b = exp2b.getMatch(buf, start); REMatch m2c = exp2c.getMatch(buf, start); REMatch m2d = exp2d.getMatch(buf, start); REMatch m2e = exp2e.getMatch(buf, start); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "type[" + type + "] m2[" + m2 + "] m2a[" + m2a + "] m2b[" + m2b + "] m2c[" + m2c + "] m2d[" + m2d + "] m2e[" + m2e + "]"); if (m2 == null && m2a == null && m2b == null && m2c == null && m2d == null && m2e == null) { type = "contents"; m2 = exp2.getMatch(buf, start); m2a = exp2a.getMatch(buf, start); m2b = exp2b.getMatch(buf, start); m2c = exp2c.getMatch(buf, start); m2d = exp2d.getMatch(buf, start); m2e = exp2e.getMatch(buf, start); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "type[" + type + "] m2[" + m2 + "] m2a[" + m2a + "] m2b[" + m2b + "] m2c[" + m2c + "] m2d[" + m2d + "] m2e[" + m2e + "]"); if (m2 == null && m2a == null && m2b == null && m2c == null && m2d == null && m2e == null) { throw new TokODDFileError(mrb.getString("errormsg.contentsnotfound")); } } if (m2 != null) { idxop = m2.getEndIndex(); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "m2 adjusted idxop[" + idxop + "] m2 end[" + m2.getEndIndex() + "]"); } else if (m2a != null) { idxop = m2a.getEndIndex(); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "m2a adjusted idxop[" + idxop + "] m2a end[" + m2a.getEndIndex() + "]"); } else if (m2b != null) { idxop = m2b.getEndIndex(); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "m2b adjusted idxop[" + idxop + "] m2b end[" + m2b.getEndIndex() + "]"); } else if (m2c != null) { idxop = m2c.getEndIndex(); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "m2c adjusted idxop[" + idxop + "] m2c end[" + m2c.getEndIndex() + "]"); } else if (m2d != null) { idxop = m2d.getEndIndex(); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "m2d adjusted idxop[" + idxop + "] m2d end[" + m2d.getEndIndex() + "]"); } else { idxop = m2e.getEndIndex(); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "m2e adjusted idxop[" + idxop + "] m2e end[" + m2e.getEndIndex() + "]"); } } log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "idxop[" + idxop + "]"); int nsc = buf.indexOf(";", idxop); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "nsc[" + nsc + "][" + buf.substring(idxop, nsc).trim() + "]"); if (buf.substring(idxop, nsc).trim().compareTo("null") == 0) { try { // Look for type = new ... connull = new RE(type + "[[:space:]]+=[[:space:]]+new.*[[:space:]]+{", RE.REG_ICASE, res); REMatch cn = connull.getMatch(buf, start); log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "cn[" + cn + "]"); if (cn != null) { idxop = cn.getEndIndex(); } else { idxop = -1; } log.logp(Level.FINEST, "TokODDListResourceBundle", "contentSectionStart", "idxop[" + idxop + "]"); } catch (REException e2) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "contentSectionStart", e2.getMessage()); e2.printStackTrace(); throw new TokODDFileError(mrb.getString("errormsg.badexpression")); } } log.logp(Level.FINE, "TokODDListResourceBundle", "contentSectionStart", "final idxop[" + idxop + "]"); return idxop; } //------------------------------------------------------------ /** Tokenizes a section of theListResourceBundle
that may contain strings.
* The section of the file processed may not be the contents section. The section of the file is appended to the TokFile
with an appropriate token inserted for each string found. The strings are appended to the StrFile
with their tokens. No attempt is made to find elements of an array. The entire array of strings is treated as a single string.
If the entire string is numeric it is ignored and left intact in the file.
*If the string is found in a System.out.println
statement and it is a quoted string, an error is reported but the string is not replaced with a token nor is it written to the StrFile
. At some later time we may decide to tokenize these strings.
ListResourceBundle
and extracts the translatable values.
* This looks for quoted strings in the specified string. When it finds a quoted string it replaces it with a token and adds the token and extracted string to the specified StrFile
. It adds the tokenized string to the specified TokFile
.
ListResourceBundle
that has the pattern of a System.out.println
.
* The section of the file is updated with the appropriate token inserted and returned.
* @param keyvalStr a String specifying the key/value string * @param m a REMatch object specifying the regular expression match * @return a String representing the tokenized key/value string * @throws TokODDFileError when something goes wrong */ protected static String tokSOP(String keyvalStr, REMatch m) throws TokODDFileError { log.logp(Level.FINER, "TokODDListResourceBundle", "tokSOP", "found sop pattern"); log.logp(Level.FINER, "TokODDListResourceBundle", "tokSOP", "key: [" + "NoKey" + "] value: [" + m.toString(1) + "]"); tokContext = new TokContext(theContextFileName, "NoKey", null, null); int valstart = m.getStartIndex(1); int valend = m.getEndIndex(1); String val = keyvalStr.substring(valstart, valend); if (val.indexOf("\"") >= 0) { // String has some part of it as a quoted string so Tok it. Otherwise, ignore it. // Do not remove the concats since these may be variables so may be needed in the final version of the string. // Since this is truly an I18N bug we decided to only report that it is there and not Tok it. Object[] c = { m.toString() }; log.logrb(Level.INFO, "TokODDListResourceBundle", "tokSOP", "com.g11ntoolkit.resources.messages", "errormsg.soppattern", c); } return keyvalStr; } //------------------------------------------------------------ /** Parses a key/value string to find the value strings that need to be extracted. *This looks for quoted value strings in the specified key/value string. When it finds a quoted value string it replaces it with a token and adds the token and the extracted string to the specified StrFile
and adds the tokenized record to the TokFile
file.
ListResourceBundle
that has the pattern of a key with a string array for a value.
* The section of the file is updated with the appropriate token inserted and returned.
* @param keyvalStr a String specifying the key/value string * @param m a REMatch object specifying the regular expression match * @return a String representing the tokenized key/value string * @throws TokODDFileError when something goes wrong */ protected static String tokKSA(String keyvalStr, REMatch m) throws FileTokenizerError, TokODDFileError { log.logp(Level.FINER, "TokODDListResourceBundle", "tokKSA", "found ksa pattern"); log.logp(Level.FINER, "TokODDListResourceBundle", "tokKSA", "key: [" + m.toString(1).trim() + "] value: [" + m.toString(2) + "]"); tokContext = new TokContext(theContextFileName, m.toString(1).trim(), null, null); RE vs = null; RESyntax res = new RESyntax(RESyntax.RE_SYNTAX_AWK); res = res.set(RESyntax.RE_CHAR_CLASSES); res = res.set(RESyntax.RE_DOT_NEWLINE); try { // Look for a value set. vs = new RE("([^{]*)({.*})(.*)", 0, res); } catch (REException e) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "tokKSA", e.toString()); e.printStackTrace(); throw new TokODDFileError(mrb.getString("errormsg.badexpression")); } int qscount = 0; String val = new String(); int valstart = m.getStartIndex(2); int valend = valstart; String s = null; String workVal = m.toString(2); REMatch mvs = vs.getMatch(workVal); if (!(mvs == null)) { log.logp(Level.FINER, "TokODDListResourceBundle", "tokKSA", "valstart: [" + valstart + "] valend: [" + valend + "]"); log.logp(Level.FINER, "TokODDListResourceBundle", "tokKSA", "mvs(2) start: [" + mvs.getStartIndex(2) + "] mvs(2) end: [" + mvs.getEndIndex(2) + "]"); valstart += mvs.getStartIndex(2); valend += mvs.getEndIndex(2); val = keyvalStr.substring(valstart, valend); // Tokenize the value. try { XLEntry ts = new XLEntry(targetLocale, cleanConcats(val)); ts.clean(); ts.setContext(tokContext); strFile.append(new com.g11ntoolkit.token.Token(token.nextToken()), ts); tokFile.setContext(tokContext, new com.g11ntoolkit.token.Token(token.getToken())); keyvalStr = keyvalStr.substring(0, valstart) + token.getDecoratedToken() + keyvalStr.substring(valend); } catch (MalformedToken mt) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "tokKSA", mt.toString()); mt.printStackTrace(); } } return keyvalStr; } //------------------------------------------------------------ /** Tokenizes a section of theListResourceBundle
that has the pattern of a key with a quoted string for a value.
* The section of the file is updated with the appropriate token inserted and returned.
* @param keyvalStr a String specifying the key/value string * @param m a REMatch object specifying the regular expression match * @return a String representing the tokenized key/value string * @throws TokODDFileError when something goes wrong */ protected static String tokKQV(String keyvalStr, REMatch m) throws FileTokenizerError, TokODDFileError { log.logp(Level.FINER, "TokODDListResourceBundle", "tokKQV", "found kqv pattern"); log.logp(Level.FINER, "TokODDListResourceBundle", "tokKQV", "key: [" + m.toString(1).trim() + "] value: [" + m.toString(2) + "]"); tokContext = new TokContext(theContextFileName, m.toString(1).trim(), null, null); RE qs = null; RE vs = null; RESyntax res = new RESyntax(RESyntax.RE_SYNTAX_AWK); res = res.set(RESyntax.RE_CHAR_CLASSES); res = res.set(RESyntax.RE_DOT_NEWLINE); try { // Look for quoted strings separated either by commas. This is used to determine if a value is a single element or an array of elements. qs = new RE("(\"[^\"]*\")[^\"]*", 0, res); // Look for a value set. vs = new RE("([^{]*)({[^}]*})(.*)", 0, res); } catch (REException e) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "tokKQV", e.toString()); e.printStackTrace(); throw new TokODDFileError(mrb.getString("errormsg.badexpression")); } String val = new String(); char quoteDelim = '"'; StringBuffer quotedString = new StringBuffer(); boolean inQuotedString = false; StringCharacterIterator ci = new StringCharacterIterator(keyvalStr.substring(m.getStartIndex(2), m.getEndIndex(2))); int qsstart = m.getStartIndex(2); int qsend = 0; char c = ci.first(); scan: for (char nc = ci.next(); nc != StringCharacterIterator.DONE; nc = ci.next()) { if (inQuotedString) { // Accumulate the characters in the quoted string and process it when the end is reached. if (c == '\\') { quotedString.append(c); qsend++; quotedString.append(nc); qsend++; nc = ci.next(); } else { quotedString.append(c); // Add character to quoted string. qsend++; if (c == quoteDelim) { // This is the end of the quoted string. inQuotedString = false; } } } else { // Not in a quoted string. } means that is the end of everything. " means start a new quoted string. Set qsstart if this is the first quoted string. if (c == '}') { // End of everything. break scan; } if (c == quoteDelim && qsend <= qsstart) { // Begin the quoted string. inQuotedString = true; quotedString.append(c); qsend = qsstart + 1; } else if (qsend <= qsstart) { // No quoted string found yet so move the potential start. qsstart++; } else { // Drop the character and replace it with a blank in the current quoted string. quotedString.append(c); qsend++; if (c == quoteDelim) { inQuotedString = true; } } } // end quoted string c = nc; } // scan if (inQuotedString) { quotedString.append(c); qsend++; } val = quotedString.toString(); while (val.indexOf("@@r@@") >= 0) { val = val.substring(0, val.indexOf("@@r@@")) + " " + val.substring(val.indexOf("@@r@@") + 5); } while (val.indexOf("@@n@@") >= 0) { val = val.substring(0, val.indexOf("@@n@@")) + " " + val.substring(val.indexOf("@@n@@") + 5); } while (val.indexOf("@@f@@") >= 0) { val = val.substring(0, val.indexOf("@@f@@")) + " " + val.substring(val.indexOf("@@f@@") + 5); } // Tokenize the value. try { XLEntry ts = new XLEntry(targetLocale, cleanConcats(val)); ts.clean(); ts.setContext(tokContext); strFile.append(new com.g11ntoolkit.token.Token(token.nextToken()), ts); tokFile.setContext(tokContext, new com.g11ntoolkit.token.Token(token.getToken())); keyvalStr = keyvalStr.substring(0, qsstart) + token.getDecoratedToken() + keyvalStr.substring(qsend); } catch (MalformedToken mt) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "tokKQV", mt.toString()); mt.printStackTrace(); } return keyvalStr; } //------------------------------------------------------------ /** Tokenizes a section of theListResourceBundle
that has the pattern of a key with multiple values.
* The section of the file is updated with the appropriate token inserted and returned.
* @param keyvalStr a String specifying the key/value string * @param m a REMatch object specifying the regular expression match * @return a String representing the tokenized key/value string * @throws TokODDFileError when something goes wrong */ protected static String tokKMV(String keyvalStr, REMatch m) throws FileTokenizerError { log.logp(Level.FINER, "TokODDListResourceBundle", "tokKMV", "found kmv pattern"); log.logp(Level.FINER, "TokODDListResourceBundle", "tokKMV", "key: [" + m.toString(1).trim() + "] value: [" + m.toString(2) + "]"); tokContext = new TokContext(theContextFileName, m.toString(1).trim(), null, null); int valstart = m.getStartIndex(2); int valend = m.getEndIndex(2); String val = keyvalStr.substring(valstart, valend); // Tokenize the value. try { XLEntry ts = new XLEntry(targetLocale, cleanConcats(val)); ts.clean(); ts.setContext(tokContext); strFile.append(new com.g11ntoolkit.token.Token(token.nextToken()), ts); tokFile.setContext(tokContext, new com.g11ntoolkit.token.Token(token.getToken())); keyvalStr = keyvalStr.substring(0, valstart) + token.getDecoratedToken() + keyvalStr.substring(valend); } catch (MalformedToken mt) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "tokKMV", mt.toString()); mt.printStackTrace(); } return keyvalStr; } //------------------------------------------------------------ /** Tokenizes a section of theListResourceBundle
that has the pattern of a key with a non-quoted string for a value.
* The section of the file is updated with the appropriate token inserted and returned.
*This pattern is important for things like font specifications and sizing information. These things tend to be specified as something other than a quoted string. It is not consistent as to how they are specified so we use this general pattern to describe them.
* @param keyvalStr a String specifying the key/value string * @param m a REMatch object specifying the regular expression match * @return a String representing the tokenized key/value string * @throws TokODDFileError when something goes wrong */ protected static String tokKV(String keyvalStr, REMatch m) throws TokODDFileError { log.logp(Level.FINER, "TokODDListResourceBundle", "tokKV", "found kv pattern"); log.logp(Level.FINER, "TokODDListResourceBundle", "tokKV", "key: [" + m.toString(1).trim() + "] value: [" + m.toString(2) + "]"); tokContext = new TokContext(theContextFileName, m.toString(1).trim(), null, null); int vstart = m.getStartIndex(2); int vend = m.getEndIndex(2); // Tokenize the value. try { XLEntry ts = new XLEntry(targetLocale, keyvalStr.substring(vstart, vend)); ts.clean(); ts.setContext(tokContext); strFile.append(new com.g11ntoolkit.token.Token(token.nextToken()), ts); tokFile.setContext(tokContext, new com.g11ntoolkit.token.Token(token.getToken())); keyvalStr = keyvalStr.substring(0, vstart) + token.getDecoratedToken() + keyvalStr.substring(vend); } catch (MalformedToken mt) { log.logp(Level.SEVERE, "TokODDListResourceBundle", "tokKV", mt.toString()); mt.printStackTrace(); } return keyvalStr; } //------------------------------------------------------------ } //------------------------------------------------------------ /** Reports errors while tokenizing the file. * @version 2005/09/19 * @author Bill Rich, Wilandra Consulting LLC *TokODDFileError
object.
* @param s a String specifying the error message
*/
TokODDFileError(String s)
{
super(s);
}
}
//------------------------------------------------------------