001 // Copyright 2007 by Basil Vandegriend. All rights reserved.
002 package com.basilv.envgen;
003
004 import java.io.BufferedReader;
005 import java.io.IOException;
006 import java.io.StringReader;
007 import java.io.Writer;
008 import java.util.Map;
009
010 import freemarker.template.TemplateModelException;
011 import freemarker.template.TemplateTransformModel;
012
013 /**
014 * Template to format input into a form acceptable for mainframes.
015 * The formatting changes that are made are:
016 * <ul>
017 * <li>Convert tabs to spaces (4 spaces per tab)</li>
018 * <li>Trim whitespace from end of line</li>
019 * <li>Fail with error message if a line is longer than 75 characters</li>
020 * </ul>
021 */
022 public class MainframeFileFormatTransform implements TemplateTransformModel {
023
024 static final int MAX_LINE_LENGTH = 75;
025
026 /**
027 * Must have a default no-arg constructor.
028 */
029 public MainframeFileFormatTransform() {
030 }
031
032
033 public Writer getWriter(final Writer out, Map args) throws TemplateModelException {
034
035 // If you want to handle arguments to the transform, this is where it is done.
036 // Any variables must be stored in the writer instance below and not in the main transform class.
037
038 final StringBuffer buffer = new StringBuffer();
039 return new Writer() {
040 public void write(char cbuf[], int off, int len) {
041 buffer.append(cbuf, off, len);
042 }
043
044 public void flush() throws IOException {
045 out.flush();
046 }
047
048 public void close() throws IOException {
049 StringBuffer transformedBuffer = transform(buffer);
050 out.write(transformedBuffer.toString());
051 out.flush();
052 }
053
054 };
055 }
056
057 // Non-private for testing
058 static StringBuffer transform(StringBuffer inputBuffer) throws IOException {
059 BufferedReader reader = new BufferedReader(new StringReader(inputBuffer.toString()));
060 StringBuffer outputBuffer = new StringBuffer(inputBuffer.length());
061 try {
062 int lineNumber = 0;
063 String line = reader.readLine();
064 while (line != null) {
065 lineNumber++;
066
067 String transformedLine = transformLine(line, lineNumber);
068 outputBuffer.append(transformedLine);
069 outputBuffer.append("\n"); // since removed by readLine().
070
071 line = reader.readLine();
072 }
073
074 } finally {
075 reader.close();
076 }
077
078 return outputBuffer;
079 }
080
081
082 // Non-private for testing.
083 static String transformLine(String line, int lineNumber) {
084
085 if (line.length() == 0) {
086 return line;
087 }
088
089 // Convert tabs to spaces
090 String newLine = line.replaceAll("\t", " ");
091
092 // Trim ending whitespace
093 int lastNonWhitespaceIndex = newLine.length() - 1;
094 while (Character.isWhitespace(newLine.charAt(lastNonWhitespaceIndex))) {
095 lastNonWhitespaceIndex --;
096 if (lastNonWhitespaceIndex < 0) {
097 // Line is nothing but whitespace
098 return "";
099 }
100 }
101 newLine = newLine.substring(0, lastNonWhitespaceIndex+1);
102
103 if (newLine.length() > MAX_LINE_LENGTH) {
104 throw new RuntimeException("Line #" + lineNumber +
105 " is longer than the maximum of " + MAX_LINE_LENGTH +
106 " characters. Line content = [" + line + "].");
107 }
108
109 return newLine;
110 }
111
112 }