
org.apache.royale.maven.BaseMojo Maven / Gradle / Ivy
The newest version!
/*
* 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 org.apache.royale.maven;
import org.apache.flex.tools.FlexTool;
import org.apache.flex.tools.FlexToolGroup;
import org.apache.flex.tools.FlexToolRegistry;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.MavenExecutionPlan;
import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
import org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator;
import org.apache.maven.lifecycle.internal.TaskSegment;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectDependenciesResolver;
import org.apache.royale.maven.utils.DependencyHelper;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.eclipse.aether.RepositorySystemSession;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
/**
*/
public abstract class BaseMojo
extends AbstractMojo
{
@Parameter(defaultValue = "${project}", readonly = true)
protected MavenProject project;
@Parameter(defaultValue="${project.build.directory}")
protected File outputDirectory;
@Parameter
private Namespace[] namespaces;
@Parameter
private String[] includeClasses;
@Parameter
private IncludeFile[] includeFiles;
@Parameter
private Define[] defines;
@Parameter
private String[] keepAs3Metadata;
/**
* When compiling framework libraries, it might be desirable to link the
* dependencies externally, by setting this option to 'true' all dependencies
* are added to the external-library-path, no matter what scope they have.
*/
@Parameter(defaultValue = "false")
private boolean forceSwcExternalLibraryPath;
@Parameter(defaultValue = "11.1")
private String targetPlayer;
@Parameter(defaultValue = "false")
private boolean includeSources;
@Parameter
protected boolean debug = false;
@Parameter
protected boolean failOnCompilerWarnings = false;
@Parameter
protected boolean allowSubclassOverrides = false;
@Parameter
private Boolean includeLookupOnly = null;
@Parameter(readonly = true, defaultValue = "${repositorySystemSession}")
private RepositorySystemSession repositorySystemSession;
@Parameter
private String additionalCompilerOptions = null;
@Parameter(defaultValue = "${session}", required = true, readonly = true)
private MavenSession session;
@Component
private LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator;
@Component
private LifecycleExecutionPlanCalculator lifecycleExecutionPlanCalculator;
@Component
private ProjectDependenciesResolver projectDependenciesResolver;
protected boolean skip() {
return false;
}
protected abstract String getConfigFileName() throws MojoExecutionException;
protected abstract File getOutput() throws MojoExecutionException;
protected String getLanguageManifestFileName()
{
return "mxml-language-manifest.xml";
}
protected String getLanguageNamespaceURI()
{
return "http://ns.adobe.com/mxml/2009";
}
protected VelocityContext getVelocityContext() throws MojoExecutionException {
VelocityContext context = new VelocityContext();
List allLibraries = DependencyHelper.getAllLibraries(
project, repositorySystemSession, projectDependenciesResolver);
List filteredLibraries = getFilteredLibraries(allLibraries);
List libraries = getLibraries(filteredLibraries);
List jsLibraries = getJSLibraries(filteredLibraries);
List swfLibraries = getSWFLibraries(filteredLibraries);
List externalLibraries = getExternalLibraries(filteredLibraries);
List jsExternalLibraries = getJSExternalLibraries(filteredLibraries);
List swfExternalLibraries = getSWFExternalLibraries(filteredLibraries);
List themeLibraries = getThemeLibraries(filteredLibraries);
List sourcePaths = getSourcePaths();
context.put("libraries", libraries);
context.put("externalLibraries", externalLibraries);
context.put("jsLibraries", jsLibraries);
context.put("jsExternalLibraries", jsExternalLibraries);
context.put("swfLibraries", swfLibraries);
context.put("swfExternalLibraries", swfExternalLibraries);
context.put("themeLibraries", themeLibraries);
context.put("sourcePaths", sourcePaths);
context.put("languageNamespace", getLanguageNamespace());
context.put("namespaces", getNamespaces());
context.put("jsNamespaces", getNamespacesJS());
context.put("namespaceUris", getNamespaceUris());
context.put("includeClasses", includeClasses);
context.put("includeFiles", includeFiles);
context.put("defines", getDefines());
context.put("keepAs3Metadata", keepAs3Metadata);
context.put("targetPlayer", targetPlayer);
context.put("includeSources", includeSources);
context.put("debug", debug);
context.put("allowSubclassOverrides", allowSubclassOverrides);
if(includeLookupOnly != null) {
context.put("includeLookupOnly", includeLookupOnly);
}
context.put("output", getOutput());
context.put("manifestComponents", getLanguageManifestComponents());
return context;
}
protected abstract String getToolGroupName();
protected abstract String getFlexTool();
protected List getNamespaces() {
List namespaces = new LinkedList();
if(this.namespaces != null) {
for (Namespace namespace : this.namespaces) {
namespaces.add(namespace);
}
}
return namespaces;
}
protected Namespace getLanguageNamespace() {
File manifestFile = new File(outputDirectory, getLanguageManifestFileName());
Namespace namespace = new Namespace();
namespace.setUri(getLanguageNamespaceURI());
namespace.setManifest(manifestFile.getAbsolutePath());
return namespace;
}
protected List getNamespacesJS() {
List namespaces = new LinkedList();
if(this.namespaces != null) {
for (Namespace namespace : this.namespaces) {
namespaces.add(namespace);
}
}
return namespaces;
}
protected Set getNamespaceUris() {
Set namespaceUris = new HashSet();
for(Namespace namespace : getNamespaces()) {
namespaceUris.add(namespace.getUri());
}
return namespaceUris;
}
protected List getLanguageManifestComponents()
{
List manifestComponents = new ArrayList();
manifestComponents.add(new ManifestComponent("Array", "Array", true));
manifestComponents.add(new ManifestComponent("Boolean", "Boolean", true));
manifestComponents.add(new ManifestComponent("Class", "Class", true));
manifestComponents.add(new ManifestComponent("Date", "Date", true));
manifestComponents.add(new ManifestComponent("DesignLayer", "mx.core.DesignLayer", false));
manifestComponents.add(new ManifestComponent("Function", "Function", true));
manifestComponents.add(new ManifestComponent("int", "int", true));
manifestComponents.add(new ManifestComponent("Number", "Number", true));
manifestComponents.add(new ManifestComponent("Object", "Object", true));
manifestComponents.add(new ManifestComponent("RegExp", "RegExp", true));
manifestComponents.add(new ManifestComponent("String", "String", true));
manifestComponents.add(new ManifestComponent("uint", "uint", true));
manifestComponents.add(new ManifestComponent("Vector", "__AS3__.vec.Vector", true));
manifestComponents.add(new ManifestComponent("XML", "XML", true));
manifestComponents.add(new ManifestComponent("XMLList", "XMLList", true));
return manifestComponents;
}
@SuppressWarnings("unchecked")
protected List getSourcePaths() {
List sourcePaths = new LinkedList();
for(String sourcePath : (List) project.getCompileSourceRoots()) {
if(new File(sourcePath).exists()) {
sourcePaths.add(sourcePath);
}
}
return sourcePaths;
}
protected String getSourcePath(String resourceOnPath) {
for(String path : getSourcePaths()) {
File tmpFile = new File(path, resourceOnPath);
if(tmpFile.exists()) {
return tmpFile.getPath();
}
}
return null;
}
/*@SuppressWarnings("unchecked")
protected List getIncludedFiles() {
List includedFiles = new LinkedList();
// Add all manually added files.
if(includeFiles != null) {
includedFiles.addAll(Arrays.asList(includeFiles));
}
// Add all files in the resources directory.
if(project.getResources() != null) {
for(Resource resource : (List) project.getResources()) {
File resourceDirectory = new File(resource.getDirectory());
if(resourceDirectory.exists()) {
Collection files = FileUtils.listFiles(resourceDirectory,
new RegexFileFilter("^(.*?)"), DirectoryFileFilter.DIRECTORY);
for(File file : files) {
IncludeFile includeFile = new IncludeFile();
String relativePath = file.getPath().substring(resourceDirectory.getPath().length());
includeFile.setName(relativePath);
includeFile.setPath(file.getPath());
includedFiles.add(includeFile);
}
}
}
}
return includedFiles;
}*/
protected List getCompilerArgs(File configFile) throws MojoExecutionException {
List args = new LinkedList();
args.add("-load-config=" + configFile.getPath());
if(additionalCompilerOptions != null) {
//remove whitespace after any '=' or '+='
additionalCompilerOptions = additionalCompilerOptions.replaceAll("=\\s+", "=");
//remove whitespace before or after any ',' (this assumes that ',' is never part of a value assignment itself and is only used to separate list values in config settings)
additionalCompilerOptions = additionalCompilerOptions.replaceAll("\\s*,\\s*", ",");
//any explicit line separators can be resolved to a single separator (';') multiple sequential separators will be ignored if there are explicit ';' separators included below
additionalCompilerOptions = additionalCompilerOptions.replaceAll("(\\r\\n?|\\n)+", ";");
if (additionalCompilerOptions.contains(";"))
{
String[] options = additionalCompilerOptions.split(";");
for (String option : options)
{
if (option.trim().length() > 0)
args.add(option.trim());
}
}
else {
if (additionalCompilerOptions.trim().length() > 0)
args.add(additionalCompilerOptions.trim());
}
}
return args;
}
public void execute()
throws MojoExecutionException
{
// Skip this step if not all preconditions are met.
if(skip()) {
return;
}
VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADERS, "classpath");
velocityEngine.setProperty("resource.loader.classpath.class", ClasspathResourceLoader.class.getName());
velocityEngine.setProperty(RuntimeConstants.SPACE_GOBBLING, "bc");
velocityEngine.setProperty(RuntimeConstants.CHECK_EMPTY_OBJECTS, false);
velocityEngine.setProperty("runtime.conversion.handler", "none");
velocityEngine.init();
VelocityContext context = getVelocityContext();
// Prepare the config file.
File configFile = new File(outputDirectory, getConfigFileName());
Template configTemplate = velocityEngine.getTemplate("config/" + getConfigFileName());
if(!configFile.getParentFile().exists()) {
if(!configFile.getParentFile().mkdirs()) {
throw new MojoExecutionException("Could not create output directory: " + configFile.getParent());
}
}
FileWriter configWriter = null;
try {
configWriter = new FileWriter(configFile);
configTemplate.merge(context, configWriter);
} catch (IOException e) {
throw new MojoExecutionException("Error creating config file at " + configFile.getPath());
} finally {
if(configWriter != null) {
try {
configWriter.close();
} catch (IOException e) {
throw new MojoExecutionException("Error creating config file at " + configFile.getPath());
}
}
}
// Prepare the MXML language manifest file.
File manifestFile = new File(outputDirectory, getLanguageManifestFileName());
Template manifestTemplate = velocityEngine.getTemplate("config/" + getLanguageManifestFileName());
if(!manifestFile.getParentFile().exists()) {
if(!manifestFile.getParentFile().mkdirs()) {
throw new MojoExecutionException("Could not create output directory: " + manifestFile.getParent());
}
}
FileWriter manifestWriter = null;
try {
manifestWriter = new FileWriter(manifestFile);
manifestTemplate.merge(context, manifestWriter);
} catch (IOException e) {
throw new MojoExecutionException("Error creating manifest file at " + manifestFile.getPath());
} finally {
if(manifestWriter != null) {
try {
manifestWriter.close();
} catch (IOException e) {
throw new MojoExecutionException("Error creating manifest file at " + manifestFile.getPath());
}
}
}
// Get the tool group.
FlexToolRegistry toolRegistry = new FlexToolRegistry();
FlexToolGroup toolGroup = toolRegistry.getToolGroup(getToolGroupName());
if(toolGroup == null) {
throw new MojoExecutionException("Could not find tool group: " + getToolGroupName());
}
// Get an instance of the compiler and run the build.
FlexTool tool = toolGroup.getFlexTool(getFlexTool());
String[] args = getCompilerArgs(configFile).toArray(new String[0]);
getLog().info("Executing " + getFlexTool() + " in tool group " + getToolGroupName() + " with args: " + Arrays.toString(args));
int exitCode = tool.execute(args);
handleExitCode(exitCode);
}
protected void handleExitCode(int exitCode) throws MojoExecutionException {
if(exitCode == 1000) {
// if the compiler is watching for file changes, make sure that the
// user didn't request any goals or lifecycle phases after compile
checkForInvalidGoalOrPhaseAfterCompile();
// if the compiler is watching for file changes, pause this thread
// to prevent Maven from exiting while the watch thread is running
try {
while(true) {
Thread.sleep(60000);
}
}
catch(InterruptedException e) {}
}
if(exitCode != 0) {
throw new MojoExecutionException("There were errors during the build. Got return code " + exitCode);
}
}
protected void checkForInvalidGoalOrPhaseAfterCompile() throws MojoExecutionException {
List segments = null;
try {
segments = lifecycleTaskSegmentCalculator.calculateTaskSegments(session);
} catch(Exception e) {
throw new MojoExecutionException("Failed to calculate session task segments for --watch=true");
}
for (TaskSegment segment : segments) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy