--- /dev/null
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ * A file reader that concatenates lines
+ *
+ * @author gmcarstairs
+ *
+ */
+public class BufferedLineReader
+{
+ interface LineCleaner
+ {
+ String cleanLine(String l);
+ }
+
+ /*
+ * a reader for the file being read
+ */
+ private BufferedReader br;
+
+ /*
+ * optional handler to post-process each line as it is read
+ */
+ private LineCleaner cleaner;
+
+ /*
+ * current buffer of <bufferSize> post-processed input lines
+ */
+ private String[] buffer;
+
+ private boolean atEof;
+
+ /**
+ * Constructor
+ *
+ * @param reader
+ * @param bufferSize
+ * the number of lines to concatenate at a time while reading
+ * @param tidier
+ * an optional callback handler to post-process each line after
+ * reading
+ * @throws FileNotFoundException
+ */
+ public BufferedLineReader(BufferedReader reader, int bufferSize,
+ LineCleaner tidier)
+ throws IOException
+ {
+ br = reader;
+ buffer = new String[bufferSize];
+ cleaner = tidier;
+
+ /*
+ * load up the buffer with N-1 lines, ready for the first read
+ */
+ for (int i = 1; i < bufferSize; i++)
+ {
+ readLine();
+ }
+
+ }
+
+ /**
+ * Reads the next line from file, invokes the post-processor if one was
+ * provided, and returns the 'cleaned' line, or null at end of file.
+ *
+ * @return
+ */
+ private String readLine() // throws IOException
+ {
+ if (atEof)
+ {
+ return null;
+ }
+
+ String line = null;
+ try
+ {
+ line = br.readLine();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ if (line == null)
+ {
+ atEof = true;
+ return null;
+ }
+ if (cleaner != null)
+ {
+ line = cleaner.cleanLine(line);
+ }
+
+ /*
+ * shuffle down the lines buffer and add the new line
+ * in the last position
+ */
+ for (int i = 1; i < buffer.length; i++)
+ {
+ buffer[i - 1] = buffer[i];
+ }
+ buffer[buffer.length - 1] = line;
+ return line;
+ }
+
+ /**
+ * Returns a number of concatenated lines from the file, or null at end of
+ * file.
+ *
+ * @return
+ */
+ public String read()
+ {
+ if (readLine() == null)
+ {
+ return null;
+ }
+ StringBuilder result = new StringBuilder(100 * buffer.length);
+ for (String line : buffer)
+ {
+ if (line != null)
+ {
+ result.append(line);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * A main 'test' method!
+ *
+ * @throws IOException
+ */
+ public static void main(String[] args) throws IOException
+ {
+ String data = "Now is the winter\n" + "Of our discontent\n"
+ + "Made glorious summer\n" + "By this sun of York\n";
+ BufferedReader br = new BufferedReader(new StringReader(data));
+ BufferedLineReader reader = new BufferedLineReader(br, 3,
+ new LineCleaner()
+ {
+ @Override
+ public String cleanLine(String l)
+ {
+ return l.toUpperCase();
+ }
+ });
+ String line = reader.read();
+ String expect = "NOW IS THE WINTEROF OUR DISCONTENTMADE GLORIOUS SUMMER";
+ if (!line.equals(expect))
+ {
+ System.err.println("Fail: expected '" + expect + "', found '" + line
+ + ";");
+ }
+ else
+ {
+ System.out.println("Line one ok!");
+ }
+ line = reader.read();
+ expect = "OF OUR DISCONTENTMADE GLORIOUS SUMMERBY THIS SUN OF YORK";
+ if (!line.equals(expect))
+ {
+ System.err.println("Fail: expected '" + expect + "', found '" + line
+ + "'");
+ }
+ else
+ {
+ System.out.println("Line two ok!!");
+ }
+ line = reader.read();
+ if (line != null)
+ {
+ System.err.println("Fail: expected null at eof, got '" + line + "'");
+ }
+ else
+ {
+ System.out.println("EOF ok!!!");
+ }
+ }
+}
* @author gmcarstairs
*
*/
-public class MessageBundleChecker
+public class MessageBundleChecker implements BufferedLineReader.LineCleaner
{
/*
* regex ^"[^"]*"$
return;
}
- String[] lines = new String[bufferSize];
BufferedReader br = new BufferedReader(new FileReader(f));
- for (int i = 0; i < bufferSize; i++)
- {
- String readLine = br.readLine();
- lines[i] = stripCommentsAndTrim(readLine);
- }
+ BufferedLineReader blr = new BufferedLineReader(br, bufferSize, this);
int lineNo = 0;
-
- while (lines[bufferSize - 1] != null)
+ String line = blr.read();
+ while (line != null)
{
lineNo++;
- inspectSourceLines(path, lineNo, lines);
-
- for (int i = 0; i < bufferSize - 1; i++)
- {
- lines[i] = lines[i + 1];
- }
- lines[bufferSize - 1] = stripCommentsAndTrim(br.readLine());
+ inspectSourceLines(path, lineNo, line);
+ line = blr.read();
}
br.close();
}
- /*
- * removes anything after (and including) '//'
- */
- private String stripCommentsAndTrim(String line)
- {
- if (line != null)
- {
- int pos = line.indexOf("//");
- if (pos != -1)
- {
- line = line.substring(0, pos);
- }
- line = line.replace("\t", " ").trim();
- }
- return line;
- }
-
/**
* Look for calls to MessageManager methods, possibly split over two or more
- * lines
+ * lines that have been concatenated while parsing the file
*
* @param path
* @param lineNo
- * @param lines
+ * @param line
*/
- private void inspectSourceLines(String path, int lineNo, String[] lines)
+ private void inspectSourceLines(String path, int lineNo, String line)
{
- String lineNos = String.format("%d-%d", lineNo, lineNo + lines.length
+ String lineNos = String
+ .format("%d-%d", lineNo, lineNo + bufferSize
- 1);
- String combined = combineLines(lines);
for (String method : METHODS)
{
- int pos = combined.indexOf(method);
+ int pos = line.indexOf(method);
if (pos == -1)
{
continue;
/*
* extract what follows the opening bracket of the method call
*/
- String methodArgs = combined.substring(pos + method.length()).trim();
+ String methodArgs = line.substring(pos + method.length()).trim();
if ("".equals(methodArgs))
{
/*
if (METHOD3 == method)
{
System.out.println(String.format("Dynamic key at %s line %s %s",
- path.substring(sourcePath.length()), lineNos, combined));
+ path.substring(sourcePath.length()), lineNos, line));
continue;
}
if (messageKey == null)
{
System.out.println(String.format("Trouble parsing %s line %s %s",
- path.substring(sourcePath.length()), lineNos, combined));
+ path.substring(sourcePath.length()), lineNos, line));
continue;
}
if (!(STRING_PATTERN.matcher(messageKey).matches()))
{
System.out.println(String.format("Dynamic key at %s line %s %s",
- path.substring(sourcePath.length()), lineNos, combined));
+ path.substring(sourcePath.length()), lineNos, line));
continue;
}
return endPos == -1 ? null : key.substring(0, endPos);
}
- private String combineLines(String[] lines)
- {
- String combined = "";
- if (lines != null)
- {
- for (String line : lines)
- {
- if (line != null)
- {
- combined += line;
- }
- }
- }
- return combined;
- }
-
/**
* Loads properties from Message.properties
*
}
+ /**
+ * Remove any trailing comments, change tabs to space, and trim
+ */
+ @Override
+ public String cleanLine(String l)
+ {
+ if (l != null)
+ {
+ int pos = l.indexOf("//");
+ if (pos != -1)
+ {
+ l = l.substring(0, pos);
+ }
+ l = l.replace("\t", " ").trim();
+ }
+ return l;
+ }
+
}