001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.xbean.maven; 018 019import java.beans.PropertyEditorManager; 020import java.io.File; 021import java.net.MalformedURLException; 022import java.net.URL; 023import java.net.URLClassLoader; 024import java.util.ArrayList; 025import java.util.Arrays; 026import java.util.Collections; 027import java.util.HashSet; 028import java.util.Iterator; 029import java.util.LinkedList; 030import java.util.List; 031import java.util.Set; 032import java.util.StringTokenizer; 033 034import org.apache.maven.artifact.Artifact; 035import org.apache.maven.model.Resource; 036import org.apache.maven.plugin.AbstractMojo; 037import org.apache.maven.plugin.MojoExecutionException; 038import org.apache.maven.plugin.MojoFailureException; 039import org.apache.maven.project.MavenProject; 040import org.apache.maven.project.MavenProjectHelper; 041import org.apache.tools.ant.BuildException; 042import org.apache.xbean.spring.generator.DocumentationGenerator; 043import org.apache.xbean.spring.generator.GeneratorPlugin; 044import org.apache.xbean.spring.generator.LogFacade; 045import org.apache.xbean.spring.generator.MappingLoader; 046import org.apache.xbean.spring.generator.NamespaceMapping; 047import org.apache.xbean.spring.generator.QdoxMappingLoader; 048import org.apache.xbean.spring.generator.WikiDocumentationGenerator; 049import org.apache.xbean.spring.generator.XmlMetadataGenerator; 050import org.apache.xbean.spring.generator.XsdGenerator; 051 052/** 053 * @author <a href="gnodet@apache.org">Guillaume Nodet</a> 054 * @version $Id: GenerateApplicationXmlMojo.java 314956 2005-10-12 16:27:15Z brett $ 055 * @goal mapping 056 * @description Creates xbean mapping file 057 * @phase generate-sources 058 * @requiresDependencyResolution compile 059 */ 060public class XBeanMojo extends AbstractMojo implements LogFacade { 061 062 /** 063 * @parameter expression="${project}" 064 * @required 065 */ 066 private MavenProject project; 067 068 /** 069 * Maven ProjectHelper 070 * 071 * @component 072 */ 073 protected MavenProjectHelper projectHelper; 074 075 /** 076 * @parameter 077 * @required 078 */ 079 private String namespace; 080 081 /** 082 * @parameter expression="${basedir}/src/main/java" 083 * @required 084 */ 085 private File srcDir; 086 087 /** 088 * @parameter 089 */ 090 private List<String> includes; 091 092 /** 093 * @parameter 094 */ 095 private List<String> classPathIncludes; 096 097 /** 098 * @parameter 099 */ 100 private String excludedClasses; 101 102 /** 103 * @parameter expression="${basedir}/target/xbean/" 104 * @required 105 */ 106 private File outputDir; 107 108 /** 109 * @parameter 110 */ 111 private File schema; 112 113 /** 114 * @parameter expression="org.apache.xbean.spring.context.impl" 115 */ 116 private String propertyEditorPaths; 117 118 /** 119 * @parameter schemaAsArtifact 120 */ 121 private boolean schemaAsArtifact = true; 122 123 /** 124 * @parameter 125 */ 126 private boolean generateSpringSchemasFile = true; 127 128 /** 129 * @parameter 130 */ 131 private boolean generateSpringHandlersFile = true; 132 133 /** 134 * @parameter 135 */ 136 private boolean strictXsdOrder = true; 137 138 /** 139 * A list of additional GeneratorPlugins that should get used executed 140 * when generating output. 141 * 142 * @parameter 143 */ 144 private List<GeneratorPlugin> generatorPlugins = Collections.emptyList(); 145 146 public void execute() throws MojoExecutionException, MojoFailureException { 147 getLog().debug( " ======= XBeanMojo settings =======" ); 148 getLog().debug( "namespace[" + namespace + "]" ); 149 getLog().debug( "srcDir[" + srcDir + "]" ); 150 getLog().debug( "schema[" + schema + "]" ); 151 getLog().debug( "excludedClasses[" + excludedClasses + "]"); 152 getLog().debug( "outputDir[" + outputDir + "]" ); 153 getLog().debug( "propertyEditorPaths[" + propertyEditorPaths + "]" ); 154 getLog().debug( "schemaAsArtifact[" + schemaAsArtifact + "]"); 155 getLog().debug( "generateSpringSchemasFile[" + generateSpringSchemasFile + "]"); 156 getLog().debug( "generateSpringHandlersFile[" + generateSpringHandlersFile + "]"); 157 158 if (schema == null) { 159 schema = new File(outputDir, project.getArtifactId() + ".xsd"); 160 } 161 162 if (propertyEditorPaths != null) { 163 List<String> editorSearchPath = new LinkedList<String>(Arrays.asList(PropertyEditorManager.getEditorSearchPath())); 164 for (StringTokenizer paths = new StringTokenizer(propertyEditorPaths, " ,"); paths.hasMoreElements(); ) { 165 //StringTokenizer implements Enumeration<Object>, not Enumeration<String> !! 166 editorSearchPath.add((String) paths.nextElement()); 167 } 168 PropertyEditorManager.setEditorSearchPath( editorSearchPath.toArray(new String[editorSearchPath.size()])); 169 } 170 171 ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); 172 Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); 173 try { 174 schema.getParentFile().mkdirs(); 175 176 String[] excludedClasses = null; 177 if (this.excludedClasses != null) { 178 excludedClasses = this.excludedClasses.split(" *, *"); 179 } 180 Set<Artifact> dependencies = project.getDependencyArtifacts(); 181 List<File> sourceJars = new ArrayList<File>(); 182 sourceJars.add(srcDir); 183 if( includes !=null ) { 184 for (String src : includes) { 185 sourceJars.add(new File(src)); 186 } 187 } 188 for (Artifact dependency : dependencies) { 189 if ("sources".equals(dependency.getClassifier())) { 190 File file = dependency.getFile(); 191 sourceJars.add(file); 192 } 193 } 194 File[] srcJars = sourceJars.toArray(new File[sourceJars.size()]); 195 MappingLoader mappingLoader = new QdoxMappingLoader(namespace, srcJars, excludedClasses); 196 GeneratorPlugin[] plugins = new GeneratorPlugin[]{ 197 new XmlMetadataGenerator(outputDir.getAbsolutePath(), schema, generateSpringSchemasFile, generateSpringHandlersFile), 198 new DocumentationGenerator(schema), 199 new XsdGenerator(schema, strictXsdOrder), 200 new WikiDocumentationGenerator(schema), 201 }; 202 203 // load the mappings 204 Thread.currentThread().setContextClassLoader(getClassLoader()); 205 Set<NamespaceMapping> namespaces = mappingLoader.loadNamespaces(); 206 if (namespaces.isEmpty()) { 207 System.out.println("Warning: no namespaces found!"); 208 } 209 210 // generate the files 211 for (NamespaceMapping namespaceMapping : namespaces) { 212 for (GeneratorPlugin plugin : plugins) { 213 plugin.setLog(this); 214 plugin.generate(namespaceMapping); 215 } 216 for (GeneratorPlugin plugin : generatorPlugins) { 217 plugin.setLog(this); 218 plugin.generate(namespaceMapping); 219 } 220 } 221 222 // Attach them as artifacts 223 if (schemaAsArtifact) { 224 projectHelper.attachArtifact(project, "xsd", null, schema); 225 projectHelper.attachArtifact(project, "html", "schema", new File(schema.getAbsolutePath() + ".html")); 226 } 227 228 Resource res = new Resource(); 229 res.setDirectory(outputDir.toString()); 230 project.addResource(res); 231 232 log("...done."); 233 } catch (Exception e) { 234 throw new BuildException(e); 235 } finally { 236 Thread.currentThread().setContextClassLoader(oldCL); 237 } 238 } 239 240 public void log(String message) { 241 getLog().info(message); 242 } 243 244 public void log(String message, int level) { 245 getLog().info(message); 246 } 247 248 protected URLClassLoader getClassLoader() throws MojoExecutionException { 249 try { 250 Set<URL> urls = new HashSet<URL>(); 251 252 URL mainClasses = new File(project.getBuild().getOutputDirectory()) 253 .toURI().toURL(); 254 getLog().debug("Adding to classpath : " + mainClasses); 255 urls.add(mainClasses); 256 257 URL testClasses = new File(project.getBuild() 258 .getTestOutputDirectory()).toURI().toURL(); 259 getLog().debug("Adding to classpath : " + testClasses); 260 urls.add(testClasses); 261 262 Set<Artifact> dependencies = project.getArtifacts(); 263 for (Artifact classPathElement : dependencies) { 264 getLog().debug( 265 "Adding artifact: " + classPathElement.getFile() 266 + " to classpath"); 267 urls.add(classPathElement.getFile().toURI().toURL()); 268 } 269 270 if( classPathIncludes!=null ) { 271 for (String include : classPathIncludes) { 272 final URL url = new File(include).toURI().toURL(); 273 getLog().debug("Adding to classpath : " + url); 274 urls.add(url); 275 } 276 } 277 278 return new URLClassLoader(urls.toArray(new URL[urls.size()]), 279 this.getClass().getClassLoader()); 280 } catch (MalformedURLException e) { 281 throw new MojoExecutionException( 282 "Error during setting up classpath", e); 283 } 284 } 285 286}