Java tutorial
// // Copyright 2013 The Palantir Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package com.xylocore.copybook.runtime.internal; import java.io.FileOutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.apache.commons.lang3.StringUtils; import com.xylocore.commons.util.FormatHelper; /** * FILLIN * * @author Eric R. Medley */ public class AbstractCopybookGenerator { // // Nested classes // private static class Parameter { // // Members // private String dataType; private String name; // // Class implementation // /** * FILLIN * * @param aDataType * @param aName */ public Parameter(String aDataType, String aName) { assert StringUtils.isNotBlank(aDataType); assert StringUtils.isNotBlank(aName); dataType = aDataType; name = aName; } /** * FILLIN * * @return */ public String getDataType() { return dataType; } /** * FILLIN * * @return */ public String getName() { return name; } } // // Members // private static final String[][] allDataTypes = { { "byte", "Byte" }, { "char", "Char" }, { "short", "Short" }, { "int", "Integer" }, { "long", "Long" }, { "float", "Float" }, { "double", "Double" }, { "BigInteger", "BigInteger" }, { "BigDecimal", "BigDecimal" }, { "String", "String" }, { "Date", "Date" } }; private static final String[][] comp12DataTypes = { { "byte", "Byte" }, { "char", "Char" }, { "short", "Short" }, { "int", "Integer" }, { "long", "Long" }, { "float", "Float" }, { "double", "Double" }, { "BigInteger", "BigInteger" }, { "BigDecimal", "BigDecimal" }, { "String", "String" } }; // // Class implementation // public static void main(String[] args) { try { PrintStream myOutputStream = System.out; myOutputStream = new PrintStream(new FileOutputStream( "src/main/java/com/xylocore/commons/data/copybook/runtime/AbstractCopybook.java.new")); AbstractCopybookGenerator myGenerator = new AbstractCopybookGenerator(); myGenerator.generate(myOutputStream); myOutputStream.close(); } catch (Exception myException) { myException.printStackTrace(); } } public void generate(PrintStream aOutputStream) { generateHeader(aOutputStream); generateNumericDisplayPICMarshallerDelegation(aOutputStream); generateDelegationSectionSeparator(aOutputStream); generateNumericNationalPICMarshallerDelegation(aOutputStream); generateDelegationSectionSeparator(aOutputStream); generateBinaryPICMarshallerDelegation(aOutputStream); generateDelegationSectionSeparator(aOutputStream); generateComputational1PICMarshallerDelegation(aOutputStream); generateDelegationSectionSeparator(aOutputStream); generateComputational2PICMarshallerDelegation(aOutputStream); generateDelegationSectionSeparator(aOutputStream); generateComputational3PICMarshallerDelegation(aOutputStream); generateDelegationSectionSeparator(aOutputStream); generateComputational5PICMarshallerDelegation(aOutputStream); generateDelegationSectionSeparator(aOutputStream); generateAlphanumericPICMarshallerDelegation(aOutputStream); generateFooter(aOutputStream); } private static void generateHeader(PrintStream aOutputStream) { aOutputStream.println("//"); aOutputStream.println("// Copyright 2013 The Palantir Corporation"); aOutputStream.println("//"); aOutputStream.println("// Licensed under the Apache License, Version 2.0 (the \"License\");"); aOutputStream.println("// you may not use this file except in compliance with the License."); aOutputStream.println("// You may obtain a copy of the License at"); aOutputStream.println("//"); aOutputStream.println("// http://www.apache.org/licenses/LICENSE-2.0"); aOutputStream.println("//"); aOutputStream.println("// Unless required by applicable law or agreed to in writing, software"); aOutputStream.println("// distributed under the License is distributed on an \"AS IS\" BASIS,"); aOutputStream.println("// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."); aOutputStream.println("// See the License for the specific language governing permissions and"); aOutputStream.println("// limitations under the License."); aOutputStream.println("//"); aOutputStream.println(); aOutputStream.println(); aOutputStream.println("package com.xylocore.commons.data.copybook.runtime;"); aOutputStream.println(); aOutputStream.println("import java.math.BigDecimal;"); aOutputStream.println("import java.math.BigInteger;"); aOutputStream.println("import java.util.Date;"); aOutputStream.println(); aOutputStream.println("import com.xylocore.commons.data.copybook.runtime.CopybookContext;"); aOutputStream.println("import com.xylocore.commons.data.copybook.runtime.converters.Converter;"); aOutputStream.println("import com.xylocore.commons.data.copybook.runtime.nulleq.NullEquivalentStrategy;"); aOutputStream.println(); aOutputStream.println(); aOutputStream.println("/**"); aOutputStream.println(" * FILLIN"); aOutputStream.println(" * "); aOutputStream.println(" * @author Eric R. Medley"); aOutputStream.println(" */"); aOutputStream.println(); aOutputStream.println("public abstract class AbstractCopybook"); aOutputStream.println(" extends"); aOutputStream.println(" AbstractCopybookBase"); aOutputStream.println("{"); } private static void generateNumericDisplayPICMarshallerDelegation(PrintStream aOutputStream) { generateNumericSectionPICMarshallerDelegation(aOutputStream, "Display"); } private static void generateNumericNationalPICMarshallerDelegation(PrintStream aOutputStream) { generateNumericSectionPICMarshallerDelegation(aOutputStream, "National"); } private static void generateBinaryPICMarshallerDelegation(PrintStream aOutputStream) { generateNumericCompPICMarshallerDelegation(aOutputStream, "Binary", "Binary"); } private static void generateComputational1PICMarshallerDelegation(PrintStream aOutputStream) { generateNumericComp12PICMarshallerDelegation(aOutputStream, "Comp1", "Computational1"); } private static void generateComputational2PICMarshallerDelegation(PrintStream aOutputStream) { generateNumericComp12PICMarshallerDelegation(aOutputStream, "Comp2", "Computational2"); } private static void generateComputational3PICMarshallerDelegation(PrintStream aOutputStream) { generateNumericCompPICMarshallerDelegation(aOutputStream, "Comp3", "Computational3"); } private static void generateComputational5PICMarshallerDelegation(PrintStream aOutputStream) { generateNumericCompPICMarshallerDelegation(aOutputStream, "Comp5", "Computational5"); } private static void generateAlphanumericPICMarshallerDelegation(PrintStream aOutputStream) { generateDelegationSectionTitle(aOutputStream, "AlphanumericPICMarshaller"); List<Parameter> myParameters = new ArrayList<>(); myParameters.add(new Parameter("CopybookContext", "aContext")); myParameters.add(new Parameter("int", "aOffset")); myParameters.add(new Parameter("int", "aSize")); myParameters.add(new Parameter("int", "aFlags")); generateIsBlankMethod(aOutputStream, "public", "isAlphanumericBlank", "alphanumericMarshaller.isBlank", myParameters, 0, 0); for (int i = 0, ci = allDataTypes.length; i < ci; i++) { generateAlphanumericSectionMethodsForDataType(aOutputStream, allDataTypes[i][0], allDataTypes[i][1]); } generateIsConditionNameValidMethod(aOutputStream, "public", "isAlphanumericConditionNameValid", "alphanumericMarshaller.isConditionNameValid", myParameters, 2, 0); } private static void generateFooter(PrintStream aOutputStream) { aOutputStream.println("}"); } private static void generateDelegationSectionTitle(PrintStream aOutputStream, String aTitle) { aOutputStream.println(" //"); aOutputStream.println(" // " + aTitle + " delegation"); aOutputStream.println(" //"); aOutputStream.println(); aOutputStream.println(); } private static void generateDelegationSectionSeparator(PrintStream aOutputStream) { aOutputStream.println(); aOutputStream.println(); aOutputStream.println(); aOutputStream.println(); } private static void generateNumericSectionPICMarshallerDelegation(PrintStream aOutputStream, String aNumericType) { generateDelegationSectionTitle(aOutputStream, "Numeric" + aNumericType + "PICMarshaller"); List<Parameter> myParameters = new ArrayList<>(); myParameters.add(new Parameter("CopybookContext", "aContext")); myParameters.add(new Parameter("int", "aOffset")); myParameters.add(new Parameter("int", "aDigits")); myParameters.add(new Parameter("SignType", "aSignType")); myParameters.add(new Parameter("SignPosition", "aSignPosition")); String myMarshallerName = "numeric" + aNumericType + "Marshaller"; String myNumericClass = "Numeric" + aNumericType; generateIsBlankMethod(aOutputStream, "public", "is" + myNumericClass + "Blank", myMarshallerName + ".isBlank", myParameters, 0, 0); myParameters.add(new Parameter("int", "aPrecision")); myParameters.add(new Parameter("int", "aScalingPosition")); for (int i = 0, ci = allDataTypes.length; i < ci; i++) { generateNumericSectionMethodsForDataType(aOutputStream, myParameters, myMarshallerName, myNumericClass, allDataTypes[i][0], allDataTypes[i][1]); } generateIsConditionNameValidMethod(aOutputStream, "public", "is" + myNumericClass + "ConditionNameValid", myMarshallerName + ".isConditionNameValid", myParameters, 2, 0); } private static void generateNumericSectionMethodsForDataType(PrintStream aOutputStream, List<Parameter> aParameters, String aMarshallerName, String aNumericClass, String aDataType, String aDataTypeName) { List<Parameter> myParameters = new ArrayList<>(aParameters); if (aDataTypeName.equals("Date")) { myParameters.add(new Parameter("Converter", "aConverter")); } if (aDataTypeName.equals("BigInteger") || aDataTypeName.equals("BigDecimal") || aDataTypeName.equals("String") || aDataTypeName.equals("Date")) { myParameters.add(new Parameter("NullEquivalentStrategy[]", "aNullEquivalentStrategies")); } generateIsValidMethod(aOutputStream, "public", "is" + aNumericClass + "As" + aDataTypeName + "Valid", aMarshallerName + ".isValidAs" + aDataTypeName, myParameters, 2, 0); generateDecodeMethod(aOutputStream, "public", aDataType, "decode" + aNumericClass + "As" + aDataTypeName, aMarshallerName + ".decodeAs" + aDataTypeName, myParameters, 2, 0); myParameters.add(2, new Parameter(aDataType, "aValue")); generateEncodeMethod(aOutputStream, "public", aDataType, "encode" + aNumericClass + "As" + aDataTypeName, aMarshallerName + ".encodeAs" + aDataTypeName, myParameters, 2, 0); } private static void generateNumericComp12PICMarshallerDelegation(PrintStream aOutputStream, String aNumericType, String aSectionHeaderType) { generateDelegationSectionTitle(aOutputStream, aSectionHeaderType + "PICMarshaller"); List<Parameter> myParameters = new ArrayList<>(); myParameters.add(new Parameter("CopybookContext", "aContext")); myParameters.add(new Parameter("int", "aOffset")); String myMarshallerName = buildMarshallerName(aNumericType); generateIsValidMethod(aOutputStream, "public", "is" + aNumericType + "Valid", myMarshallerName + ".isValid", myParameters, 0, 0); for (int i = 0, ci = comp12DataTypes.length; i < ci; i++) { generateNumericComp12SectionMethodsForDataType(aOutputStream, aNumericType, allDataTypes[i][0], allDataTypes[i][1]); } generateIsConditionNameValidMethod(aOutputStream, "public", "is" + aNumericType + "ConditionNameValid", myMarshallerName + ".isConditionNameValid", myParameters, 2, 0); } private static void generateNumericComp12SectionMethodsForDataType(PrintStream aOutputStream, String aNumericType, String aDataType, String aDataTypeName) { List<Parameter> myParameters = new ArrayList<>(); myParameters.add(new Parameter("CopybookContext", "aContext")); myParameters.add(new Parameter("int", "aOffset")); String myMarshallerName = buildMarshallerName(aNumericType); generateDecodeMethod(aOutputStream, "public", aDataType, "decode" + aNumericType + "As" + aDataTypeName, myMarshallerName + ".decodeAs" + aDataTypeName, myParameters, 2, 0); myParameters.add(new Parameter(aDataType, "aValue")); generateEncodeMethod(aOutputStream, "public", aDataType, "encode" + aNumericType + "As" + aDataTypeName, myMarshallerName + ".encodeAs" + aDataTypeName, myParameters, 2, 0); } private static void generateNumericCompPICMarshallerDelegation(PrintStream aOutputStream, String aNumericType, String aSectionHeaderType) { List<Parameter> myParameters = new ArrayList<>(); myParameters.add(new Parameter("CopybookContext", "aContext")); myParameters.add(new Parameter("int", "aOffset")); myParameters.add(new Parameter("int", "aDigits")); myParameters.add(new Parameter("SignType", "aSignType")); myParameters.add(new Parameter("int", "aPrecision")); myParameters.add(new Parameter("int", "aScalingPosition")); String myMarshallerName = buildMarshallerName(aNumericType); generateDelegationSectionTitle(aOutputStream, aSectionHeaderType + "PICMarshaller"); for (int i = 0, ci = allDataTypes.length; i < ci; i++) { generateNumericCompSectionMethodsForDataType(aOutputStream, aNumericType, myParameters, myMarshallerName, allDataTypes[i][0], allDataTypes[i][1]); } generateIsConditionNameValidMethod(aOutputStream, "public", "is" + aNumericType + "ConditionNameValid", myMarshallerName + ".isConditionNameValid", myParameters, 0, 0); } private static void generateNumericCompSectionMethodsForDataType(PrintStream aOutputStream, String aNumericType, List<Parameter> aParameters, String aMarshallerName, String aDataType, String aDataTypeName) { List<Parameter> myParameters = new ArrayList<>(aParameters); generateIsValidMethod(aOutputStream, "public", "is" + aNumericType + "As" + aDataTypeName + "Valid", aMarshallerName + ".isValidAs" + aDataTypeName, myParameters, 0, 2); generateDecodeMethod(aOutputStream, "public", aDataType, "decode" + aNumericType + "As" + aDataTypeName, aMarshallerName + ".decodeAs" + aDataTypeName, myParameters, 0, 2); myParameters.add(2, new Parameter(aDataType, "aValue")); generateEncodeMethod(aOutputStream, "public", aDataType, "encode" + aNumericType + "As" + aDataTypeName, aMarshallerName + ".encodeAs" + aDataTypeName, myParameters, 0, 2); } private static void generateAlphanumericSectionMethodsForDataType(PrintStream aOutputStream, String aDataType, String aDataTypeName) { List<Parameter> myParameters = new ArrayList<>(); myParameters.add(new Parameter("CopybookContext", "aContext")); myParameters.add(new Parameter("int", "aOffset")); myParameters.add(new Parameter("int", "aSize")); myParameters.add(new Parameter("int", "aFlags")); if (aDataTypeName.equals("Date")) { myParameters.add(new Parameter("Converter", "aConverter")); } if (aDataTypeName.equals("BigInteger") || aDataTypeName.equals("BigDecimal") || aDataTypeName.equals("String") || aDataTypeName.equals("Date")) { myParameters.add(new Parameter("NullEquivalentStrategy[]", "aNullEquivalentStrategies")); } generateIsValidMethod(aOutputStream, "public", "isAlphanumericAs" + aDataTypeName + "Valid", "alphanumericMarshaller.isValidAs" + aDataTypeName, myParameters, 2, 0); generateDecodeMethod(aOutputStream, "public", aDataType, "decodeAlphanumericAs" + aDataTypeName, "alphanumericMarshaller.decodeAs" + aDataTypeName, myParameters, 2, 0); myParameters.add(2, new Parameter(aDataType, "aValue")); generateEncodeMethod(aOutputStream, "public", aDataType, "encodeAlphanumericAs" + aDataTypeName, "alphanumericMarshaller.encodeAs" + aDataTypeName, myParameters, 2, 0); } private static String buildMarshallerName(String aNumericType) { return aNumericType.substring(0, 1).toLowerCase() + aNumericType.substring(1) + "Marshaller"; } private static void generateIsBlankMethod(PrintStream aOutputStream, String aModifiers, String aMethodName, String aDelegateMethodPrefix, List<Parameter> aParameters, int aLinesBefore, int aLinesAfter) { for (int i = 0; i < aLinesBefore; i++) { aOutputStream.println(); } generateMethodHeader(aOutputStream, aModifiers, aMethodName, "boolean", aParameters); aOutputStream.println(" {"); aOutputStream.println(" aContext.clearError();"); generateDelegateMethodCall(aOutputStream, "boolean myBlank = " + aDelegateMethodPrefix, aParameters); aOutputStream.println(" checkForError( aContext );"); aOutputStream.println(" return myBlank;"); aOutputStream.println(" }"); for (int i = 0; i < aLinesAfter; i++) { aOutputStream.println(); } } private static void generateIsValidMethod(PrintStream aOutputStream, String aModifiers, String aMethodName, String aDelegateMethodPrefix, List<Parameter> aParameters, int aLinesBefore, int aLinesAfter) { for (int i = 0; i < aLinesBefore; i++) { aOutputStream.println(); } generateMethodHeader(aOutputStream, aModifiers, aMethodName, "boolean", aParameters); aOutputStream.println(" {"); generateDelegateMethodCall(aOutputStream, "return " + aDelegateMethodPrefix, aParameters); aOutputStream.println(" }"); for (int i = 0; i < aLinesAfter; i++) { aOutputStream.println(); } } private static void generateIsConditionNameValidMethod(PrintStream aOutputStream, String aModifiers, String aMethodName, String aDelegateMethodPrefix, List<Parameter> aParameters, int aLinesBefore, int aLinesAfter) { List<Parameter> myParameters = new ArrayList<>(aParameters); myParameters.add(2, new Parameter("String", "aConditionName")); myParameters.add(3, new Parameter("java.util.Map<String,ConstantValue[]>", "aConditionNameValueMappings")); for (int i = 0; i < aLinesBefore; i++) { aOutputStream.println(); } generateMethodHeader(aOutputStream, aModifiers, aMethodName, "boolean", myParameters); aOutputStream.println(" {"); generateDelegateMethodCall(aOutputStream, "return " + aDelegateMethodPrefix, myParameters); aOutputStream.println(" }"); for (int i = 0; i < aLinesAfter; i++) { aOutputStream.println(); } } private static void generateDecodeMethod(PrintStream aOutputStream, String aModifiers, String aDataType, String aMethodName, String aDelegateMethodPrefix, List<Parameter> aParameters, int aLinesBefore, int aLinesAfter) { for (int i = 0; i < aLinesBefore; i++) { aOutputStream.println(); } generateMethodHeader(aOutputStream, aModifiers, aMethodName, aDataType, aParameters); aOutputStream.println(" {"); aOutputStream.println(" aContext.clearError();"); generateDelegateMethodCall(aOutputStream, aDataType + " myValue = " + aDelegateMethodPrefix, aParameters); aOutputStream.println(" checkForError( aContext );"); aOutputStream.println(" return myValue;"); aOutputStream.println(" }"); for (int i = 0; i < aLinesAfter; i++) { aOutputStream.println(); } } private static void generateEncodeMethod(PrintStream aOutputStream, String aModifiers, String aDataType, String aMethodName, String aDelegateMethodPrefix, List<Parameter> aParameters, int aLinesBefore, int aLinesAfter) { for (int i = 0; i < aLinesBefore; i++) { aOutputStream.println(); } generateMethodHeader(aOutputStream, aModifiers, aMethodName, "void", aParameters); aOutputStream.println(" {"); aOutputStream.println(" aContext.clearError();"); generateDelegateMethodCall(aOutputStream, aDelegateMethodPrefix, aParameters); aOutputStream.println(" checkForError( aContext );"); aOutputStream.println(" }"); for (int i = 0; i < aLinesAfter; i++) { aOutputStream.println(); } } /** * FILLIN * * @param aOutputStream * @param aModifiers * @param aMethodName * @param aReturnType * @param aParameters */ private static void generateMethodHeader(PrintStream aOutputStream, String aModifiers, String aMethodName, String aReturnType, List<Parameter> aParameters) { assert StringUtils.isNotBlank(aMethodName); assert StringUtils.isNotBlank(aModifiers); if (aReturnType == null) { aReturnType = "void"; } if (aParameters == null) { aParameters = Collections.<Parameter>emptyList(); } int myParameterCount = aParameters.size(); aOutputStream.println(" /**"); aOutputStream.println(" * FILLIN"); aOutputStream.println(" * "); for (Parameter myParameter : aParameters) { aOutputStream.println(" * @param " + myParameter.getName()); } if (!aReturnType.equals("void")) { aOutputStream.println(" * "); aOutputStream.println(" * @return"); } aOutputStream.println(" */"); String myMethodPrefix = " " + aModifiers + " " + aReturnType + " " + aMethodName; if (myParameterCount != 0) { String myParameterSeparator = (myParameterCount > 1) ? " " : " "; String myLastParameterSuffix = (myParameterCount > 1) ? " )" : ")"; StringBuilder myBuffer = new StringBuilder(); boolean myFirst = true; int myMaxParamTypeLength = 0; int myMaxParamNameLength = 0; for (Parameter myParameter : aParameters) { myMaxParamTypeLength = Math.max(myMaxParamTypeLength, myParameter.getDataType().length()); myMaxParamNameLength = Math.max(myMaxParamNameLength, myParameter.getName().length()); } for (Iterator<Parameter> myIterator = aParameters.iterator(); myIterator.hasNext();) { Parameter myParameter = myIterator.next(); myBuffer.setLength(0); if (myFirst) { myBuffer.append(myMethodPrefix).append("( "); myFirst = false; } else { FormatHelper.stringOfCharacters(myBuffer, ' ', myMethodPrefix.length() + 2); } String myParameterSuffix = (myIterator.hasNext()) ? "," : " "; FormatHelper.formatString(myBuffer, myParameter.getDataType(), myMaxParamTypeLength); myBuffer.append(myParameterSeparator); FormatHelper.formatString(myBuffer, myParameter.getName() + myParameterSuffix, myMaxParamNameLength + myParameterSuffix.length()); if (!myIterator.hasNext()) { myBuffer.append(myLastParameterSuffix); } aOutputStream.println(myBuffer.toString()); } } else { aOutputStream.println(myMethodPrefix + "()"); } } /** * FILLIN * * @param aOutputStream * @param aMethodCall * @param aParameters */ private static void generateDelegateMethodCall(PrintStream aOutputStream, String aMethodCall, List<Parameter> aParameters) { assert aOutputStream != null; assert StringUtils.isNotBlank(aMethodCall); if (aParameters == null) { aParameters = Collections.<Parameter>emptyList(); } int myParameterCount = aParameters.size(); String myMethodCallPrefix = " " + aMethodCall; if (myParameterCount != 0) { String myLastParameterSuffix = (myParameterCount > 1) ? " );" : ");"; StringBuilder myBuffer = new StringBuilder(); boolean myFirst = true; int myMaxParamTypeLength = 0; int myMaxParamNameLength = 0; for (Parameter myParameter : aParameters) { myMaxParamTypeLength = Math.max(myMaxParamTypeLength, myParameter.getDataType().length()); myMaxParamNameLength = Math.max(myMaxParamNameLength, myParameter.getName().length()); } for (Iterator<Parameter> myIterator = aParameters.iterator(); myIterator.hasNext();) { Parameter myParameter = myIterator.next(); myBuffer.setLength(0); if (myFirst) { myBuffer.append(myMethodCallPrefix).append("( "); myFirst = false; } else { FormatHelper.stringOfCharacters(myBuffer, ' ', myMethodCallPrefix.length() + 2); } String myParameterSuffix = (myIterator.hasNext()) ? "," : " "; FormatHelper.formatString(myBuffer, myParameter.getName() + myParameterSuffix, myMaxParamNameLength + myParameterSuffix.length()); if (!myIterator.hasNext()) { myBuffer.append(myLastParameterSuffix); } aOutputStream.println(myBuffer.toString()); } } else { aOutputStream.println(myMethodCallPrefix + "();"); } } }