| /* |
| * |
| * 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.*; |
| import flex2.compiler.*; |
| import flex2.compiler.SourceList.UnsupportedFileType; |
| import flex2.compiler.ResourceBundlePath; |
| import flex2.compiler.abc.AbcCompiler; |
| import flex2.compiler.as3.As3Compiler; |
| import flex2.compiler.as3.EmbedExtension; |
| import flex2.compiler.as3.SignatureExtension; |
| import flex2.compiler.as3.StyleExtension; |
| import flex2.compiler.as3.HostComponentExtension; |
| import flex2.compiler.as3.binding.BindableExtension; |
| import flex2.compiler.as3.SkinPartExtension; |
| import flex2.compiler.as3.managed.ManagedExtension; |
| import flex2.compiler.common.CompilerConfiguration; |
| import flex2.compiler.common.Configuration; |
| import flex2.compiler.css.CssCompiler; |
| import flex2.compiler.fxg.FXGCompiler; |
| import flex2.compiler.i18n.I18nCompiler; |
| import flex2.compiler.i18n.I18nUtils; |
| import flex2.compiler.io.VirtualFile; |
| import flex2.compiler.media.*; |
| import flex2.compiler.mxml.MxmlCompiler; |
| import flex2.compiler.swc.SwcCache; |
| import flex2.compiler.util.MimeMappings; |
| import flex2.compiler.util.NameMappings; |
| import flex2.compiler.util.ThreadLocalToolkit; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * This class is used externally by the webtier compiler and |
| * internally by some of the other flex tools, like fcsh and mxmlc. |
| */ |
| public final class WebTierAPI extends Tool |
| { |
| /** |
| * This method is called by flex.webtier.server.j2ee.CompilerFilter. |
| */ |
| public static Target compile(VirtualFile targetFile, Configuration configuration, SwcCache swcCache, Map licenseMap) |
| throws CompilerException |
| { |
| Target target = new Target(); |
| |
| try |
| { |
| if (configuration.benchmark()) |
| { |
| flex2.compiler.CompilerAPI.runBenchmark(); |
| } |
| else |
| { |
| flex2.compiler.CompilerAPI.disableBenchmark(); |
| } |
| |
| target.configuration = configuration; |
| |
| flex2.compiler.CompilerAPI.useAS3(); |
| flex2.compiler.CompilerAPI.usePathResolver(); |
| flex2.compiler.CompilerAPI.setupHeadless(configuration); |
| |
| // set up for localizing messages |
| LocalizationManager l10n = new LocalizationManager(); |
| l10n.addLocalizer( new XLRLocalizer() ); |
| l10n.addLocalizer( new ResourceBundleLocalizer() ); |
| ThreadLocalToolkit.setLocalizationManager( l10n ); |
| |
| checkSupportedTargetMimeType(targetFile); |
| |
| List<VirtualFile> virtualFileList = new ArrayList<VirtualFile>(); |
| virtualFileList.add(targetFile); |
| |
| CompilerConfiguration compilerConfig = configuration.getCompilerConfiguration(); |
| NameMappings mappings = flex2.compiler.CompilerAPI.getNameMappings(configuration); |
| |
| // get standard bundle of compilers, transcoders |
| flex2.compiler.Transcoder[] transcoders = getTranscoders(configuration); |
| flex2.compiler.SubCompiler[] compilers = getCompilers(compilerConfig, mappings, transcoders); |
| |
| // create a FileSpec... |
| target.fileSpec = new FileSpec(Collections.<VirtualFile>emptyList(), getFileSpecMimeTypes()); |
| |
| VirtualFile[] asClasspath = compilerConfig.getSourcePath(); |
| |
| // create a SourceList... |
| target.sourceList = new SourceList(virtualFileList, |
| asClasspath, |
| targetFile, |
| getSourcePathMimeTypes()); |
| // create a SourcePath... |
| target.sourcePath = new SourcePath(asClasspath, |
| targetFile, |
| getSourcePathMimeTypes(), |
| compilerConfig.allowSourcePathOverlap()); |
| |
| // create a ResourceContainer |
| target.resources = new ResourceContainer(); |
| |
| target.bundlePath = new ResourceBundlePath(configuration.getCompilerConfiguration(), targetFile); |
| |
| if (ThreadLocalToolkit.getBenchmark() != null) |
| { |
| ThreadLocalToolkit.getBenchmark().benchmark(l10n.getLocalizedTextString(new Mxmlc.InitialSetup())); |
| } |
| |
| // load SWCs |
| CompilerSwcContext swcContext = new CompilerSwcContext(); |
| swcContext.load(compilerConfig.getLibraryPath(), |
| Configuration.getAllExcludedLibraries(compilerConfig, configuration), |
| compilerConfig.getThemeFiles(), |
| compilerConfig.getIncludeLibraries(), |
| mappings, |
| I18nUtils.getTranslationFormat(compilerConfig), |
| swcCache); |
| configuration.addExterns(swcContext.getExterns()); |
| configuration.addIncludes( swcContext.getIncludes() ); |
| configuration.getCompilerConfiguration().addThemeCssFiles(swcContext.getThemeStyleSheets()); |
| |
| // validate CompilationUnits in FileSpec, SourceList and SourcePath |
| flex2.compiler.CompilerAPI.validateCompilationUnits(target.fileSpec, target.sourceList, target.sourcePath, |
| target.bundlePath, target.resources, swcContext, null, configuration); |
| |
| // create a SymbolTable... |
| final SymbolTable symbolTable = new SymbolTable(configuration); |
| target.perCompileData = symbolTable.perCompileData; |
| |
| // compile |
| target.units = flex2.compiler.CompilerAPI.compile(target.fileSpec, target.sourceList, null, target.sourcePath, target.resources, |
| target.bundlePath, swcContext, symbolTable, mappings, configuration, compilers, |
| new PreLink(), licenseMap, new ArrayList<Source>()); |
| |
| return target; |
| } |
| catch (CompilerException ex) |
| { |
| throw ex; |
| } |
| catch (Throwable t) |
| { |
| String message = t.getMessage(); |
| if (message == null) |
| { |
| message = t.getClass().getName(); |
| } |
| ThreadLocalToolkit.logError(message); |
| throw new CompilerException(message); |
| } |
| finally |
| { |
| flex2.compiler.CompilerAPI.removePathResolver(); |
| } |
| } |
| |
| /** |
| * This method is used by Toolkit. |
| * |
| * @see flex2.tools.oem.Toolkit |
| */ |
| public static long optimize(InputStream in, OutputStream out, Configuration configuration) throws IOException |
| { |
| // decoder |
| Movie movie = new Movie(); |
| TagDecoder tagDecoder = new TagDecoder(in); |
| MovieDecoder movieDecoder = new MovieDecoder(movie); |
| tagDecoder.parse(movieDecoder); |
| |
| // optimize |
| optimize(movie, configuration); |
| |
| //TODO PERFORMANCE: A lot of unnecessary recopying and buffering here |
| // encode |
| TagEncoder handler = new TagEncoder(); |
| MovieEncoder encoder = new MovieEncoder(handler); |
| encoder.export(movie); |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| handler.writeTo(baos); |
| out.write(baos.toByteArray()); |
| |
| return baos.size(); |
| } |
| |
| /** |
| * This method is used by Optimizer. |
| * |
| * @see flex2.tools.Optimizer |
| */ |
| static void optimize(Movie m, Configuration configuration) |
| { |
| // don't keep debug opcodes |
| // abc merge |
| // peephole optimization |
| m.enableDebugger = null; |
| m.uuid = null; |
| PostLink postLink = (configuration != null) ? new PostLink(configuration) : new PostLink(false, true); |
| postLink.run(m); |
| } |
| |
| /** |
| * This method is used by Toolkit. |
| * |
| * @see flex2.tools.oem.Toolkit |
| */ |
| public static long optimize(InputStream in, OutputStream out) throws IOException |
| { |
| return optimize(in, out, null); |
| } |
| |
| /** |
| * This method is called by flex.webtier.server.j2ee.IncrementalCompilerFilter. |
| */ |
| public static Transcoder[] getTranscoders( Configuration cfg ) |
| { |
| // create a list of supported transcoders |
| return new Transcoder[]{new JPEGTranscoder(), new LosslessImageTranscoder(), //new JAITranscoder(), |
| new SVGTranscoder(cfg.getCompilerConfiguration().showDeprecationWarnings()), |
| new SoundTranscoder(), new MovieTranscoder(), new FontTranscoder(cfg), |
| new DataTranscoder(), new XMLTranscoder(), |
| new SkinTranscoder(), new PBJTranscoder() |
| }; |
| } |
| |
| /** |
| * This method is called by flex.webtier.server.j2ee.IncrementalCompilerFilter. |
| */ |
| public static flex2.compiler.SubCompiler[] getCompilers(CompilerConfiguration compilerConfig, NameMappings mappings, |
| Transcoder[] transcoders) |
| { |
| // support .AS3 |
| As3Compiler asc = new As3Compiler(compilerConfig); |
| |
| // signature generation should occur before other extensions can touch the syntax tree |
| if (!compilerConfig.getDisableIncrementalOptimizations()) |
| { |
| SignatureExtension.init(compilerConfig); |
| asc.addCompilerExtension(SignatureExtension.getInstance()); |
| } |
| final String gendir = (compilerConfig.keepGeneratedActionScript() |
| ? compilerConfig.getGeneratedDirectory() |
| : null); |
| final boolean generateAbstractSyntaxTree = compilerConfig.getGenerateAbstractSyntaxTree(); |
| asc.addCompilerExtension(new EmbedExtension(transcoders, gendir, compilerConfig.showDeprecationWarnings())); |
| asc.addCompilerExtension(new StyleExtension()); |
| // IMPORTANT!!!! The HostComponentExtension must run before the BindableExtension!!!! |
| asc.addCompilerExtension(new HostComponentExtension(compilerConfig.reportMissingRequiredSkinPartsAsWarnings())); |
| asc.addCompilerExtension(new BindableExtension(gendir, generateAbstractSyntaxTree, false)); |
| asc.addCompilerExtension(new ManagedExtension(gendir, generateAbstractSyntaxTree, |
| compilerConfig.getServicesDependencies(), false)); |
| asc.addCompilerExtension(new SkinPartExtension()); |
| // asc.addCompilerExtension(new flex2.compiler.util.TraceExtension()); |
| |
| // support MXML |
| MxmlCompiler mxmlc = new MxmlCompiler(compilerConfig, compilerConfig, |
| mappings, transcoders); |
| |
| // support ABC |
| AbcCompiler abc = new AbcCompiler(compilerConfig); |
| abc.addCompilerExtension(new StyleExtension()); |
| |
| // abc.addCompilerExtension(new flex2.compiler.util.TraceExtension()); |
| |
| // support FXG |
| FXGCompiler fxg = new FXGCompiler(compilerConfig, mappings); |
| |
| // support i18n (.properties) |
| I18nCompiler prop = new I18nCompiler(compilerConfig, transcoders); |
| |
| // support CSS |
| CssCompiler css = new CssCompiler(compilerConfig, transcoders, mappings); |
| |
| return new SubCompiler[]{asc, mxmlc, abc, fxg, prop, css}; |
| } |
| |
| /** |
| * This method is used by Mxmlc, Fcsh, and Application. |
| * |
| * @see flex2.tools.Mxmlc |
| * @see flex2.tools.Fcsh |
| * @see flex2.tools.oem.Application |
| */ |
| public static void checkSupportedTargetMimeType(VirtualFile targetFile) throws CompilerException |
| { |
| String[] mimeTypes = getTargetMimeTypes(); |
| |
| for (int i = 0, length = mimeTypes.length; i < length; i++) |
| { |
| if (mimeTypes[i].equals(targetFile.getMimeType())) |
| { |
| return; |
| } |
| } |
| |
| UnsupportedFileType ex = new UnsupportedFileType(targetFile.getName()); |
| ThreadLocalToolkit.log(ex); |
| throw ex; |
| } |
| |
| /** |
| * This method is called by flex.webtier.server.j2ee.IncrementalCompilerFilter. |
| */ |
| public static String[] getFileSpecMimeTypes() |
| { |
| return new String[]{MimeMappings.AS, MimeMappings.MXML, MimeMappings.FXG, MimeMappings.CSS, MimeMappings.ABC}; |
| } |
| |
| /** |
| * This method is called by flex.webtier.server.j2ee.IncrementalCompilerFilter. |
| */ |
| public static String[] getSourceListMimeTypes() |
| { |
| return new String[]{MimeMappings.AS, MimeMappings.MXML, MimeMappings.FXG, MimeMappings.CSS}; |
| } |
| |
| /** |
| * This method is called by flex.webtier.server.j2ee.IncrementalCompilerFilter. |
| */ |
| public static String[] getSourcePathMimeTypes() |
| { |
| return new String[]{MimeMappings.AS, MimeMappings.MXML, MimeMappings.FXG}; |
| } |
| |
| /** |
| * This method is called by flex.webtier.server.j2ee.IncrementalCompilerFilter. |
| * |
| * FXG is not included in the list of target mime types, because |
| * the compiler doesn't support an FXG based root yet and we don't |
| * want to allow broken SWF's to be created. |
| */ |
| public static String[] getTargetMimeTypes() |
| { |
| return new String[]{MimeMappings.AS, MimeMappings.MXML, MimeMappings.CSS}; |
| } |
| } |