/* * [Generate.java] * * Summary: Generate HTML version of the grid, and compilable Java code exercising every conversion. * * Copyright: (c) 1997-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 5.3 2009-03-30 optimise suggested conversion code based on suggestions from Intellij Idea Inspector. * correct table entries for unsigned conversions that could not be handled purely with autoboxing. */ package com.mindprod.converter; import com.mindprod.common18.BigDate; import com.mindprod.common18.Build; import com.mindprod.entities.EntifyStrings; import java.io.FileWriter; import java.io.IOException; import java.util.StringTokenizer; import static com.mindprod.converter.Grid14.how14; import static com.mindprod.converter.Type.how; import static com.mindprod.converter.Type.howCore; import static java.lang.System.*; /** * Generate HTML version of the grid, and compilable Java code exercising every conversion. * * @author Roedy Green, Canadian Mind Products * @version 5.3 2009-03-30 optimise suggested conversion code based on suggestions from Intellij Idea Inspector. * correct table entries for unsigned conversions that could not be handled purely with autoboxing. * @since 1997 */ public class Generate { private static final String DO_NOT_EDIT = "\n"; /** * fluff < > & " to < > & " * * @param s string to insert entities to * * @return string with unsafe chars converted to entities. */ private static String fluff( String s ) { s = EntifyStrings.entifyHTML( s ); // add CSS markup to make comments stand out. final int slashPos = s.indexOf( "//" ); if ( slashPos >= 0 ) { s = s.substring( 0, slashPos ) + "" + s.substring( slashPos ) + ""; } else { final int start = s.indexOf( "/*" ); if ( start >= 0 ) { final int end = s.indexOf( "*/", start + 2 ); if ( end >= 0 ) { s = s.substring( 0, start ) + "" + s.substring( start, end + 2 ) + "" + s.substring( end + 2 ); } } } return s; } // end fluff /** * Generate all possible combinations as a partial HTML table for inclusion in converttable.html. Only used during * debugging. leaves results in E:\mindprod\jgloss\include\convert14.htmlfrag and * E:\mindprod\jgloss\include\convert15.htmlfrag * * @param considerAutoBox true if want Java 1.5 autoboxing considered. * * @noinspection EmptyCatchBlock, PointlessBooleanExpression */ private static void generateHTML( boolean considerAutoBox ) { try { String filename = Build.MINDPROD_WEBROOT + "/jgloss/include/" + ( considerAutoBox ? "convert15.htmlfrag" : "convert14.htmlfrag" ); FileWriter p = new FileWriter( filename ); // p.write("\n"); p.write( DO_NOT_EDIT + "\n" ); p.write( "" + "\n" ); p.write( "" ); p.write( "\n" ); // generate the heading titles for the columns p.write( "" ); for ( Type to : Type.values() ) { p.write( "\n" ); } p.write( "\n" ); p.write( "\n" ); int everyTenthRow = 0; for ( Type from : Type.values() ) { // generate the row title at the start of each row p.write( "\n" ); // generate a row of conversions for ( Type to : Type.values() ) { if ( from == to ) { p.write( "\n" ); } // end for to // generate title at end of each row p.write( "\n" ); p.write( "\n" ); } // end for from // generate the footer titles for the columns that // repeat the heading line p.write( "" ); for ( Type to : Type.values() ) { p.write( "\n" ); } p.write( "\n" ); p.write( "
Conversion Table
" + ( considerAutoBox ? "JDK 1.5+" : "JDK 1.4-" ) + " Convert To
Fromto: " ); p.write( fluff( to.getName() + " " + to.getVar() ) ); p.write( "From
" ); p.write( fluff( from.getName() + " " + from.getVar() ) ); p.write( "" ); p.write( "--------" ); } else { p.write( "" ); // generate code to do the conversion. // lines may contain embedded \n StringTokenizer st = new StringTokenizer( how( from, to, considerAutoBox ), "\n", false ); p.write( fluff( st.nextToken() ) ); while ( st.hasMoreTokens() ) { p.write( "
\n" ); p.write( fluff( st.nextToken() ) ); } // end while } // end else p.write( "
" ); p.write( fluff( from.getName() + " " + from.getVar() ) ); p.write( "
 to: " ); p.write( fluff( to.getName() + " " + to.getVar() ) ); p.write( " 
\n" ); p.close(); } catch ( IOException e ) { err.println( e.getMessage() ); } } // end generateHTML /** * Generate all possible combinations to ensure they can be compiled. Only used during debugging. * * @param considerAutobox true if want Java 1.5 autoboxing considered. false, just Java 1.4 methods. */ @SuppressWarnings( { "PointlessBooleanExpression" } ) private static void generateJava( boolean considerAutobox ) { try { FileWriter p = new FileWriter( "C:/temp/Test" + ( considerAutobox ? "15" : "14" ) + ".java" ); p.write( "final class Test" + ( considerAutobox ? "15" : "14" ) + "{\nvoid dummy() {\n" ); for ( Type from : Type.values() ) { for ( Type to : Type.values() ) { p.write( "{\n" + howExecute( from, to, considerAutobox ) + "\n}\n\n" ); } } p.write( "}}\n" ); p.close(); } catch ( IOException e ) { err.println( e.getMessage() ); } } // end generateJava /** * Generate a string with info on how to convert the given from/to type pair. * * @param from enumeration constant for the source type, for example, 0="boolean", 1="signed byte". * @param to enumeration constant for the target type, for example, 0="boolean", 1="signed byte". * @param considerAutobox true if want Java 1.5 autoboxing considered. false, just Java 1.4 methods. * * @return String sample Java source code to do that I/O task. */ private static String howExecute( Type from, Type to, boolean considerAutobox ) { if ( from != to ) { return from.getName() + " " + from.getVar() + // initialise the from variable, if you want executable code " = " + ( considerAutobox ? from.getInit15() : from.getInit14() ) + ";\n" + // generate declare for the second variable to.getName() + " " + to.getVar() + ";\n" + howCore( from, to, considerAutobox ); } else { return ( "// no conversion necessary" ); } } /** * make sure all entries are accounted for. */ @SuppressWarnings( { "PointlessBooleanExpression" } ) private static void validate() { if ( Grid14.how14.length < Type.values().length ) { err.println( "missing row" ); } else if ( Grid14.how14.length > Type.values().length ) { err.println( "extra row" ); } for ( Type from : Type.values() ) { String fromVar = from.getVar(); if ( Grid14.how14[ from.ordinal() ].length < Type.values().length ) { err.println( "short row from " + fromVar ); } else if ( how14[ from.ordinal() ].length > Type.values().length ) { err.println( "long row from " + fromVar ); } for ( Type to : Type.values() ) { String toVar = to.getVar(); String expansion = how( from, to, false /* no autobox */ ); if ( from == to ) { if ( !expansion.contains( "// no conversion necessary" ) ) { err.println( "not null on diagonal at " + fromVar ); } } else if ( !expansion.contains( toVar + " =" ) || !expansion.contains( fromVar ) ) { err.println( "malformed " + toVar + "=" + fromVar ); } } // end for to } // end for from } // end validate /** * test harness * * @param args not used */ public static void main( String[] args ) { // validate tables for consistency. validate(); out.println( "Generating test Java code and new HTML grid." ); // generate source code of all combinations to generateJava compile generateJava( false ); generateJava( true ); // generate HTML conversion table generateHTML( false ); // generate Java 1.5 versions. generateHTML( true ); } }