blob: 1f9a31480ef8a81856cdd0684d2a02952b958f4e [file] [log] [blame]
/*
* 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.tuscany.maven.plugin;
import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.core.AprLifecycleListener;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.startup.Tomcat;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.tuscany.sca.shell.Shell;
/**
* Maven Mojo to run the Tuscany Shell and install the project as an SCA contribution.
*
* Invoked with "mvn tuscany:run"
*
* @goal run
* @requiresDependencyResolution runtime
* @execute phase="test-compile"
* @description Runs Tuscany directly from a SCA conribution maven project
*/
public class TuscanyRunMojo extends AbstractMojo {
/**
* The maven project.
*
* @parameter expression="${project}"
* @required
* @readonly
*/
private MavenProject project;
/**
* The project artifactId.
*
* @parameter expression="${project.artifactId}"
* @required
*/
protected String artifactId;
/**
* The project packaging.
*
* @parameter expression=".${project.packaging}"
* @required
*/
protected String packaging;
/**
* The project build output directory
*
* @parameter expression="${project.build.outputDirectory}"
* @required
*/
protected File buildDirectory;
/**
* The project build output directory
*
* @parameter expression="${project.build.finalName}"
* @required
*/
protected File finalName;
/**
* @parameter expression="${domainURI}" default-value="uri:default"
*/
private String domainURI;
/**
* @parameter expression="${nodeXML}"
*/
private String nodeXML;
/**
* @parameter expression="${contributions}"
*/
private String[] contributions;
/**
* @parameter expression="${mainClass}"
*/
private String mainClass;
/**
* @parameter expression="${arguments}"
*/
private String[] arguments;
public void execute() throws MojoExecutionException, MojoFailureException {
if (mainClass != null) {
executeMainMethod();
} else if (".war".equals(packaging)) {
try {
executeTomcat();
} catch (Exception e) {
throw new MojoExecutionException("Exception running Tuscany/Tomcat", e);
}
} else {
executeShell();
}
}
private void executeTomcat() throws ServletException, LifecycleException, MalformedURLException {
getLog().info("Starting Tuscany/Tomcat...");
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.setBaseDir("target");
String appBase = "../src/main/webapp";
tomcat.getHost().setAppBase(".");
String contextPath = "/" + artifactId;
StandardServer server = (StandardServer)tomcat.getServer();
server.setParentClassLoader(getMainClassLoader());
AprLifecycleListener listener = new AprLifecycleListener();
server.addLifecycleListener(listener);
tomcat.addWebapp(contextPath, appBase);
tomcat.start();
tomcat.getServer().await();
}
private void executeShell() throws MojoExecutionException {
getLog().info("Starting Tuscany Shell...");
if (nodeXML != null && nodeXML.length() > 0) {
try {
Shell.main(new String[]{"-nodeXML:" + nodeXML});
} catch (Exception e) {
throw new MojoExecutionException("Exception in Shell", e);
}
} else {
List<String> contributionList = new ArrayList<String>();
addProjectContribution(contributionList);
addAdditionalContributions(contributionList);
contributionList.add(0, "-help");
contributionList.add(0, domainURI);
try {
Shell.main(contributionList.toArray(new String[contributionList.size()]));
} catch (Exception e) {
throw new MojoExecutionException("Exception in Shell", e);
}
}
getLog().info("Tuscany Shell stopped.");
}
private void addAdditionalContributions(List<String> contributionList) throws MojoExecutionException {
if (contributions != null) {
for (String s : contributions) {
if (new File(s).exists()) {
contributionList.add(s);
} else {
boolean found = false;
for (Object o : project.getDependencyArtifacts()) {
Artifact a = (Artifact) o;
if (a.getId().startsWith(s)) {
try {
contributionList.add(a.getFile().toURI().toURL().toString());
} catch (MalformedURLException e) {
throw new MojoExecutionException("", e);
}
found = true;
break;
}
}
if (!found) {
throw new IllegalArgumentException("Contribution not found as file or dependency: " + s);
}
}
}
}
}
protected void addProjectContribution(List<String> cs) throws MojoExecutionException {
try {
File contributionFile = new File(buildDirectory.getParent(), finalName.getName());
if (!contributionFile.exists()) {
contributionFile = new File(buildDirectory.getParent(), "classes");
}
if (!contributionFile.exists()) {
contributionFile = new File(buildDirectory.getParent(), finalName.getName() + packaging);
}
String contribution = contributionFile.toURI().toURL().toString();
getLog().info("Project contribution: " + contribution);
cs.add(contribution);
} catch (MalformedURLException e) {
throw new MojoExecutionException("", e);
}
}
public void executeMainMethod() throws MojoExecutionException, MojoFailureException {
getLog().info("Invoking " + mainClass + " class main method...");
if (arguments == null) {
arguments = new String[0];
}
try {
Method main = getMainClassLoader().loadClass(mainClass).getMethod("main", new Class[] {String[].class});
main.invoke(main, new Object[] {arguments});
} catch (NoSuchMethodException e) {
throw new MojoExecutionException("The specified mainClass doesn't contain a main method with appropriate signature", e);
} catch (Exception e) {
throw new MojoExecutionException("exception invoking main method", e);
}
}
private ClassLoader getMainClassLoader() throws MalformedURLException {
ClassLoader parent = Thread.currentThread().getContextClassLoader();
List<URL> classPathEntries = new ArrayList<URL>();
classPathEntries.add(new File(project.getBuild().getOutputDirectory()).toURI().toURL());
for (Object o : project.getRuntimeArtifacts()) {
Artifact a = (Artifact) o;
classPathEntries.add( a.getFile().toURI().toURL() );
}
return new URLClassLoader((URL[])classPathEntries.toArray(new URL[]{}), parent );
}
}