| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 flex2.tools; |
| |
| import flash.localization.LocalizationManager; |
| import flash.localization.ResourceBundleLocalizer; |
| import flash.localization.XLRLocalizer; |
| import flash.swf.Movie; |
| import flash.util.Trace; |
| import flex2.compiler.*; |
| import flex2.compiler.common.*; |
| import flex2.compiler.config.*; |
| import flex2.compiler.extensions.ExtensionManager; |
| import flex2.compiler.extensions.IMxmlcExtension; |
| import flex2.compiler.i18n.I18nUtils; |
| import flex2.compiler.io.FileUtil; |
| import flex2.compiler.io.VirtualFile; |
| import flex2.compiler.swc.SwcCache; |
| import flex2.compiler.swc.SwcException; |
| import flex2.compiler.util.Benchmark; |
| import flex2.compiler.util.CompilerMessage; |
| import flex2.compiler.util.NameMappings; |
| import flex2.compiler.util.ThreadLocalToolkit; |
| import flex2.linker.ConsoleApplication; |
| import flex2.linker.LinkerAPI; |
| import flex2.linker.LinkerException; |
| import org.apache.flex.tools.FlexTool; |
| |
| import java.io.*; |
| import java.util.*; |
| import java.util.Map.Entry; |
| |
| /** |
| * A command line tool for compiling Flex applications. Despite the |
| * name, in addition to .mxml files, this tool can be used to compile |
| * other file formats, like .as and .css. |
| * |
| * @author Clement Wong |
| */ |
| public final class Mxmlc extends Tool implements FlexTool |
| { |
| public static final String FILE_SPECS = "file-specs"; |
| |
| @Override |
| public String getName() { |
| return FLEX_TOOL_MXMLC; |
| } |
| |
| @Override |
| public int execute(String[] args) { |
| mxmlc(args); |
| return ThreadLocalToolkit.errorCount(); |
| } |
| |
| /** |
| * The entry-point for Mxmlc. |
| * Note that if you change anything in this method, make sure to check Compc, Shell, and |
| * the server's CompileFilter to see if the same change needs to be made there. You |
| * should also inform the Zorn team of the change. |
| * |
| * @param args |
| */ |
| public static void main(String[] args) |
| { |
| mxmlc(args); |
| System.exit(ThreadLocalToolkit.errorCount()); |
| } |
| |
| public static void mxmlc(String[] args) |
| { |
| Transcoder[] transcoders = null; |
| Benchmark benchmark = null; |
| |
| try |
| { |
| CompilerAPI.useAS3(); |
| |
| // setup the path resolver |
| CompilerAPI.usePathResolver(); |
| |
| // set up for localizing messages |
| LocalizationManager l10n = new LocalizationManager(); |
| l10n.addLocalizer( new XLRLocalizer() ); |
| l10n.addLocalizer( new ResourceBundleLocalizer() ); |
| ThreadLocalToolkit.setLocalizationManager(l10n); |
| |
| // setup the console logger. the configuration parser needs a logger. |
| CompilerAPI.useConsoleLogger(); |
| |
| // process configuration |
| ConfigurationBuffer cfgbuf = new ConfigurationBuffer(CommandLineConfiguration.class, Configuration.getAliases()); |
| |
| // Do not set this. The file-specs should be included in the configuration buffer |
| // checksum so changes to the class list can be detected during incremental builds. |
| //cfgbuf.setDefaultVar(FILE_SPECS); |
| DefaultsConfigurator.loadDefaults( cfgbuf ); |
| CommandLineConfiguration configuration = (CommandLineConfiguration) processConfiguration( |
| l10n, "mxmlc", args, cfgbuf, CommandLineConfiguration.class, FILE_SPECS); |
| |
| // well, setup the logger again now that we know configuration.getWarnings()??? |
| CompilerAPI.useConsoleLogger(true, true, configuration.getWarnings(), true); |
| CompilerAPI.setupHeadless(configuration); |
| |
| if (configuration.benchmark()) |
| { |
| benchmark = CompilerAPI.runBenchmark(); |
| benchmark.startTime(Benchmark.PRECOMPILE); |
| } |
| else |
| { |
| CompilerAPI.disableBenchmark(); |
| } |
| |
| // make sure targetFile abstract pathname is an absolute path... |
| VirtualFile targetFile = CompilerAPI.getVirtualFile(configuration.getTargetFile()); |
| WebTierAPI.checkSupportedTargetMimeType(targetFile); |
| |
| // mxmlc only wants to take one file. |
| List<String> fileList = configuration.getFileList(); |
| if (fileList == null || fileList.size() != 1) |
| { |
| throw new ConfigurationException.OnlyOneSource( "filespec", null, -1); |
| } |
| |
| List<VirtualFile> virtualFileList = CompilerAPI.getVirtualFileList(fileList); |
| |
| CompilerConfiguration compilerConfig = configuration.getCompilerConfiguration(); |
| NameMappings mappings = CompilerAPI.getNameMappings(configuration); |
| |
| // create a FileSpec... can reuse based on targetFile, debug settings, etc... |
| FileSpec fileSpec = new FileSpec(Collections.<VirtualFile>emptyList(), WebTierAPI.getFileSpecMimeTypes()); |
| |
| // create a SourcePath... |
| VirtualFile[] asClasspath = compilerConfig.getSourcePath(); |
| SourceList sourceList = new SourceList(virtualFileList, |
| asClasspath, |
| targetFile, |
| WebTierAPI.getSourcePathMimeTypes()); |
| SourcePath sourcePath = new SourcePath(asClasspath, |
| targetFile, |
| WebTierAPI.getSourcePathMimeTypes(), |
| compilerConfig.allowSourcePathOverlap()); |
| |
| ResourceContainer resources = new ResourceContainer(); |
| ResourceBundlePath bundlePath = new ResourceBundlePath(configuration.getCompilerConfiguration(), targetFile); |
| |
| ArrayList<Source> sources = new ArrayList<Source>(); |
| List<CompilationUnit> units = new ArrayList<CompilationUnit>(); |
| |
| if (benchmark != null) |
| { |
| benchmark.benchmark(l10n.getLocalizedTextString(new InitialSetup())); |
| } |
| |
| // load SWCs |
| CompilerSwcContext swcContext = new CompilerSwcContext(); |
| SwcCache cache = new SwcCache(); |
| |
| // lazy read should only be set by mxmlc/compc |
| cache.setLazyRead(true); |
| |
| swcContext.load( compilerConfig.getLibraryPath(), |
| Configuration.getAllExcludedLibraries(compilerConfig, configuration), |
| compilerConfig.getThemeFiles(), |
| compilerConfig.getIncludeLibraries(), |
| mappings, |
| I18nUtils.getTranslationFormat(compilerConfig), |
| cache ); |
| configuration.addExterns( swcContext.getExterns() ); |
| configuration.addIncludes( swcContext.getIncludes() ); |
| configuration.getCompilerConfiguration().addThemeCssFiles( swcContext.getThemeStyleSheets() ); |
| |
| // Figure out the name of the output file. |
| File outputFile = getOutputFile(configuration, targetFile); |
| |
| // Checksums to figure out if incremental compile can be done. |
| String incrementalFileName = null; |
| SwcChecksums swcChecksums = null; |
| |
| // Should we attempt to build incrementally using the incremental file? |
| boolean recompile = true; |
| |
| // If incremental compilation is enabled and the output file exists, |
| // use the persisted store to figure out if a compile/link is necessary. |
| // link without a compile is not supported without changes to the |
| // persistantStore since units for Sources of type isSwcScriptOwner() |
| // aren't stored/restored properly. units contains null entries for those |
| // type of Source. To force a rebuild, with -incremental specified, delete the |
| // incremental file. |
| if (configuration.getCompilerConfiguration().getIncremental()) |
| { |
| swcChecksums = new SwcChecksums(swcContext, cfgbuf, configuration); |
| |
| // If incremental compilation is enabled, read the cached |
| // compilation units... Do not include the checksum in the file name so that |
| // cache files don't pile up as the configuration changes. There needs |
| // to be a 1-to-1 mapping between the swc file and the cache file. |
| incrementalFileName = outputFile.getPath() + ".cache"; |
| |
| // If the output file doesn't exist don't bother loading the |
| // cache since a recompile is needed. |
| if (outputFile.exists()) |
| { |
| RandomAccessFile incrementalFile = null; |
| try |
| { |
| incrementalFile = new RandomAccessFile(incrementalFileName, "r"); |
| |
| // For loadCompilationUnits, loadedChecksums[1] must match |
| // the cached value else IOException is thrown. |
| int[] loadedChecksums = swcChecksums.copy(); |
| |
| CompilerAPI.loadCompilationUnits(configuration, fileSpec, sourceList, sourcePath, resources, bundlePath, null, /* sources */ |
| null, /*units */ |
| loadedChecksums, swcChecksums.getSwcDefSignatureChecksums(), swcChecksums.getSwcFileChecksums(), null, /* archiveFiles */ |
| incrementalFile, incrementalFileName, null /* font manager */); |
| |
| if (!(swcChecksums.isRecompilationNeeded(loadedChecksums) && !swcChecksums.isRelinkNeeded(loadedChecksums))) |
| { |
| recompile = false; |
| } |
| } |
| catch (FileNotFoundException ex) |
| { |
| // the incremental file doesn't exist |
| ThreadLocalToolkit.logDebug(ex.getLocalizedMessage()); |
| } |
| catch (IOException ex) |
| { |
| // error loading the incremental file - most likely checksum |
| // mismatch or format mismatch |
| ThreadLocalToolkit.logInfo(ex.getLocalizedMessage()); |
| } |
| finally |
| { |
| if (incrementalFile != null) |
| { |
| try |
| { |
| incrementalFile.close(); |
| } |
| catch (IOException ex) |
| { |
| } |
| // If the load failed, or recompilation is needed, reset |
| // all the variables to their original state. |
| if (recompile) |
| { |
| fileSpec = new FileSpec(Collections.<VirtualFile>emptyList(), WebTierAPI.getFileSpecMimeTypes()); |
| sourceList = new SourceList(virtualFileList, |
| asClasspath, |
| targetFile, |
| WebTierAPI.getSourcePathMimeTypes()); |
| sourcePath = new SourcePath(asClasspath, |
| targetFile, |
| WebTierAPI.getSourcePathMimeTypes(), |
| compilerConfig.allowSourcePathOverlap()); |
| resources = new ResourceContainer(); |
| bundlePath = new ResourceBundlePath(configuration.getCompilerConfiguration(), targetFile); |
| } |
| } |
| } |
| } |
| } |
| |
| VirtualFile projector = configuration.getProjector(); |
| boolean createProjector = (projector != null && projector.getName().endsWith("avmplus.exe")); |
| |
| // Validate CompilationUnits in FileSpec and SourcePath. If |
| // count > 0 something changed. |
| int count = CompilerAPI.validateCompilationUnits( |
| fileSpec, sourceList, sourcePath, bundlePath, resources, |
| swcContext, |
| null /* perCompileData */, |
| configuration); |
| recompile = recompile || (count > 0); |
| |
| if (recompile) |
| { |
| // Get standard bundle of compilers, transcoders. |
| transcoders = WebTierAPI.getTranscoders( configuration ); |
| SubCompiler[] compilers = WebTierAPI.getCompilers(compilerConfig, mappings, transcoders); |
| |
| if (benchmark != null) |
| { |
| benchmark.stopTime(Benchmark.PRECOMPILE, false); |
| } |
| |
| units = CompilerAPI.compile(fileSpec, sourceList, |
| null, /* classes */ |
| sourcePath, resources, bundlePath, swcContext, |
| mappings, configuration, compilers, |
| createProjector ? null : new PreLink(), |
| configuration.getLicensesConfiguration().getLicenseMap(), |
| sources); |
| |
| if (benchmark != null) |
| { |
| benchmark.startTime(Benchmark.POSTCOMPILE); |
| } |
| |
| OutputStream swfOut = new BufferedOutputStream(new FileOutputStream(outputFile)); |
| PostLink postLink = null; |
| |
| if (configuration.optimize() && !configuration.debug()) |
| { |
| postLink = new PostLink(configuration); |
| } |
| |
| // link |
| if (createProjector) |
| { |
| ConsoleApplication app = LinkerAPI.linkConsole(units, postLink, configuration); |
| |
| createProjector(configuration, projector, app, swfOut); |
| } |
| else |
| { |
| Movie movie = LinkerAPI.link(units, postLink, configuration); |
| |
| if (projector != null) |
| { |
| createProjector(configuration, projector, movie, swfOut); |
| } |
| else |
| { |
| CompilerAPI.encode(configuration, movie, swfOut); |
| } |
| } |
| |
| swfOut.flush(); |
| swfOut.close(); |
| |
| // If incremental compilation is enabled, save the compilation units. |
| if (configuration.getCompilerConfiguration().getIncremental()) |
| { |
| // Make sure the checksums are all current. |
| swcChecksums.saveChecksums(units); |
| |
| RandomAccessFile incrementalFile = null; |
| try |
| { |
| incrementalFile = new RandomAccessFile(incrementalFileName, "rw"); |
| |
| // In case we're reusing the file, clear it. |
| incrementalFile.setLength(0); |
| |
| CompilerAPI.persistCompilationUnits( |
| configuration, fileSpec, sourceList, sourcePath, |
| resources, bundlePath, |
| sources, /* sources */ |
| units, /* units */ |
| swcChecksums.getChecksums(), |
| swcChecksums.getSwcDefSignatureChecksums(), |
| swcChecksums.getSwcFileChecksums(), |
| null, /* archiveFiles */ |
| "", incrementalFile); |
| } |
| catch (IOException ex) |
| { |
| ThreadLocalToolkit.logInfo(ex.getLocalizedMessage()); |
| |
| // Get rid of the cache file since the write failed. |
| new File(incrementalFileName).deleteOnExit(); |
| } |
| finally |
| { |
| if (incrementalFile != null) |
| { |
| try |
| { |
| incrementalFile.close(); |
| } |
| catch (IOException ex) |
| { |
| } |
| } |
| } |
| } |
| |
| ThreadLocalToolkit.log(new OutputMessage(FileUtil.getCanonicalPath(outputFile), |
| Long.toString(outputFile.length()))); |
| } |
| else |
| { |
| if (benchmark != null) |
| { |
| benchmark.stopTime(Benchmark.PRECOMPILE, false); |
| benchmark.startTime(Benchmark.POSTCOMPILE); |
| } |
| |
| // swf is already up-to-date so no need to compile/link or rewrite file |
| ThreadLocalToolkit.log(new NoUpdateMessage(FileUtil.getCanonicalPath(outputFile))); |
| } |
| |
| Set<IMxmlcExtension> extensions = ExtensionManager.getMxmlcExtensions( configuration.getCompilerConfiguration().getExtensionsConfiguration().getExtensionMappings() ); |
| for ( IMxmlcExtension extension : extensions ) |
| { |
| if(ThreadLocalToolkit.errorCount() == 0) { |
| extension.run( args ); |
| } |
| } |
| |
| } |
| catch (ConfigurationException ex) |
| { |
| ThreadLocalToolkit.logInfo( getStartMessage( "mxmlc" ) ); |
| processConfigurationException(ex, "mxmlc"); |
| } |
| catch (CompilerException ex) |
| { |
| assert ThreadLocalToolkit.errorCount() > 0; |
| } |
| catch (LinkerException ex) |
| { |
| assert ThreadLocalToolkit.errorCount() > 0; |
| } |
| catch (SwcException ex) |
| { |
| assert ThreadLocalToolkit.errorCount() > 0; |
| } |
| catch (Throwable t) // IOException, Throwable |
| { |
| ThreadLocalToolkit.logError(t.getLocalizedMessage()); |
| |
| if (Trace.error) |
| { |
| t.printStackTrace(); |
| } |
| } |
| finally |
| { |
| if (benchmark != null) |
| { |
| if ((ThreadLocalToolkit.errorCount() == 0) && |
| benchmark.hasStarted(Benchmark.POSTCOMPILE)) |
| { |
| benchmark.stopTime(Benchmark.POSTCOMPILE, false); |
| } |
| benchmark.totalTime(); |
| benchmark.peakMemoryUsage(true); |
| } |
| |
| if (transcoders != null) |
| { |
| for (Transcoder element : transcoders) |
| { |
| element.clear(); |
| } |
| } |
| |
| CompilerAPI.removePathResolver(); |
| } |
| } |
| |
| private static File getOutputFile(CommandLineConfiguration configuration, VirtualFile targetFile) |
| { |
| String name; |
| VirtualFile projector = configuration.getProjector(); |
| boolean createProjector = (projector != null && projector.getName().endsWith("avmplus.exe")); |
| |
| if (createProjector) |
| { |
| // output .exe |
| name = configuration.getOutput(); |
| if (name == null) |
| { |
| name = targetFile.getName(); |
| name = name.substring(0, name.lastIndexOf('.')) + ".exe"; |
| } |
| } |
| else |
| { |
| // output SWF |
| name = configuration.getOutput(); |
| if (name == null) |
| { |
| name = targetFile.getName(); |
| if (projector != null) |
| { |
| name = name.substring(0, name.lastIndexOf('.')) + ".exe"; |
| } |
| else |
| { |
| name = name.substring(0, name.lastIndexOf('.')) + ".swf"; |
| } |
| } |
| } |
| |
| return FileUtil.openFile(name, true); |
| } |
| |
| public static void createProjector(Configuration config, VirtualFile projector, ConsoleApplication app, OutputStream out) |
| { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| try |
| { |
| CompilerAPI.encode(app, baos); |
| createProjector(config, projector, baos, out); |
| } |
| catch (IOException ex) |
| { |
| } |
| } |
| |
| public static void createProjector(Configuration config, VirtualFile projector, Movie movie, OutputStream out) |
| { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| try |
| { |
| CompilerAPI.encode(config, movie, baos); |
| createProjector(config, projector, baos, out); |
| } |
| catch (IOException ex) |
| { |
| } |
| finally |
| { |
| } |
| } |
| |
| public static long createProjector(Configuration config, VirtualFile projector, ByteArrayOutputStream baos, OutputStream out) |
| { |
| long size = 0; |
| BufferedInputStream in = null; |
| try |
| { |
| in = new BufferedInputStream(projector.getInputStream()); |
| FileUtil.streamOutput(in, out); |
| byte header[] = new byte[8]; |
| header[0] = 0x56; |
| header[1] = 0x34; |
| header[2] = 0x12; |
| header[3] = (byte) 0xFA; |
| header[4] = (byte) (baos.size() & 0xFF); |
| header[5] = (byte) ((baos.size() >> 8) & 0xFF); |
| header[6] = (byte) ((baos.size() >> 16) & 0xFF); |
| header[7] = (byte) ((baos.size() >> 24) & 0xFF); |
| out.write(baos.toByteArray()); |
| out.write(header); |
| out.flush(); |
| size = projector.size() + baos.size() + 8; |
| } |
| catch (IOException ex) |
| { |
| size = 0; |
| } |
| finally |
| { |
| if (in != null) { try { in.close(); } catch (IOException ex) {} } |
| } |
| |
| return size; |
| } |
| |
| static private String l10nConfigPrefix = "flex2.configuration"; |
| |
| public static Configuration processConfiguration( LocalizationManager lmgr, String program, String[] args, |
| ConfigurationBuffer cfgbuf, Class<? extends Configuration> cls, String defaultVar) |
| throws ConfigurationException, IOException |
| { |
| return processConfiguration(lmgr, program, args, cfgbuf, cls, defaultVar, false); |
| } |
| |
| public static Configuration processConfiguration( LocalizationManager lmgr, String program, String[] args, |
| ConfigurationBuffer cfgbuf, Class<? extends Configuration> cls, String defaultVar, |
| boolean ignoreUnknownItems) |
| throws ConfigurationException, IOException |
| { |
| SystemPropertyConfigurator.load( cfgbuf, "flex" ); |
| |
| // Parse the command line a first time, to peak at stuff like |
| // "flexlib" and "load-config". The first parse is thrown |
| // away after that and we intentionally parse a second time |
| // below. See note below. |
| CommandLineConfigurator.parse( cfgbuf, defaultVar, args); |
| |
| String flexlib = cfgbuf.getToken( "flexlib" ); |
| if (flexlib == null) |
| { |
| String appHome = System.getProperty( "application.home" ); |
| |
| if (appHome == null) |
| { |
| appHome = "."; |
| } |
| else |
| { |
| appHome += File.separator + "frameworks"; // FIXME - need to eliminate this from the compiler |
| } |
| cfgbuf.setToken( "flexlib", appHome ); |
| } |
| |
| // Framework Type |
| // halo, gumbo, interop... |
| String framework = cfgbuf.getToken("framework"); |
| if (framework == null) |
| { |
| cfgbuf.setToken("framework", "halo"); |
| } |
| |
| String configname = cfgbuf.getToken( "configname" ); |
| if (configname == null) |
| { |
| cfgbuf.setToken( "configname", "flex" ); |
| } |
| |
| String buildNumber = cfgbuf.getToken( "build.number" ); |
| if (buildNumber == null) |
| { |
| if ("".equals(VersionInfo.getBuild())) |
| { |
| buildNumber = "workspace"; |
| } |
| else |
| { |
| buildNumber = VersionInfo.getBuild(); |
| } |
| cfgbuf.setToken( "build.number", buildNumber); |
| } |
| |
| |
| // We need to intercept "help" options because we want to try to correctly |
| // interpret them even when the rest of the configuration is totally screwed up. |
| |
| if (cfgbuf.getVar( "version" ) != null) |
| { |
| System.out.println(VersionInfo.buildMessage()); |
| System.exit(0); |
| } |
| |
| processHelp(cfgbuf, program, defaultVar, lmgr, args); |
| |
| // at this point, we should have enough to know both |
| // flexlib and the config file. |
| |
| ConfigurationPathResolver configResolver = new ConfigurationPathResolver(); |
| |
| List<ConfigurationValue> configs = cfgbuf.peekConfigurationVar( "load-config" ); |
| |
| if (configs != null) |
| { |
| for (ConfigurationValue cv : configs) |
| { |
| for (String path : cv.getArgs()) |
| { |
| VirtualFile configFile = ConfigurationPathResolver.getVirtualFile( path, configResolver, cv ); |
| cfgbuf.calculateChecksum(configFile); |
| InputStream in = configFile.getInputStream(); |
| if (in != null) |
| { |
| FileConfigurator.load(cfgbuf, new BufferedInputStream(in), configFile.getName(), |
| configFile.getParent(), "flex-config", ignoreUnknownItems); |
| } |
| else |
| { |
| throw new ConfigurationException.ConfigurationIOError( path, cv.getVar(), cv.getSource(), cv.getLine() ); |
| } |
| } |
| } |
| } |
| |
| PathResolver resolver = ThreadLocalToolkit.getPathResolver(); |
| // Load project file, if any... |
| List fileValues = cfgbuf.getVar( FILE_SPECS ); |
| if ((fileValues != null) && (fileValues.size() > 0)) |
| { |
| ConfigurationValue cv = (ConfigurationValue) fileValues.get( fileValues.size() - 1 ); |
| if (cv.getArgs().size() > 0) |
| { |
| String val = cv.getArgs().get( cv.getArgs().size() - 1 ); |
| int index = val.lastIndexOf( '.' ); |
| if (index != -1) |
| { |
| String project = val.substring( 0, index ) + "-config.xml"; |
| VirtualFile projectFile = resolver.resolve( configResolver, project ); |
| if (projectFile != null) |
| { |
| cfgbuf.calculateChecksum(projectFile); |
| InputStream in = projectFile.getInputStream(); |
| if (in != null) |
| { |
| FileConfigurator.load( cfgbuf, new BufferedInputStream(in), |
| projectFile.getName(), projectFile.getParent(), "flex-config", |
| ignoreUnknownItems); |
| } |
| } |
| } |
| } |
| } |
| |
| // The command line needs to take precedence over all defaults and config files. |
| // This is a bit gross, but by simply re-merging the command line back on top, |
| // we will get the behavior we want. |
| cfgbuf.clearSourceVars( CommandLineConfigurator.source ); |
| CommandLineConfigurator.parse(cfgbuf, defaultVar, args); |
| |
| ToolsConfiguration toolsConfiguration = null; |
| try |
| { |
| toolsConfiguration = (ToolsConfiguration)cls.newInstance(); |
| toolsConfiguration.setConfigPathResolver( configResolver ); |
| } |
| catch (Exception e) |
| { |
| LocalizationManager l10n = ThreadLocalToolkit.getLocalizationManager(); |
| throw new ConfigurationException(l10n.getLocalizedTextString(new CouldNotInstantiate(toolsConfiguration))); |
| } |
| cfgbuf.commit( toolsConfiguration ); |
| |
| // enterprise service config file has other config file dependencies. add them here... |
| calculateServicesChecksum(toolsConfiguration, cfgbuf); |
| |
| toolsConfiguration.validate( cfgbuf ); |
| |
| // consolidate license keys... |
| VirtualFile licenseFile = toolsConfiguration.getLicenseFile(); |
| if (licenseFile != null) |
| { |
| Map<String, String> fileLicenses = Tool.getLicenseMapFromFile(licenseFile.getName()); |
| Map<String, String> cmdLicenses = toolsConfiguration.getLicensesConfiguration().getLicenseMap(); |
| if (cmdLicenses == null) |
| { |
| toolsConfiguration.getLicensesConfiguration().setLicenseMap(fileLicenses); |
| } |
| else if (fileLicenses != null) |
| { |
| fileLicenses.putAll(cmdLicenses); |
| toolsConfiguration.getLicensesConfiguration().setLicenseMap(fileLicenses); |
| } |
| } |
| |
| return toolsConfiguration; |
| } |
| |
| static void processHelp(ConfigurationBuffer cfgbuf, String program, String defaultVar, LocalizationManager lmgr, String[] args) |
| { |
| if (cfgbuf.getVar( "help" ) != null) |
| { |
| Set<String> keywords = new HashSet<String>(); |
| List vals = cfgbuf.getVar( "help" ); |
| for (Iterator it = vals.iterator(); it.hasNext();) |
| { |
| ConfigurationValue val = (ConfigurationValue) it.next(); |
| for (Object element : val.getArgs()) |
| { |
| String keyword = (String) element; |
| while (keyword.startsWith( "-" )) |
| keyword = keyword.substring( 1 ); |
| keywords.add( keyword ); |
| } |
| } |
| if (keywords.size() == 0) |
| { |
| keywords.add( "help" ); |
| } |
| |
| ThreadLocalToolkit.logInfo( getStartMessage( program ) ); |
| System.out.println(); |
| System.out.println( CommandLineConfigurator.usage( program, defaultVar, cfgbuf, keywords, lmgr, l10nConfigPrefix )); |
| System.exit( 0 ); |
| } |
| |
| if (args.length == 0 && ("mxmlc".equals(program) || "compc".equals(program))) |
| { |
| ThreadLocalToolkit.logInfo( getStartMessage( program ) ); |
| System.err.println( CommandLineConfigurator.brief( program, defaultVar, lmgr, l10nConfigPrefix )); |
| System.exit( 1 ); |
| } |
| } |
| |
| private static void calculateServicesChecksum(Configuration config, ConfigurationBuffer cfgbuf) |
| { |
| Map<String,Long> services = null; |
| if (config.getCompilerConfiguration().getServicesDependencies() != null) |
| { |
| services = config.getCompilerConfiguration().getServicesDependencies().getConfigPaths(); |
| } |
| |
| if (services != null) |
| { |
| for (Entry<String, Long> entry : services.entrySet()) |
| { |
| cfgbuf.calculateChecksum(entry.getKey(), entry.getValue()); |
| } |
| } |
| } |
| |
| public static void processConfigurationException(ConfigurationException ex, String program) |
| { |
| ThreadLocalToolkit.log( ex ); |
| |
| if (ex.source == null || ex.source.equals("command line")) |
| { |
| Map<String, String> p = new HashMap<String, String>(); |
| p.put( "program", program ); |
| String help = ThreadLocalToolkit.getLocalizationManager().getLocalizedTextString( "flex2.compiler.CommandLineHelp", p ); |
| if (help != null) |
| { |
| // "Use '" + program + " -help' for information about using the command line."); |
| System.err.println( help ); |
| } |
| } |
| } |
| |
| private static String getStartMessage( String program ) |
| { |
| LocalizationManager l10n = ThreadLocalToolkit.getLocalizationManager(); |
| |
| return l10n.getLocalizedTextString(new StartMessage(program, VersionInfo.buildMessage())); |
| } |
| |
| // error messages |
| |
| public static class InitialSetup extends CompilerMessage.CompilerInfo |
| { |
| private static final long serialVersionUID = 1333039844101599298L; |
| |
| public InitialSetup() |
| { |
| super(); |
| } |
| } |
| |
| public static class DumpConfig extends CompilerMessage.CompilerInfo |
| { |
| private static final long serialVersionUID = 953067728556782737L; |
| |
| public DumpConfig(String filename) |
| { |
| this.filename = filename; |
| } |
| public final String filename; |
| } |
| |
| public static class LoadedSWCs extends CompilerMessage.CompilerInfo |
| { |
| private static final long serialVersionUID = 5287457959220324715L; |
| |
| public LoadedSWCs(int num) |
| { |
| super(); |
| this.num = num; |
| } |
| |
| public final int num; |
| } |
| |
| public static class CouldNotInstantiate extends CompilerMessage.CompilerInfo |
| { |
| private static final long serialVersionUID = -8970190710117830662L; |
| |
| public CouldNotInstantiate(Configuration config) |
| { |
| super(); |
| this.config = config; |
| } |
| |
| public final Configuration config; |
| } |
| |
| public static class StartMessage extends CompilerMessage.CompilerInfo |
| { |
| private static final long serialVersionUID = 4807822711658875257L; |
| |
| public StartMessage(String program, String buildMessage) |
| { |
| super(); |
| this.program = program; |
| this.buildMessage = buildMessage; |
| } |
| |
| public final String program, buildMessage; |
| } |
| |
| public static class OutputMessage extends CompilerMessage.CompilerInfo |
| { |
| private static final long serialVersionUID = -4859993585489031839L; |
| |
| public String name; |
| public String length; |
| |
| public OutputMessage(String name, String length) |
| { |
| this.name = name; |
| this.length = length; |
| } |
| } |
| |
| public static class NoUpdateMessage extends CompilerMessage.CompilerInfo |
| { |
| private static final long serialVersionUID = 6943388392279226490L; |
| public String name; |
| |
| public NoUpdateMessage(String name) |
| { |
| this.name = name; |
| } |
| } |
| |
| } |
| |