001 package com.softwarementors.extjs.djn.jscodegen; 002 003 import java.io.File; 004 import java.io.IOException; 005 import java.util.HashMap; 006 import java.util.Map; 007 008 import org.apache.commons.io.FileUtils; 009 import org.apache.log4j.Logger; 010 011 import com.softwarementors.extjs.djn.StringUtils; 012 import com.softwarementors.extjs.djn.api.RegisteredApi; 013 import com.softwarementors.extjs.djn.api.Registry; 014 import com.softwarementors.extjs.djn.config.GlobalConfiguration; 015 016 public class CodeFileGenerator { 017 private Registry registry; 018 Map<String, StringBuilder> debugFileOutputs = new HashMap<String,StringBuilder>(); 019 Map<String, StringBuilder> noCommentsFileOutputs = new HashMap<String,StringBuilder>(); 020 021 private GlobalConfiguration getGlobalConfiguration() { 022 return this.registry.getGlobalConfiguration(); 023 } 024 025 private CodeFileGenerator( Registry registry) { 026 assert registry != null; 027 028 this.registry = registry; 029 } 030 031 private static final Logger logger = Logger.getLogger( CodeFileGenerator.class); 032 033 public static void updateApiFiles( Registry registry ) throws IOException { 034 assert registry != null; 035 036 CodeFileGenerator generator = new CodeFileGenerator(registry); 037 038 generator.generateCode(); 039 generator.saveCode(); 040 } 041 042 private void generateCode() { 043 for( RegisteredApi api : this.registry.getApis() ) { 044 String fileName = api.getFullApiFileName(); 045 StringBuilder debugOutput = this.debugFileOutputs.get(fileName); 046 StringBuilder noCommentsOutput = this.noCommentsFileOutputs.get(fileName); 047 assert (debugOutput == null) == (noCommentsOutput == null); 048 049 if( debugOutput == null) { 050 debugOutput = new StringBuilder(); 051 this.debugFileOutputs.put( fileName, debugOutput); 052 053 noCommentsOutput = new StringBuilder(); 054 this.noCommentsFileOutputs.put( fileName, noCommentsOutput); 055 } 056 057 ApiCodeGenerator generator = new ApiCodeGenerator( getGlobalConfiguration(), api ); 058 generator.appendCode(debugOutput, false); 059 generator.appendCode(noCommentsOutput, true); 060 } 061 } 062 063 private void saveCode() throws IOException 064 { 065 for( String defaultFileName : this.debugFileOutputs.keySet() ) { 066 String debugFileName = getDebugFileName(defaultFileName); 067 String minifiedFileName = Minifier.getMinifiedFileName(defaultFileName); 068 069 boolean minify = getGlobalConfiguration().getMinify(); 070 boolean debug = getGlobalConfiguration().getDebug(); 071 072 String debugCode = this.debugFileOutputs.get(defaultFileName).toString(); 073 String defaultCode = debugCode; 074 String minifiedCode = debugCode; 075 076 boolean haveMinifiedCode = false; 077 if( minify ) { 078 String noCommentsCode = this.noCommentsFileOutputs.get(defaultFileName).toString(); 079 minifiedCode = Minifier.minify(noCommentsCode, defaultFileName, debugCode.length()); 080 if( minifiedCode == null ) { 081 logger.warn( "Unable to minify code: using Debug code for '" + minifiedFileName + "'."); 082 minifiedCode = debugCode; 083 } 084 else { 085 haveMinifiedCode = true; 086 } 087 } 088 089 if( !debug && haveMinifiedCode) { 090 defaultCode = minifiedCode; 091 if( logger.isDebugEnabled()) { 092 logger.debug( "Production mode: using minified code for '" + defaultFileName + "'"); 093 } 094 } 095 else { 096 if( logger.isDebugEnabled()) { 097 logger.debug( "Using Debug code for '" + defaultFileName + "'"); 098 } 099 } 100 101 updateFile( debugFileName, debugCode ); 102 updateFile( defaultFileName, defaultCode ); 103 if( minify ) { 104 updateFile( minifiedFileName, minifiedCode ); 105 } 106 else { 107 deleteFile( minifiedFileName ); 108 } 109 110 } 111 } 112 113 private void deleteFile( String fullFileName ) { 114 assert !StringUtils.isEmpty(fullFileName); 115 116 File file = new File( fullFileName ); 117 if( file.exists()) { 118 file.delete(); 119 if( logger.isDebugEnabled() ) { 120 logger.debug( "Api file deleted: '" + file.getAbsolutePath() + "'"); 121 } 122 } 123 } 124 125 private void updateFile( String fullFileName, String code ) throws IOException { 126 assert !StringUtils.isEmpty(fullFileName); 127 assert code != null; 128 129 File file = new File( fullFileName ); 130 if( !fileContentEquals(file, code) ) { 131 FileUtils.writeStringToFile(file, code); 132 if( logger.isDebugEnabled() ) { 133 logger.debug( "Api file updated: '" + file.getAbsolutePath() + "'"); 134 } 135 } 136 else { 137 if( logger.isDebugEnabled() ) { 138 logger.debug( "Api file '" + file.getAbsolutePath() + '\'' + " is up to date: it was not rewritten."); 139 } 140 } 141 } 142 143 private boolean fileContentEquals(File file, String code) throws IOException { 144 assert file != null; 145 assert code != null; 146 147 if( file.exists()) { 148 String contents = FileUtils.readFileToString(file); 149 boolean result = contents.equals( code ); 150 return result; 151 } 152 return false; 153 } 154 155 private String getDebugFileName( String file ) { 156 String result = file.replace( ".js", "-debug.js"); 157 return result; 158 } 159 }