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 */
017 package org.apache.xbean.maven;
018
019 import java.beans.PropertyEditorManager;
020 import java.io.File;
021 import java.net.MalformedURLException;
022 import java.net.URL;
023 import java.net.URLClassLoader;
024 import java.util.ArrayList;
025 import java.util.Arrays;
026 import java.util.Collections;
027 import java.util.HashSet;
028 import java.util.Iterator;
029 import java.util.LinkedList;
030 import java.util.List;
031 import java.util.Set;
032 import java.util.StringTokenizer;
033
034 import org.apache.maven.artifact.Artifact;
035 import org.apache.maven.model.Resource;
036 import org.apache.maven.plugin.AbstractMojo;
037 import org.apache.maven.plugin.MojoExecutionException;
038 import org.apache.maven.plugin.MojoFailureException;
039 import org.apache.maven.project.MavenProject;
040 import org.apache.maven.project.MavenProjectHelper;
041 import org.apache.tools.ant.BuildException;
042 import org.apache.xbean.spring.generator.DocumentationGenerator;
043 import org.apache.xbean.spring.generator.GeneratorPlugin;
044 import org.apache.xbean.spring.generator.LogFacade;
045 import org.apache.xbean.spring.generator.MappingLoader;
046 import org.apache.xbean.spring.generator.NamespaceMapping;
047 import org.apache.xbean.spring.generator.QdoxMappingLoader;
048 import org.apache.xbean.spring.generator.WikiDocumentationGenerator;
049 import org.apache.xbean.spring.generator.XmlMetadataGenerator;
050 import 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 */
060 public 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 String excludedClasses;
091
092 /**
093 * @parameter expression="${basedir}/target/xbean/"
094 * @required
095 */
096 private File outputDir;
097
098 /**
099 * @parameter
100 */
101 private File schema;
102
103 /**
104 * @parameter expression="org.apache.xbean.spring.context.impl"
105 */
106 private String propertyEditorPaths;
107
108 /**
109 * @parameter schemaAsArtifact
110 */
111 private boolean schemaAsArtifact = true;
112
113 /**
114 * @parameter
115 */
116 private boolean generateSpringSchemasFile = true;
117
118 /**
119 * @parameter
120 */
121 private boolean generateSpringHandlersFile = true;
122
123 /**
124 * A list of additional GeneratorPlugins that should get used executed
125 * when generating output.
126 *
127 * @parameter
128 */
129 private List<GeneratorPlugin> generatorPlugins = Collections.emptyList();
130
131 public void execute() throws MojoExecutionException, MojoFailureException {
132 getLog().debug( " ======= XBeanMojo settings =======" );
133 getLog().debug( "namespace[" + namespace + "]" );
134 getLog().debug( "srcDir[" + srcDir + "]" );
135 getLog().debug( "schema[" + schema + "]" );
136 getLog().debug( "excludedClasses[" + excludedClasses + "]");
137 getLog().debug( "outputDir[" + outputDir + "]" );
138 getLog().debug( "propertyEditorPaths[" + propertyEditorPaths + "]" );
139 getLog().debug( "schemaAsArtifact[" + schemaAsArtifact + "]");
140 getLog().debug( "generateSpringSchemasFile[" + generateSpringSchemasFile + "]");
141 getLog().debug( "generateSpringHandlersFile[" + generateSpringHandlersFile + "]");
142
143 if (schema == null) {
144 schema = new File(outputDir, project.getArtifactId() + ".xsd");
145 }
146
147 if (propertyEditorPaths != null) {
148 List<String> editorSearchPath = new LinkedList<String>(Arrays.asList(PropertyEditorManager.getEditorSearchPath()));
149 for (StringTokenizer paths = new StringTokenizer(propertyEditorPaths, " ,"); paths.hasMoreElements(); ) {
150 //StringTokenizer implements Enumeration<Object>, not Enumeration<String> !!
151 editorSearchPath.add((String) paths.nextElement());
152 }
153 PropertyEditorManager.setEditorSearchPath( editorSearchPath.toArray(new String[editorSearchPath.size()]));
154 }
155
156 ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
157 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
158 try {
159 schema.getParentFile().mkdirs();
160
161 String[] excludedClasses = null;
162 if (this.excludedClasses != null) {
163 excludedClasses = this.excludedClasses.split(" *, *");
164 }
165 Set<Artifact> dependencies = project.getDependencyArtifacts();
166 List<File> sourceJars = new ArrayList<File>();
167 sourceJars.add(srcDir);
168 for (Artifact dependency : dependencies) {
169 if ("sources".equals(dependency.getClassifier())) {
170 File file = dependency.getFile();
171 sourceJars.add(file);
172 }
173 }
174 File[] srcJars = sourceJars.toArray(new File[sourceJars.size()]);
175 MappingLoader mappingLoader = new QdoxMappingLoader(namespace, srcJars, excludedClasses);
176 GeneratorPlugin[] plugins = new GeneratorPlugin[]{
177 new XmlMetadataGenerator(outputDir.getAbsolutePath(), schema, generateSpringSchemasFile, generateSpringHandlersFile),
178 new DocumentationGenerator(schema),
179 new XsdGenerator(schema),
180 new WikiDocumentationGenerator(schema),
181 };
182
183 // load the mappings
184 Thread.currentThread().setContextClassLoader(getClassLoader());
185 Set<NamespaceMapping> namespaces = mappingLoader.loadNamespaces();
186 if (namespaces.isEmpty()) {
187 System.out.println("Warning: no namespaces found!");
188 }
189
190 // generate the files
191 for (NamespaceMapping namespaceMapping : namespaces) {
192 for (GeneratorPlugin plugin : plugins) {
193 plugin.setLog(this);
194 plugin.generate(namespaceMapping);
195 }
196 for (GeneratorPlugin plugin : generatorPlugins) {
197 plugin.setLog(this);
198 plugin.generate(namespaceMapping);
199 }
200 }
201
202 // Attach them as artifacts
203 if (schemaAsArtifact) {
204 projectHelper.attachArtifact(project, "xsd", null, schema);
205 projectHelper.attachArtifact(project, "html", "schema", new File(schema.getAbsolutePath() + ".html"));
206 }
207
208 Resource res = new Resource();
209 res.setDirectory(outputDir.toString());
210 project.addResource(res);
211
212 log("...done.");
213 } catch (Exception e) {
214 throw new BuildException(e);
215 } finally {
216 Thread.currentThread().setContextClassLoader(oldCL);
217 }
218 }
219
220 public void log(String message) {
221 getLog().info(message);
222 }
223
224 public void log(String message, int level) {
225 getLog().info(message);
226 }
227
228 protected URLClassLoader getClassLoader() throws MojoExecutionException {
229 try {
230 Set<URL> urls = new HashSet<URL>();
231
232 URL mainClasses = new File(project.getBuild().getOutputDirectory())
233 .toURL();
234 getLog().debug("Adding to classpath : " + mainClasses);
235 urls.add(mainClasses);
236
237 URL testClasses = new File(project.getBuild()
238 .getTestOutputDirectory()).toURL();
239 getLog().debug("Adding to classpath : " + testClasses);
240 urls.add(testClasses);
241
242 Set<Artifact> dependencies = project.getArtifacts();
243 Iterator iter = dependencies.iterator();
244 for (Artifact classPathElement : dependencies) {
245 getLog().debug(
246 "Adding artifact: " + classPathElement.getFile()
247 + " to classpath");
248 urls.add(classPathElement.getFile().toURL());
249 }
250 URLClassLoader appClassloader = new URLClassLoader(urls.toArray(new URL[urls.size()]),
251 this.getClass().getClassLoader());
252 return appClassloader;
253 } catch (MalformedURLException e) {
254 throw new MojoExecutionException(
255 "Error during setting up classpath", e);
256 }
257 }
258
259 }