net.flexmojos.oss.plugin.compiler.AbstractFlexCompilerMojo Maven / Gradle / Ivy
/**
* Flexmojos is a set of maven goals to allow maven users to compile, optimize and test Flex SWF, Flex SWC, Air SWF and Air SWC.
* Copyright (C) 2008-2012 Marvin Froeder
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package net.flexmojos.oss.plugin.compiler;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static net.flexmojos.oss.matcher.artifact.ArtifactMatcher.classifier;
import static net.flexmojos.oss.matcher.artifact.ArtifactMatcher.scope;
import static net.flexmojos.oss.matcher.artifact.ArtifactMatcher.type;
import static net.flexmojos.oss.plugin.common.FlexClassifier.CONFIGS;
import static net.flexmojos.oss.plugin.common.FlexClassifier.LINK_REPORT;
import static net.flexmojos.oss.plugin.common.FlexClassifier.SIZE_REPORT;
import static net.flexmojos.oss.plugin.common.FlexExtension.ANE;
import static net.flexmojos.oss.plugin.common.FlexExtension.CSS;
import static net.flexmojos.oss.plugin.common.FlexExtension.RB_SWC;
import static net.flexmojos.oss.plugin.common.FlexExtension.SWC;
import static net.flexmojos.oss.plugin.common.FlexExtension.SWF;
import static net.flexmojos.oss.plugin.common.FlexExtension.SWZ;
import static net.flexmojos.oss.plugin.common.FlexExtension.XML;
import static net.flexmojos.oss.plugin.common.FlexScopes.CACHING;
import static net.flexmojos.oss.plugin.common.FlexScopes.COMPILE;
import static net.flexmojos.oss.plugin.common.FlexScopes.EXTERNAL;
import static net.flexmojos.oss.plugin.common.FlexScopes.INTERNAL;
import static net.flexmojos.oss.plugin.common.FlexScopes.MERGED;
import static net.flexmojos.oss.plugin.common.FlexScopes.RSL;
import static net.flexmojos.oss.util.PathUtil.files;
import static net.flexmojos.oss.util.PathUtil.pathsList;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.*;
import java.util.Map.Entry;
import org.apache.commons.io.filefilter.AgeFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Contributor;
import org.apache.maven.model.Developer;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.hamcrest.Matcher;
import net.flexmojos.oss.compatibilitykit.FlexMojo;
import net.flexmojos.oss.compatibilitykit.VersionUtils;
import net.flexmojos.oss.compiler.IApplicationDomain;
import net.flexmojos.oss.compiler.ICompcConfiguration;
import net.flexmojos.oss.compiler.ICompilerConfiguration;
import net.flexmojos.oss.compiler.IDefaultScriptLimits;
import net.flexmojos.oss.compiler.IDefaultSize;
import net.flexmojos.oss.compiler.IDefine;
import net.flexmojos.oss.compiler.IExtension;
import net.flexmojos.oss.compiler.IExtensionsConfiguration;
import net.flexmojos.oss.compiler.IFontsConfiguration;
import net.flexmojos.oss.compiler.IFrame;
import net.flexmojos.oss.compiler.IFramesConfiguration;
import net.flexmojos.oss.compiler.ILicense;
import net.flexmojos.oss.compiler.ILicensesConfiguration;
import net.flexmojos.oss.compiler.ILocalizedDescription;
import net.flexmojos.oss.compiler.ILocalizedTitle;
import net.flexmojos.oss.compiler.IMetadataConfiguration;
import net.flexmojos.oss.compiler.IMxmlConfiguration;
import net.flexmojos.oss.compiler.INamespace;
import net.flexmojos.oss.compiler.INamespacesConfiguration;
import net.flexmojos.oss.compiler.IRuntimeSharedLibraryPath;
import net.flexmojos.oss.compiler.IRuntimeSharedLibrarySettingsConfiguration;
import net.flexmojos.oss.compiler.command.Result;
import net.flexmojos.oss.license.LicenseCalculator;
import net.flexmojos.oss.plugin.AbstractMavenMojo;
import net.flexmojos.oss.plugin.RuntimeMavenResolutionException;
import net.flexmojos.oss.plugin.common.FlexScopes;
import net.flexmojos.oss.plugin.compiler.attributes.MavenArtifact;
import net.flexmojos.oss.plugin.compiler.attributes.MavenDefaultScriptLimits;
import net.flexmojos.oss.plugin.compiler.attributes.MavenDefaultSize;
import net.flexmojos.oss.plugin.compiler.attributes.MavenExtension;
import net.flexmojos.oss.plugin.compiler.attributes.MavenFontsConfiguration;
import net.flexmojos.oss.plugin.compiler.attributes.MavenFrame;
import net.flexmojos.oss.plugin.compiler.attributes.MavenMetadataConfiguration;
import net.flexmojos.oss.plugin.compiler.attributes.MavenNamespace;
import net.flexmojos.oss.plugin.compiler.attributes.MavenRuntimeException;
import net.flexmojos.oss.plugin.compiler.lazyload.Cacheable;
import net.flexmojos.oss.plugin.utilities.ConfigurationResolver;
import net.flexmojos.oss.plugin.utilities.MavenUtils;
import net.flexmojos.oss.util.PathUtil;
public abstract class AbstractFlexCompilerMojo>
extends AbstractMavenMojo
implements ICompilerConfiguration, IFramesConfiguration, ILicensesConfiguration, IMetadataConfiguration,
IMxmlConfiguration, INamespacesConfiguration, IExtensionsConfiguration, Cacheable, Cloneable, FlexMojo,
IRuntimeSharedLibrarySettingsConfiguration
{
private static final Object lock = new Object();
public static final String PROJECT_TYPE = "getProjectType";
/**
* Generate an accessible SWF
*
* Equivalent to -compiler.accessible
*
*
* @parameter expression="${flex.accessible}"
*/
private Boolean accessible;
/**
* Specifies actionscript file encoding. If there is no BOM in the AS3 source files, the compiler will use this file
* encoding.
*
* Equivalent to -compiler.actionscript-file-encoding
*
*
* @parameter expression="${flex.actionscriptFileEncoding}"
*/
private String actionscriptFileEncoding;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.adjust-opdebugline
*
*
* @parameter expression="${flex.adjustOpdebugline}"
*/
private Boolean adjustOpdebugline;
/**
* If true, a style manager will add style declarations to the local style manager without checking to see if the
* parent already has the same style selector with the same properties. If false, a style manager will check the
* parent to make sure a style with the same properties does not already exist before adding one locally.
* If there is no local style manager created for this application, then don't check for duplicates. Just use the
* old "selector exists" test.
*
* Equivalent to -compiler.allow-duplicate-style-declaration
*
*
* @parameter expression="${flex.allowDuplicateDefaultStyleDeclarations}"
*/
private Boolean allowDuplicateDefaultStyleDeclarations;
/**
* checks if a source-path entry is a subdirectory of another source-path entry. It helps make the package names of
* MXML components unambiguous.
*
* Equivalent to -compiler.allow-source-path-overlap
*
*
* @parameter expression="${flex.allowSourcePathOverlap}"
*/
private Boolean allowSourcePathOverlap;
/**
* Override the application domain an RSL is loaded into. The supported values are 'current', 'default', 'parent',
* or 'top-level'
*
* Equivalent to -runtime-shared-library-settings.application-domains
*
* Usage:
*
*
* <applicationDomains>
* <applicationDomain>
* <pathElement>path</pathElement>
* <applicationDomain>current</applicationDomain>
* </applicationDomain>
* <applicationDomain>
* <pathElement>path</pathElement>
* <applicationDomain>default</applicationDomain>
* </applicationDomain>
* </applicationDomains>
*
*
* @parameter
*/
private MavenApplicationDomains[] applicationDomains;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.archive-classes-and-assets
*
*
* @parameter expression="${flex.archiveClassesAndAssets}"
*/
private Boolean archiveClassesAndAssets;
/**
* Use the ActionScript 3 class based object model for greater performance and better error reporting. In the class
* based object model most built-in functions are implemented as fixed methods of classes
*
* Equivalent to -compiler.as3
*
*
* @parameter expression="${flex.as3}"
*/
private Boolean as3;
/**
* Output performance benchmark
*
* Equivalent to -benchmark
*
*
* @parameter expression="${flex.benchmark}"
*/
protected Boolean benchmark;
/**
* DOCME undocumented by adobe
*
* Equivalent to -benchmark-compiler-details
*
* 0 = none, 1 = light, 5 = verbose
*
* @parameter expression="${flex.benchmarkCompilerDetails}"
*/
private Integer benchmarkCompilerDetails;
/**
* DOCME undocumented by adobe
*
* Equivalent to -benchmark-time-filter
*
* min time of units to log in ms
*
* @parameter expression="${flex.benchmarkTimeFilter}"
*/
private Long benchmarkTimeFilter;
/**
* Classifier to add to the artifact generated. If given, the artifact will be an attachment instead.
*
* @parameter expression="${flex.classifier}"
*/
protected String classifier;
/**
* Specifies a compatibility version
*
* Equivalent to -compiler.mxml.compatibility-version
*
*
* @parameter expression="${flex.compatibilityVersion}"
*/
private String compatibilityVersion;
/**
* @component
* @readonly
*/
protected net.flexmojos.oss.compiler.FlexCompiler compiler;
/**
* A list of warnings that should be enabled/disabled
*
* Equivalent to -compiler.show-actionscript-warnings, -compiler.show-binding-warnings,
* -compiler.show-shadowed-device-font-warnings, -compiler.show-unused-type-selector-warnings and -compiler.warn-*
*
* Usage:
*
*
* <compilerWarnings>
* <show-actionscript-warnings>true</show-actionscript-warnings>
* <warn-bad-nan-comparison>false</warn-bad-nan-comparison>
* </compilerWarnings>
*
*
* @parameter
*/
private final Map compilerWarnings = new LinkedHashMap();
/**
* The maven compile source roots
*
* Equivalent to -compiler.source-path
*
* List of path elements that form the roots of ActionScript class
*
* @parameter expression="${project.compileSourceRoots}"
* @required
* @readonly
*/
private List compileSourceRoots;
/**
* DOCME Guess what, undocumented by adobe.
*
* Equivalent to -compiler.compress
*
*
* @parameter expression="${flex.compress}"
*/
private Boolean compress;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.conservative
*
* compiler algorithm settings
*
* @parameter expression="${flex.conservative}"
*/
private Boolean conservative;
/**
* Path to replace {context.root} tokens for service channel endpoints
*
* Equivalent to -compiler.context-root
*
*
* @parameter expression="${flex.contextRoot}"
*/
private String contextRoot;
/**
* Generates a movie that is suitable for debugging
*
* Equivalent to -compiler.debug
*
*
* @parameter expression="${flex.debug}"
*/
private Boolean debug;
/**
* The password to include in debuggable SWFs
*
* Equivalent to -debug-password
*
*
* @parameter expression="${flex.debugPassword}"
*/
protected String debugPassword;
/**
* Default background color (may be overridden by the application code)
*
* Equivalent to -default-background-color
*
*
* @parameter expression="${flex.defaultBackgroundColor}"
*/
private Integer defaultBackgroundColor;
/**
* Default frame rate to be used in the SWF
*
* Equivalent to -default-frame-rate
*
*
* @parameter expression="${flex.defaultFrameRate}"
*/
private Integer defaultFrameRate;
/**
* Default value of resourceBundleList used when it is not defined
*
* @parameter default-value= "${project.build.directory}/${project.build.finalName}-rb.properties"
* @readonly
*/
private File defaultResourceBundleList;
/**
* Default script execution limits (may be overridden by root attributes)
*
* Equivalent to -default-script-limits
*
* Usage:
*
*
* <defaultScriptLimits>
* <maxExecutionTime>???</maxExecutionTime>
* <maxRecursionDepth>???</maxRecursionDepth>
* </defaultScriptLimits>
*
*
* @parameter
*/
private MavenDefaultScriptLimits defaultScriptLimits;
/**
* Location of defaults style stylesheets
*
* Equivalent to -compiler.defaults-css-url
*
* Usage:
*
*
* <defaultsCssFiles>
* <defaultsCssFile>???</defaultsCssFile>
* <defaultsCssFile>???</defaultsCssFile>
* </defaultsCssFiles>
*
*
* @parameter
*/
private File[] defaultsCssFiles;
/**
* Defines the location of the default style sheet. Setting this option overrides the implicit use of the
* defaults.css style sheet in the framework.swc file
*
* Equivalent to -compiler.defaults-css-url
*
*
* @parameter expression="${flex.defaultsCssUrl}"
*/
private String defaultsCssUrl;
/**
* Default application size (may be overridden by root attributes in the application)
*
* Equivalent to -default-size
*
* Usage:
*
*
* <defaultSize>
* <height>???</height>
* <width>???</width>
* </defaultSize>
*
*
* @parameter
*/
private MavenDefaultSize defaultSize;
/**
* Define a global AS3 conditional compilation definition, e.g. -define=CONFIG::debugging,true or
* -define+=CONFIG::debugging,true (to append to existing definitions in flex-config.xml)
*
* Equivalent to -compiler.define
*
* Usage:
*
*
* <defines>
* <property>
* <name>SOMETHING::aNumber</name>
* <value>2.2</value>
* </property>
* <property>
* <name>SOMETHING::aString</name>
* <value>"text"</value>
* </property>
* </defines>
*
*
* @parameter
*/
private Properties defines;
/**
* Back-door to disable optimizations in case they are causing problems
*
* Equivalent to -compiler.disable-incremental-optimizations
*
*
* @parameter expression="${flex.disableIncrementalOptimizations}"
*/
private Boolean disableIncrementalOptimizations;
/**
* DOCME undocumented
*
* Equivalent to -compiler.doc
*
*
* @parameter expression="${flex.doc}"
*/
private Boolean doc;
/**
* Write a file containing all currently set configuration values in a format suitable for use as a flex config file
*
* Equivalent to -dump-config
*
*
* @parameter expression="${flex.dumpConfig}"
*/
private boolean dumpConfigAttach;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.enable-runtime-design-layers
*
*
* @parameter expression="${flex.enableRuntimeDesignLayers}"
*/
private Boolean enableRuntimeDesignLayers;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.enable-swc-version-filtering
*
*
* @parameter expression="${flex.enableSwcVersionFiltering}"
*/
private Boolean enableSwcVersionFiltering;
/**
* Use the ECMAScript edition 3 prototype based object model to allow dynamic overriding of prototype properties. In
* the prototype based object model built-in functions are implemented as dynamic properties of prototype objects
*
* Equivalent to -compiler.es
*
*
* @parameter expression="${flex.es}"
*/
private Boolean es;
/**
* Configure extensions to flex compiler
*
* Equivalent to -compiler.extensions.extension
*
* Usage:
*
*
* <extensions>
* <extension>
* <extensionArtifact>
* <groupId>org.myproject</groupId>
* <artifactId>my-extension</artifactId>
* <version>1.0</version>
* </extensionArtifact>
* <parameters>
* <parameter>param1</parameter>
* <parameter>param2</parameter>
* <parameter>param3</parameter>
* </parameters>
* </extension>
* </extensions>
*
*
* @parameter
*/
private MavenExtension[] extensions;
/**
* A list of symbols to omit from linking when building a SWF
*
* Equivalent to -externs
*
* Usage:
*
*
* <externs>
* <extern>???</extern>
* <extern>???</extern>
* </externs>
*
*
* @parameter
*/
private String[] externs;
/**
* The name of the compiled file
*
* @parameter default-name="${project.build.finalName}" expression="${flex.finalName}"
*/
protected String finalName;
/**
* Fonts configurations to be used on SWF compilation
*
* Equivalent to -compiler.fonts.*
*
* Usage:
*
*
* <fonts>
* <advancedAntiAliasing>true</advancedAntiAliasing>
* <flashType>true</flashType>
* <languages>
* <englishRange>U+0020-U+007E</englishRange>
* </languages>
* <localFontsSnapshot>${baseDir}/src/main/resources/fonts.ser</localFontsSnapshot>
* <managers>
* <manager>flash.fonts.BatikFontManager</manager>
* </managers>
* <maxCachedFonts>20</maxCachedFonts>
* <maxGlyphsPerFace>1000</maxGlyphsPerFace>
* </fonts>
*
*
* @parameter
*/
private MavenFontsConfiguration fonts;
/**
* Force an RSL to be loaded, overriding the removal caused by using the remove-unused-rsls option.
*
* Equivalent to -runtime-shared-library-settings.force-rsls
*
*
* @parameter
*/
private String[] forceRsls;
/**
* A SWF frame label with a sequence of classnames that will be linked onto the frame
*
* Equivalent to -frames.frame
*
* Usage:
*
*
* <frames>
* <frame>
* <label>???</label>
* <classNames>
* <className>???</className>
* <className>???</className>
* </classNames>
* </frame>
* </frames>
*
*
* @parameter
*/
private MavenFrame[] frames;
/**
* DOCME undocumented by adobe
*
* Equivalent to -framework
*
*
* @parameter expression="${flex.framework}"
*/
private String framework;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.generate-abstract-syntax-tree
*
*
* @parameter expression="${flex.generateAbstractSyntaxTree}"
*/
private Boolean generateAbstractSyntaxTree;
/**
* DOCME Undocumented by adobe
*
* Equivalent to -generated-frame-loader
*
*
* @parameter expression="${flex.generateFrameLoader}"
*/
private Boolean generateFrameLoader;
/**
* A flag to set when Flex is running on a server without a display
*
* Equivalent to -compiler.headless-server
*
*
* @parameter expression="${flex.headlessServer}"
*/
private Boolean headlessServer;
/**
* Only include inheritance dependencies of classes specified with include-classes.
*
* Equivalent to -include-inheritance-dependencies-only
*
*
* @parameter expression="${flex.includeInheritanceDependenciesOnly}"
*/
private Boolean includeInheritanceDependenciesOnly;
/**
* A list of resource bundles to include in the output SWC
*
* Equivalent to -include-resource-bundles
*
* Usage:
*
*
* <includeResourceBundles>
* <rb>SharedResources</rb>
* <rb>Collections</rb>
* </includeResourceBundles>
*
*
* @parameter
*/
protected List includeResourceBundles;
/**
* A list of symbols to always link in when building a SWF
*
* Equivalent to -includes
*
* Usage:
*
*
* <includes>
* <include>???</include>
* <include>???</include>
* </includes>
*
*
* @parameter
*/
private String[] includes;
/**
* Enables incremental compilation
*
* Equivalent to -compiler.incremental
*
*
* @parameter expression="${flex.incremental}"
*/
private Boolean incremental;
/**
* Enables the compiled application or module to set styles that only affect itself and its children.
* Allow the user to decide if the compiled application/module should have its own style manager
*
* Equivalent to -compiler.isolate-styles
*
*
* @parameter expression="${flex.isolateStyles}"
*/
private Boolean isolateStyles;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.java-profiler-class
*
*
* @parameter expression="${flex.javaProfilerClass}"
*/
private String javaProfilerClass;
/**
* Disables the pruning of unused CSS type selectors
*
* Equivalent to -compiler.keep-all-type-selectors
*
*
* @parameter expression="${flex.keepAllTypeSelectors}"
*/
private Boolean keepAllTypeSelectors;
/**
* Keep the specified metadata in the SWF
*
* Equivalent to -compiler.keep-as3-metadata
*
* Usage:
*
*
* <keepAs3Metadatas>
* <keepAs3Metadata>Bindable</keepAs3Metadata>
* <keepAs3Metadata>Events</keepAs3Metadata>
* </keepAs3Metadatas>
*
*
* @parameter
*/
private String[] keepAs3Metadatas;
/**
* Keep the specified metadata in the SWF
*
* Equivalent to -compiler.keep-generated-actionscript
*
*
* @parameter expression="${flex.keepGeneratedActionscript}"
*/
private Boolean keepGeneratedActionscript;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.keep-generated-signatures
*
*
* @parameter expression="${flex.keepGeneratedSignatures}"
*/
private Boolean keepGeneratedSignatures;
/**
* DOCME Undocumented by adobe
*
* Equivalent to -lazy-init
*
*
* @parameter expression="${flex.lazyInit}"
*/
private Boolean lazyInit;
/**
* @component
*/
private LicenseCalculator licenseCalculator;
/**
* When true flexmojos will automatically lookup for licenses folling this documentation
* http://livedocs.adobe.com/flex/3/html/help.html?content=05B_Security_03 .html#140756
*
* @parameter default-value="true" expression="${flex.licenseLocalLookup}"
*/
private boolean licenseLocalLookup;
/**
* Specifies a product and a serial number
*
* Equivalent to -licenses.license
*
* Usage:
*
*
* <licenses>
* <flexbuilder3>xxxx-xxxx-xxxx-xxxx</flexbuilder3>
* </licenses>
*
*
* @parameter
*/
private Map licenses;
/**
* When true the link report will be attached to maven reactor
*
* @parameter expression="${flex.linkReportAttach}"
*/
private boolean linkReportAttach;
/**
* Load a file containing configuration options.
*
* Equivalent to -load-config
*
* Overwrite loadConfigs when defined!
*
* @parameter expression="${flex.loadConfig}"
*/
private File loadConfig;
/**
* Load a file containing configuration options
*
* Equivalent to -load-config
*
* Usage:
*
*
* <loadConfigs>
* <loadConfig>???</loadConfig>
* <loadConfig>???</loadConfig>
* </loadConfigs>
*
*
* @parameter
*/
private File[] loadConfigs;
/**
* Sets a list of artifacts to omit from linking when building an application. This is equivalent to using the
* load-externs
option of the mxmlc or compc compilers.
* Usage:
*
*
* <loadExterns>
* <loadExtern>
* <groupId>com.acme</groupId>
* <artifactId>flexmodule</artifactId>
* <version>1.0.0</version>
* </loadExtern>
* <loadExtern>
* <groupId>org.tabajara</groupId>
* <artifactId>flexmodule</artifactId>
* <version>1.0.0</version>
* </loadExtern>
* </loadExterns>
*
*
* @deprecated use dependency with type "xml" and classifier "link-report"
* @parameter
*/
@Deprecated
protected MavenArtifact[] loadExterns;
/**
* Specifies the locale for internationalization
*
* Equivalent to -compiler.locale
*
* Usage:
*
*
* <localesCompiled>
* <locale>en_US</locale>
* </localesCompiled>
*
*
* @parameter
*/
private String[] localesCompiled;
/**
* Relative path where the locales should be created
*
* @parameter expression="${flex.localesOutputPath}"
*/
private String localesOutputPath;
/**
* Specifies the locales for external internationalization bundles
*
* No equivalent parameter
*
* Usage:
*
*
* <localesRuntime>
* <locale>en_US</locale>
* </localesRuntime>
*
*
* @parameter
*/
private String[] localesRuntime;
/**
* Define the base path to locate resouce bundle files Accept some special tokens:
*
*
* {locale} - replace by locale name
*
*
* @parameter default-value="${basedir}/src/main/locales/{locale}"
*/
protected File localesSourcePath;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.memory-usage-factor
*
*
* @parameter expression="${flex.memoryUsageFactor}"
*/
private Integer memoryUsageFactor;
/**
* Information to store in the SWF metadata
*
* Equivalent to: -metadata.*
*
* Usage:
*
*
* <metadata>
* <contributors>
* <contributor>???</contributor>
* </contributors>
* <creators>
* <creator>???</creator>
* </creators>
* <date>???</date>
* <description>???</description>
* <languages>
* <language>???</language>
* </languages>
* <localizedDescriptions>
* <lang>text</land>
* </localizedDescriptions>
* <localizedTitles>
* <lang>title</land>
* </localizedTitles>
* <publishers>
* <publisher>???</publisher>
* </publishers>
* <title>???</title>
* </metadata>
*
*
* @parameter
*/
private MavenMetadataConfiguration metadata;
/**
* Minimum supported SDK version for this library. This string will always be of the form N.N.N. For example, if
* -minimum-supported-version=2, this string is "2.0.0", not "2".
*
* Equivalent to -compiler.mxml.minimum-supported-version
*
*
* @parameter expression="${flex.minimumSupportedVersion}"
*/
private String minimumSupportedVersion;
/**
* Specifies the target runtime is a mobile device
*
* Equivalent to -compiler.mobile
*
*
* @parameter expression="${flex.mobile}"
*/
private Boolean mobile;
/**
* Specify a URI to associate with a manifest of components for use as MXML elements
*
* Equivalent to -compiler.namespaces.namespace
*
* Usage:
*
*
* <namespaces>
* <namespace>
* <uri>http://www.adobe.com/2006/mxml</uri>
* <manifest>${basedir}/manifest.xml</manifest>
* </namespace>
* </namespaces>
*
*
* @parameter
*/
private MavenNamespace[] namespaces;
/**
* Toggle whether trace statements are omitted
*
* Equivalent to -compiler.omit-trace-statements
*
*
* @parameter expression="${flex.omitTraceStatements}"
*/
private Boolean omitTraceStatements;
/**
* Enable post-link SWF optimization
*
* Equivalent to -compiler.optimize
*
*
* @parameter expression="${flex.optimize}"
*/
private Boolean optimize;
/**
* policyFileUrls array of policy file URLs. Each entry in the rslUrls array must have a corresponding entry in this
* array. A policy file may be needed in order to allow the player to read an RSL from another domain. If a policy
* file is not required, then set it to an empty string. Accept some special tokens:
*
*
* {contextRoot} - replace by defined context root
* {groupId} - replace by library groupId
* {artifactId} - replace by library artifactId
* {version} - replace by library version
* {extension} - replace by library extension swf or swz
*
*
*
* Usage:
*
*
* <policyFileUrls>
* <url>/{contextRoot}/rsl/policy-{artifactId}-{version}.xml</url>
* </policyFileUrls>
*
*
* @parameter
*/
private String[] policyFileUrls;
/**
* Specifies the default value for the Application's preloader attribute. If not specified, the default preloader
* value will be mx.preloaders.SparkDownloadProgressBar with -compatibility-version >= 4.0 and it will be
* mx.preloader.DownloadProgressBar with -compatibility-version < 4.0.
*
* Equivalent to -compiler.preloader
*
*
* @parameter expression="${flex.preloader}"
*/
private String preloader;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.mxml.qualified-type-selectors
*
*
* @parameter expression="${flex.qualifiedTypeSelectors}"
*/
private Boolean qualifiedTypeSelectors;
/**
* XML text to store in the SWF metadata (overrides metadata.* configuration)
*
* Equivalent to -raw-metadata
*
*
* @parameter expression="${flex.rawMetadata}"
*/
private String rawMetadata;
/**
* Remove RSLs that are not being used by the application.
*
* Equivalent to -remove-unused-rsls
*
*
* @parameter expression="${flex.removeUnusedRsls}"
*/
private Boolean removeUnusedRsls;
/**
* Use this option to generate a warning instead of an error when a missing required skin part is detected.
*
* Equivalent to -compiler.report-missing-required-skin-parts-as-warnings
*
*
* @parameter expression="${flex.reportMissingRequiredSkinPartsAsWarnings}"
*/
private Boolean reportMissingRequiredSkinPartsAsWarnings;
/**
* Prints a list of resource bundles to a file for input to the compc compiler to create a resource bundle SWC file.
*
* Equivalent to -resource-bundle-list
*
*
* @parameter expression="${flex.resourceBundleList}"
*/
private File resourceBundleList;
/**
* Pattern to be used for locales resurce bundles names generation. Accepts special tokens:
*
*
* {locale} - replace by locale name
* {artifactId} - replace by artifactId
* {groupId} - replace by groupId
* {version} - replace by version
* {classifier} - replace by classifier
*
*
* @parameter
*/
protected String resourceBundleNames;
/**
* This undocumented option is for compiler performance testing. It allows the Flex 3 compiler to compile the Flex 2
* framework and Flex 2 apps. This is not an officially-supported combination
*
* Equivalent to -compiler.resource-hack
*
*
* @parameter expression="${flex.resourceHack}"
*/
private Boolean resourceHack;
/**
* rslUrls array of URLs. The first RSL URL in the list is the primary RSL. The remaining RSL URLs will only be
* loaded if the primary RSL fails to load. Accept some special tokens:
*
*
* {contextRoot} - replace by defined context root
* {groupId} - replace by library groupId
* {artifactId} - replace by library artifactId
* {version} - replace by library version
* {extension} - replace by library extension swf or swz
* {classifier} - replace by library classifier swf or swz
* {hard-version} - replace by library timestamped version (for -SNAPSHOT artifacts only and if timestamped is available)
*
*
* default-value="/{contextRoot}/rsl/{artifactId}-{version}.{extension}"
* Usage:
*
*
* <rslUrls>
* <url>/{contextRoot}/rsl/{artifactId}-{classifier}-{version}.{extension}</url>
* </rslUrls>
*
*
* @parameter
*/
private String[] rslUrls;
/**
* Path to Flex Data Services configuration file
*
* Equivalent to -compiler.services
*
*
* @parameter expression="${flex.services}"
*/
private File services;
/**
* Toggle the display of warnings
*
* Equivalent to -warnings
*
*
* @parameter expression="${flex.showWarnings}"
*/
private Boolean showWarnings;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.signature-directory
*
*
* @parameter expression="${flex.signatureDirectory}"
*/
private File signatureDirectory;
/**
* When true the size report will be attached to maven reactor
*
* @parameter expression="${flex.sizeReportAttach}"
*/
private boolean sizeReportAttach;
/**
* Statically link the libraries specified by the -runtime-shared-libraries-path option.
*
* Equivalent to -static-link-runtime-shared-libraries
*
*
* @parameter expression="${flex.staticLinkRuntimeSharedLibraries}"
*/
private Boolean staticLinkRuntimeSharedLibraries;
/**
* Runs the AS3 compiler in strict error checking mode
*
* Equivalent to -compiler.strict
*
*
* @parameter expression="${flex.strict}"
*/
private Boolean strict;
/**
* If true optimization using signature checksums are enabled
*
* Equivalent to -swc-checksum
*
*
* @parameter expression="${flex.swcChecksum}"
*/
private Boolean swcChecksum;
/**
* Specifies the version of the compiled SWF file
*
* Equivalent to -swf-version
*
*
* @parameter expression="${flex.swfVersion}"
*/
private Integer swfVersion;
/**
* List of CSS or SWC files to apply as a theme
*
* Equivalent to -compiler.theme
*
* Usage:
*
*
* <themes>
* <theme>css/main.css</theme>
* </themes>
*
*
* If you are using SWC theme should be better keep it's version controlled, so is advised to use a dependency with
* theme scope.
* Like this:
*
*
* <dependency>
* <groupId>com.acme</groupId>
* <artifactId>acme-theme</artifactId>
* <type>swc</type>
* <scope>theme</scope>
* <version>1.0</version>
* </dependency>
*
*
* There are three ways a theme can be included when you compile
*
* 1 - you explicitly list a in the config of the pom file
* 2 - You include a dependency with scope="theme" and with type="css" or type="swc"
* 3 - if you don't do either of the above steps, flexmojos will attempt to automatically include a theme for you
* based on your dependencies. (if you depend upon mx.swc halo will be included, if you depend upon spark.swc -
* spark.css theme will be included)
*
* @parameter
*/
private String[] themes;
/**
* Configures the LocalizationManager's locale, which is used when reporting compile time errors, warnings, and
* info. For example, "en" or "ja_JP".
*
* Equivalent to -tools-locale
*
*
* @parameter expression="${flex.toolsLocale}" default-value="en_US"
*/
protected String toolsLocale;
/**
* DOCME undocumented by adobe
*
* Equivalent to -compiler.translation-format
*
*
* @parameter expression="${flex.translationFormat}"
*/
private String translationFormat;
/**
* Use hardware acceleration to blit graphics to the screen, where such acceleration is available
*
* Equivalent to -use-direct-blit
*
*
* @parameter expression="${flex.useDirectBlit}"
*/
private Boolean useDirectBlit;
/**
* Use GPU compositing features when drawing graphics, where such acceleration is available
*
* Equivalent to -compiler.use-gpu
*
*
* @parameter expression="${flex.useGpu}"
*/
private Boolean useGpu;
/**
* Toggle whether the SWF is flagged for access to network resources
*
* Equivalent to -use-network
*
*
* @parameter expression="${flex.useNetwork}"
*/
private Boolean useNetwork;
/**
* Determines whether resources bundles are included in the application
*
* Equivalent to -compiler.use-resource-bundle-metadata
*
*
* @parameter expression="${flex.useResourceBundleMetadata}"
*/
private Boolean useResourceBundleMetadata;
/**
* Save callstack information to the SWF for debugging
*
* Equivalent to -compiler.verbose-stacktraces
*
*
* @parameter expression="${flex.verboseStacktraces}"
*/
private Boolean verboseStacktraces;
/**
* Verifies the libraries loaded at runtime are the correct ones
*
* Equivalent to -verify-digests
*
*
* @parameter expression="${flex.verifyDigests}"
*/
private Boolean verifyDigests;
/**
* DOCME Guess what, undocumented by adobe. Looks like it was overwritten by source paths
*
* Equivalent to -root
*
*
* @parameter expression="${flex.advancedTelemetry}"
*/
private Boolean advancedTelemetry;
/**
* Name of the Flex Tool Group that should be used for the build.
*
* @parameter expression="${flex.compilerName}"
*/
protected String compilerName;
protected Artifact adaptResourceBundle( final Artifact baseRbSwc, String requestedLocale )
{
getLog().debug( "Adapting resource bundle " + baseRbSwc.getArtifactId() + ":" + baseRbSwc.getClassifier()
+ " to " + requestedLocale );
Artifact rbSwc;
try
{
rbSwc =
resolve( baseRbSwc.getGroupId(), baseRbSwc.getArtifactId(), baseRbSwc.getVersion(),
baseRbSwc.getClassifier() + "2" + requestedLocale, baseRbSwc.getType() );
}
catch ( RuntimeMavenResolutionException e )
{
rbSwc = e.getArtifact();
}
if ( rbSwc.isResolved() )
{
return rbSwc;
}
File dest;
try
{
UnArchiver unzip = archiverManager.getUnArchiver( "zip" );
unzip.setSourceFile( baseRbSwc.getFile() );
dest = FileUtils.createTempFile( baseRbSwc.getArtifactId(), requestedLocale, getOutputDirectory() );
unzip.extract( "locale/" + baseRbSwc.getClassifier(), dest );
}
catch ( Exception e )
{
throw new MavenRuntimeException( "Unable to extract base locale", e );
}
File resourceBundleBaseDir = new File( dest, "locale/" + baseRbSwc.getClassifier() );
List bundles = new ArrayList();
for ( String bundle : resourceBundleBaseDir.list() )
{
bundles.add( bundle.replace( ".properties", "" ) );
}
ICompcConfiguration cfg = mock( ICompcConfiguration.class, RETURNS_NULL );
when( cfg.getLoadConfig() ).thenReturn( getLoadConfig() );
when( cfg.getIncludeResourceBundles() ).thenReturn( bundles );
String output = PathUtil.path( baseRbSwc.getFile() ).replace( baseRbSwc.getClassifier(), rbSwc.getClassifier() );
when( cfg.getOutput() ).thenReturn( output );
ICompilerConfiguration compilerCfg = mock( ICompilerConfiguration.class, RETURNS_NULL );
when( compilerCfg.getTheme() ).thenReturn( Collections.EMPTY_LIST );
when( compilerCfg.getFontsConfiguration() ).thenReturn( getFontsConfiguration() );
when( compilerCfg.getLocale() ).thenReturn( new String[] { requestedLocale } );
when( compilerCfg.getSourcePath() ).thenReturn( new File[] { resourceBundleBaseDir } );
when( compilerCfg.getExternalLibraryPath() ).thenReturn( this.getExternalLibraryPath() );
when( compilerCfg.getLibraryPath() ).thenReturn( this.getLibraryPath( false ) );
when( cfg.getCompilerConfiguration() ).thenReturn( compilerCfg );
try
{
checkResult( compiler.compileSwc( cfg, true, compilerName ) );
}
catch ( Exception e )
{
throw new MavenRuntimeException( "Unable to compile adapted resource bundle", e );
}
rbSwc.setFile( new File( output ) );
rbSwc.setResolved( true );
return rbSwc;
}
protected Map calculateRuntimeLibraryPath( Artifact artifact, String[] rslUrls,
String[] policyFileUrls )
{
getLog().debug( "runtime libraries: id: " + artifact.getArtifactId() );
String scope = artifact.getScope();
final String extension;
if ( CACHING.equals( scope ) )
{
extension = SWZ;
}
else
{
extension = SWF;
}
Map paths = new LinkedHashMap();
for ( int i = 0; i < rslUrls.length; i++ )
{
String rsl = rslUrls[i];
String policy;
if ( i < policyFileUrls.length )
{
policy = policyFileUrls[i];
}
else
{
policy = null;
}
rsl = MavenUtils.interpolateRslUrl( rsl, artifact, extension, contextRoot );
policy = MavenUtils.interpolateRslUrl( policy, artifact, extension, contextRoot );
getLog().debug( "RSL url: " + rsl + " - " + policy );
paths.put( rsl, policy );
}
return paths;
}
@SuppressWarnings( "unchecked" )
@Override
public C clone()
{
try
{
C clone = (C) super.clone();
clone.cache = new LinkedHashMap();
return clone;
}
catch ( CloneNotSupportedException e )
{
throw new IllegalStateException( "The class '" + getClass() + "' is supposed to be clonable", e );
}
}
@SuppressWarnings( "unchecked" )
protected void configureResourceBundle( String locale, AbstractFlexCompilerMojo, ?> cfg )
{
cfg.localesCompiled = new String[] { locale };
cfg.localesRuntime = null;
if ( locale.contains( "," ) )
{
cfg.classifier = locale.split( "," )[0];
}
else
{
cfg.classifier = locale;
}
if ( resourceBundleNames != null )
{
cfg.finalName =
MavenUtils.getRuntimeLocaleOutputName( resourceBundleNames, project.getArtifact(), cfg.classifier );
}
cfg.includeResourceBundles = getResourceBundleListContent();
cfg.getCache().put(EXTERNAL_LIBRARY_PATH, MavenUtils.getFiles(getDependencies(type(SWC))));
cfg.getCache().put(LIBRARY_PATH, MavenUtils.getFiles(cfg.getCompiledResouceBundles()));
if ( localesOutputPath != null )
{
cfg.getCache().put( TARGET_DIRECTORY, new File( getTargetDirectory(), localesOutputPath ) );
}
}
private void configureThemeHaloSwc( List themes )
{
File haloSwc = resolveThemeFile( "halo" );
if ( haloSwc == null )
{
return;
}
getLog().warn( "Adding halo.swc theme because mx.swc was included as a dependency" );
themes.add( haloSwc );
}
private void configureThemeSparkCss( List themes )
{
File sparkTheme = resolveThemeFile( "spark" );
if ( sparkTheme == null )
{
return;
}
getLog().warn( "Adding spark theme because spark.swc was included as a dependency" );
themes.add( sparkTheme );
}
public abstract Result doCompile( CFG cfg, boolean synchronize )
throws Exception;
private Artifact doLocalizationChain( String[] locales, String requestedLocale, Artifact beacon,
Artifact requestRbSwc )
{
getLog().info( "Resolving resource bundle for '" + beacon + "' using localization chain." );
for ( String locale : locales )
{
Artifact rbSwc;
try
{
rbSwc =
resolve( beacon.getGroupId(), beacon.getArtifactId(), beacon.getVersion(), locale, beacon.getType() );
}
catch ( RuntimeMavenResolutionException e )
{
rbSwc = e.getArtifact();
}
if ( rbSwc.isResolved() )
{
if ( !requestedLocale.equals( locale ) )
{
getLog().info( "Resolved resource bundle for '" + beacon + "' using localization chain. The '"
+ locale + "' will be used to build the missing '" + requestedLocale + "'" );
return adaptResourceBundle( rbSwc, requestedLocale );
}
return rbSwc;
}
}
throw new MavenRuntimeException( "Unable to resolve resource bundle '" + beacon + "' for '" + requestedLocale
+ "'" );
}
protected Result executeCompiler( CFG cfg, boolean synchronize )
throws MojoExecutionException, MojoFailureException
{
Result result;
try
{
result = doCompile( cfg, synchronize );
}
catch ( Exception e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
if ( synchronize )
{
checkResult( result );
}
return result;
}
public Boolean getAccessible()
{
return accessible;
}
public String getActionscriptFileEncoding()
{
return actionscriptFileEncoding;
}
public Boolean getAdjustOpdebugline()
{
return adjustOpdebugline;
}
public Boolean getAllowDuplicateDefaultStyleDeclarations()
{
return allowDuplicateDefaultStyleDeclarations;
}
public Boolean getAllowSourcePathOverlap()
{
return allowSourcePathOverlap;
}
public IApplicationDomain[] getApplicationDomain()
{
return this.applicationDomains;
}
public Boolean getArchiveClassesAndAssets()
{
return archiveClassesAndAssets;
}
public Boolean getAs3()
{
return as3;
}
public Boolean getBenchmark()
{
return benchmark;
}
public Integer getBenchmarkCompilerDetails()
{
if ( benchmarkCompilerDetails == null )
{
return null;
}
if ( benchmarkCompilerDetails != 0 && benchmarkCompilerDetails != 1 && benchmarkCompilerDetails != 5 )
{
throw new IllegalArgumentException( "Invalid benchmark compiler details level: '"
+ benchmarkCompilerDetails + "', it does accept 0 = none, 1 = light, 5 = verbose" );
}
return benchmarkCompilerDetails;
}
public Long getBenchmarkTimeFilter()
{
return benchmarkTimeFilter;
}
public String getClassifier()
{
return classifier;
}
public String getCompatibilityVersion()
{
if ( compatibilityVersion == null )
{
return null;
}
String[] versionStringParts = compatibilityVersion.split( "\\." );
if ( versionStringParts.length != 3 )
{
throw new MavenRuntimeException( "compatibilityVersion (" + compatibilityVersion
+ ") isn't in the required .. pattern." );
}
else
{
try
{
for ( int i = 0; i < 3; i++ )
{
Integer.parseInt( versionStringParts[i] );
}
}
catch ( NumberFormatException e )
{
throw new MavenRuntimeException( "compatibilityVersion contained a non-numeric segment", e );
}
}
return compatibilityVersion;
}
@SuppressWarnings( "unchecked" )
protected Collection getCompiledResouceBundles()
{
if ( this.getLocale() == null )
{
return null;
}
Collection rbsSwc = new LinkedHashSet();
Set beacons = getDependencies( type( RB_SWC ) );
String[] localeChains = this.localesCompiled;
if ( localeChains == null )
{
localeChains = getLocale();
}
// TODO for for for for if for for, too many nested blocks, improve this
for ( Artifact beacon : beacons )
{
for ( String localeChain : localeChains )
{
String[] locales;
if ( localeChain.contains( "," ) )
{
locales = localeChain.split( "," );
}
else
{
locales = new String[] { localeChain };
}
String requestedLocale = locales[0];
Artifact requestedRbSwc;
try
{
requestedRbSwc =
resolve( beacon.getGroupId(), beacon.getArtifactId(), beacon.getVersion(), requestedLocale,
beacon.getType() );
}
catch ( RuntimeMavenResolutionException e )
{
requestedRbSwc = e.getArtifact();
}
Artifact resultRbSwc;
if ( requestedRbSwc.isResolved() )
{
resultRbSwc = requestedRbSwc;
}
else if ( locales.length > 1 )
{
resultRbSwc = doLocalizationChain( locales, requestedLocale, beacon, requestedRbSwc );
}
else
{
throw new MavenRuntimeException( "Missing resource bundle '" + requestedRbSwc + "'" );
}
rbsSwc.add( resultRbSwc );
}
}
return rbsSwc;
}
public ICompilerConfiguration getCompilerConfiguration()
{
return this;
}
protected File getCompilerOutput()
{
File output;
// The FlexJS compiler creates zip-files.
if("FlexJS".equals(compilerName)) {
output = new File( getTargetDirectory(), getFinalName() );
}
else {
output = new File( getTargetDirectory(), getFinalName() + "." + getProjectType() );
}
output.getParentFile().mkdirs();
return output;
}
public Map getCompilerWarnings()
{
// converts the map into a one
Map compilerWarnings = new LinkedHashMap();
Set> warns = this.compilerWarnings.entrySet();
for ( Entry entry : warns )
{
compilerWarnings.put( entry.getKey(), Boolean.valueOf( entry.getValue() ) );
}
return compilerWarnings;
}
public Boolean getCompress()
{
return compress;
}
public Boolean getConservative()
{
return conservative;
}
public String getContextRoot()
{
return contextRoot;
}
public String[] getContributor()
{
if ( this.metadata != null && this.metadata.getContributor() != null )
{
return this.metadata.getContributor();
}
List contributors = project.getContributors();
if ( contributors == null || contributors.isEmpty() )
{
return null;
}
String[] contributorsName = new String[contributors.size()];
for ( int i = 0; i < contributorsName.length; i++ )
{
contributorsName[i] = contributors.get( i ).getName();
}
return contributorsName;
}
public String[] getCreator()
{
if ( this.metadata != null && this.metadata.getCreator() != null )
{
return this.metadata.getCreator();
}
List developers = project.getDevelopers();
if ( developers == null || developers.isEmpty() )
{
return null;
}
String[] creatorsName = new String[developers.size()];
for ( int i = 0; i < creatorsName.length; i++ )
{
creatorsName[i] = developers.get( i ).getName();
}
return creatorsName;
}
public String getDate()
{
if ( this.metadata != null && this.metadata.getDate() != null )
{
return this.metadata.getDate();
}
// If incremental compilation is enabled then we don't use current time
return ((incremental != null) && incremental) ? "0:00" : DATE_FORMAT.format( new Date() );
}
public Boolean getDebug()
{
return debug;
}
public String getDebugPassword()
{
return debugPassword;
}
public Integer getDefaultBackgroundColor()
{
return defaultBackgroundColor;
}
public Integer getDefaultFrameRate()
{
return defaultFrameRate;
}
public IDefaultScriptLimits getDefaultScriptLimits()
{
return defaultScriptLimits;
}
public List getDefaultsCssFiles()
{
return PathUtil.pathsList( defaultsCssFiles );
}
public String getDefaultsCssUrl()
{
return defaultsCssUrl;
}
public IDefaultSize getDefaultSize()
{
return defaultSize;
}
public IDefine[] getDefine()
{
if ( defines == null )
{
return null;
}
List keys = new ArrayList();
Set> entries = this.defines.entrySet();
for ( final Entry