package org.codehaus.mojo.gwt.shell;
/*
* 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.
*/
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.mojo.gwt.AbstractGwtModuleMojo;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* Support running GWT SDK Tools as forked JVM with classpath set according to project source/resource directories and
* dependencies.
*
* @author ccollins
* @author cooper
* @author willpugh
* @version $Id$
*/
public abstract class AbstractGwtShellMojo
extends AbstractGwtModuleMojo
{
/**
* Location on filesystem where GWT will write generated content for review (-gen option to GWT Compiler).
* <p>
* Can be set from command line using '-Dgwt.gen=...'
*/
@Parameter(defaultValue = "${project.build.directory}/.generated", property = "gwt.gen")
private File gen;
/**
* Whether to add -gen parameter to the compiler command line
* <p>
* Can be set from command line using '-Dgwt.genParam=false'. Defaults to 'true' for backwards compatibility.
*
* @since 2.5.0-rc1
*/
@Parameter(defaultValue = "true", property = "gwt.genParam")
private boolean genParam;
/**
* GWT logging level (-logLevel ERROR, WARN, INFO, TRACE, DEBUG, SPAM, or ALL).
* <p>
* Can be set from command line using '-Dgwt.logLevel=...'
*/
@Parameter(defaultValue = "INFO", property = "gwt.logLevel")
private String logLevel;
/**
* GWT JavaScript compiler output style (-style OBF[USCATED], PRETTY, or DETAILED).
* <p>
* Can be set from command line using '-Dgwt.style=...'
*/
@Parameter(property = "gwt.style")
protected String style;
/**
* The directory into which deployable but not servable output files will be written (defaults to 'WEB-INF/deploy' under the webappDirectory directory/jar, and may be the same as the extra directory/jar)
*
* @since 2.3.0-1
*/
@Parameter
private File deploy;
/**
* Extra JVM arguments that are passed to the GWT-Maven generated scripts (for compiler, shell, etc - typically use
* -Xmx512m here, or -XstartOnFirstThread, etc).
* <p>
* Can be set from command line using '-Dgwt.extraJvmArgs=...', defaults to setting max Heap size to be large enough
* for most GWT use cases.
* </p>
*/
@Parameter(property = "gwt.extraJvmArgs", defaultValue="-Xmx512m")
private String extraJvmArgs;
/**
* Option to specify the jvm (or path to the java executable) to use with the forking scripts. For the default, the
* jvm will be the same as the one used to run Maven.
*
* @since 1.1
*/
@Parameter(property = "gwt.jvm")
private String jvm;
/**
* Forked process execution timeOut. Usefull to avoid maven to hang in continuous integration server.
*/
@Parameter
private int timeOut;
/**
*
* Artifacts to be included as source-jars in GWTCompiler Classpath. Removes the restriction that source code must
* be bundled inside of the final JAR when dealing with external utility libraries not designed exclusivelly for
* GWT. The plugin will download the source.jar if necessary.
*
* This option is a workaround to avoid packaging sources inside the same JAR when splitting and application into
* modules. A smaller JAR can then be used on server classpath and distributed without sources (that may not be
* desirable).
*
* @deprecated add a {@code <classifier>sources</classifier>} dependency instead
*/
@Deprecated
@Parameter
private String[] compileSourcesArtifacts;
/**
* Whether to use the persistent unit cache or not.
* <p>
* Can be set from command line using '-Dgwt.persistentunitcache=...'
*
* @since 2.5.0-rc1
*/
@Parameter(property = "gwt.persistentunitcache")
private Boolean persistentunitcache;
/**
* The directory where the persistent unit cache will be created if enabled.
* <p>
* Can be set from command line using '-Dgwt.persistentunitcachedir=...'
*
* @since 2.5.0-rc1
*/
@Parameter(property = "gwt.persistentunitcachedir")
private File persistentunitcachedir;
// methods
/**
* {@inheritDoc}
*
* @see org.apache.maven.plugin.Mojo#execute()
*/
public final void execute()
throws MojoExecutionException, MojoFailureException
{
doExecute();
}
public abstract void doExecute()
throws MojoExecutionException, MojoFailureException;
protected String getExtraJvmArgs()
{
return extraJvmArgs;
}
protected String getLogLevel()
{
return this.logLevel;
}
protected String getStyle()
{
return this.style;
}
protected String getJvm()
{
return jvm;
}
/**
* hook to post-process the dependency-based classpath
*/
protected void postProcessClassPath( Collection<File> classpath )
{
// Nothing to do in most case
}
private List<String> getJvmArgs()
{
List<String> extra = new ArrayList<String>();
String userExtraJvmArgs = getExtraJvmArgs();
if ( userExtraJvmArgs != null )
{
try
{
// cleanup new lines bc removeDuplicateWhitespace leaves the first isWhitespace character found
userExtraJvmArgs = userExtraJvmArgs.replace('\n', ' ').replace('\r', ' ');
return new ArrayList<String>(Arrays.asList( CommandLineUtils.translateCommandline( StringUtils.removeDuplicateWhitespace( userExtraJvmArgs ) ) ) );
}
catch ( Exception e )
{
throw new RuntimeException( e );
}
}
return extra;
}
/**
* @param timeOut the timeOut to set
*/
public void setTimeOut( int timeOut )
{
this.timeOut = timeOut;
}
protected JavaCommand createJavaCommand() {
return new JavaCommand()
.setLog( getLog() )
.setJvm( getJvm() )
.setJvmArgs( getJvmArgs() )
.setTimeOut( timeOut )
.addClassPathProcessors( new ClassPathProcessor()
{
@Override
public void postProcessClassPath( List<File> files )
{
AbstractGwtShellMojo.this.postProcessClassPath( files );
}
} );
}
/**
* Add sources.jar artifacts for project dependencies listed as compileSourcesArtifacts. This is a GWT hack to avoid
* packaging java source files into JAR when sharing code between server and client. Typically, some domain model
* classes or business rules may be packaged as a separate Maven module. With GWT packaging this requires to
* distribute such classes with code, that may not be desirable.
* <p>
* The hack can also be used to include utility code from external librariries that may not have been designed for
* GWT.
*/
protected void addCompileSourceArtifacts(JavaCommand cmd)
throws MojoExecutionException
{
if ( compileSourcesArtifacts == null )
{
return;
}
for ( String include : compileSourcesArtifacts )
{
List<String> parts = new ArrayList<String>();
parts.addAll( Arrays.asList(include.split(":")) );
if ( parts.size() == 2 )
{
// type is optional as it will mostly be "jar"
parts.add( "jar" );
}
String dependencyId = StringUtils.join( parts.iterator(), ":" );
boolean found = false;
for ( Artifact artifact : getProjectArtifacts() )
{
getLog().debug( "compare " + dependencyId + " with " + artifact.getDependencyConflictId() );
if ( artifact.getDependencyConflictId().equals( dependencyId ) )
{
getLog().debug( "Add " + dependencyId + " sources.jar artifact to compile classpath" );
Artifact sources =
resolve( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(),
"jar", "sources" );
cmd.addToClasspath( sources.getFile() );
found = true;
break;
}
}
if ( !found )
getLog().warn(
"Declared compileSourcesArtifact was not found in project dependencies " + dependencyId );
}
}
protected void addArgumentDeploy(JavaCommand cmd) {
if ( deploy != null )
{
cmd.arg( "-deploy" ).arg( String.valueOf( deploy ) );
}
}
protected void addArgumentGen( JavaCommand cmd )
{
if ( this.genParam )
{
if ( !this.gen.exists() )
{
this.gen.mkdirs();
}
cmd.arg( "-gen", this.gen.getAbsolutePath() );
}
}
protected void addPersistentUnitCache(JavaCommand cmd) {
if ( persistentunitcache != null )
{
cmd.systemProperty( "gwt.persistentunitcache", String.valueOf( persistentunitcache.booleanValue() ) );
}
if ( persistentunitcachedir != null )
{
cmd.systemProperty( "gwt.persistentunitcachedir", persistentunitcachedir.getAbsolutePath() );
}
}
}