blob: 532be0a4062bb802d6f4dec0802f22bff4a0e2f0 [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.servicemix.maven.plugin.xfire;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Project;
import org.codehaus.xfire.gen.WsdlGenTask;
import org.codehaus.xfire.spring.XFireConfigLoader;
/**
* WsdlGen mojo.
* <p/>
* Implemented as a wrapper around the XFire WsdlGen Ant task.
*
* @author <a href="jerome@coffeebreaks.org">Jerome Lacoste</a>
* @version $Id$
* @goal wsdlgen
* @requiresProject
* @requiresDependencyResolution
*/
public class WsdlgenMojo extends AbstractMojo {
/**
* Project.
*
* @parameter expression="${project}"
* @required
* @readonly
*/
private MavenProject project;
/**
* xfire service.xml config files
* If not specified, the list will contain a single value 'src/main/resources/META-INF/xfire/services.xml'
*
* @parameter
*/
private List configs;
/**
* The directory will be added as Project's Resource.
* @parameter expression="${outputDirectory}" default-value="${project.build.directory}/generated-sources/xfire/wsdlgen"
* @required
*/
private File outputDirectory;
/**
* The basedir of the project.
*
* @parameter expression="${basedir}"
* @required
* @readonly
*/
private File basedir;
/*
private PrintStream systemErr;
private PrintStream systemOut;
private final PrintStream mySystemErr = new PrintStream(new WsdlgenMojo.MyErrorStream());
private final PrintStream mySystemOut = new PrintStream(new WsdlgenMojo.MyOutputStream());
public void execute()
throws MojoExecutionException
{
systemErr = System.err;
systemOut = System.out;
System.setErr(mySystemErr);
// System.setOut(mySystemOut); // causes java.lang.OutOfMemoryError: Java heap space on my box
try {
exec();
} finally {
System.setErr( systemErr );
// System.setOut( systemOut );
}
}
class MyErrorStream extends OutputStream {
private StringBuffer buffer = new StringBuffer();
public void write( final int b ) throws IOException {
final char c = (char) b;
// shouldn't we handle '\r' as well ??
if (c == '\n') {
getLog().error( buffer );
buffer = new StringBuffer();
} else {
buffer.append( c );
}
}
}
class MyOutputStream extends OutputStream {
private StringBuffer buffer = new StringBuffer();
public void write( final int b ) throws IOException {
final char c = (char) b;
// shouldn't we handle '\r' as well ??
if (c == '\n') {
getLog().info( buffer );
buffer = new StringBuffer();
} else {
buffer.append( c );
}
}
}
*/
public void execute() throws MojoExecutionException {
if (configs == null) {
configs = new ArrayList();
}
if (configs.size() == 0) {
configs
.add(new File(basedir,
"src/main/resources/META-INF/xfire/services.xml")
.getPath());
}
if (!outputDirectory.exists() && !outputDirectory.mkdirs()) {
getLog()
.warn(
"the output directory "
+ outputDirectory
+ " doesn't exist and couldn't be created. The goal with probably fail.");
}
final Project antProject = new Project();
antProject.addBuildListener(new WsdlgenMojo.DebugAntBuildListener());
// add current pom dependencies to WsdlGenTask class loader
ClassLoader parent = WsdlGenTask.class.getClassLoader();
URL[] urls;
try {
Collection l = project.getArtifacts();
List theurls = new ArrayList();
theurls.add(new File(project.getBuild().getOutputDirectory())
.toURL());
for (Iterator iterator = l.iterator(); iterator.hasNext();) {
Artifact dep = (Artifact) iterator.next();
theurls.add(dep.getFile().toURL());
}
urls = (URL[]) theurls.toArray(new URL[theurls.size()]);
getLog().debug("classloader classpath: " + theurls);
} catch (MalformedURLException e) {
throw new IllegalStateException(e);
}
URLClassLoader cl = new URLClassLoader(urls, parent);
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
// displayClasspath(cl, "using classpath");
// load("javax.servlet.ServletException", cl);
// load("org.codehaus.xfire.transport.http.XFireServletController", cl);
final WsdlGenTask task = new WsdlGenTask();
task.setProject(antProject);
task.setOutputDirectory(outputDirectory.getAbsolutePath());
for (Iterator iterator = configs.iterator(); iterator.hasNext();) {
String configUrl = (String) iterator.next();
// required for multi-modules projects
if (!new File(configUrl).exists()) {
getLog().warn("configUrl not found. Task will perhaps fail");
}
task.setConfigUrl(configUrl);
getLog().info(
"Executing XFire WsdlGen task for configUrl: " + configUrl);
try {
task.execute();
} catch (BuildException e) {
throw new MojoExecutionException("command execution failed", e);
}
getLog().debug("generated " + task.getGeneratedFile());
}
Thread.currentThread().setContextClassLoader(oldCl);
getLog().debug("Adding outputDirectory as Project's resource.");
Resource resource = new Resource();
resource.setDirectory(outputDirectory.getAbsolutePath());
project.addResource(resource);
}
/*
void displayClasspath(URLClassLoader cl, String message)
{
URL[] urls = cl.getURLs();
for (int i = 0; i < urls.length; i++) {
URL urL = urls[i];
getLog().info("URL " + i + ":" + urL);
}
}
*/
private void displayClasspath(ClassLoader classLoader, String message) {
getLog().info("------ " + message + ":" + classLoader);
if (classLoader == null) {
return;
}
if (classLoader instanceof URLClassLoader) {
URLClassLoader cl = (URLClassLoader) classLoader;
URL[] urls = cl.getURLs();
for (int i = 0; i < urls.length; i++) {
URL urL = urls[i];
getLog().info("URL " + i + ":" + urL);
}
} else if (classLoader instanceof AntClassLoader) {
AntClassLoader cl = (AntClassLoader) XFireConfigLoader.class
.getClassLoader();
String[] urls = cl.getClasspath().split(File.pathSeparator);
for (int i = 0; i < urls.length; i++) {
String url = urls[i];
getLog().info("URL " + i + ":" + url);
}
} else {
// not handled
}
displayClasspath(classLoader.getParent(), "parent->" + message);
}
void load(String className, ClassLoader cl) {
try {
Class c = Class.forName(className, true, cl);
getLog().debug(c.toString());
} catch (Exception e) {
displayClasspath(cl, "using classpath");
getLog().error(e);
}
}
private class DebugAntBuildListener implements BuildListener {
public void buildStarted(final BuildEvent buildEvent) {
getLog().debug(buildEvent.getMessage());
}
public void buildFinished(final BuildEvent buildEvent) {
getLog().debug(buildEvent.getMessage());
}
public void targetStarted(final BuildEvent buildEvent) {
getLog().debug(buildEvent.getMessage());
}
public void targetFinished(final BuildEvent buildEvent) {
getLog().debug(buildEvent.getMessage());
}
public void taskStarted(final BuildEvent buildEvent) {
getLog().debug(buildEvent.getMessage());
}
public void taskFinished(final BuildEvent buildEvent) {
getLog().debug(buildEvent.getMessage());
}
public void messageLogged(final BuildEvent buildEvent) {
getLog().debug(buildEvent.getMessage());
}
}
}