View Javadoc
1   package org.codehaus.mojo.jaxb2.schemageneration;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.artifact.DependencyResolutionRequiredException;
23  import org.apache.maven.plugin.MojoExecutionException;
24  import org.apache.maven.plugins.annotations.LifecyclePhase;
25  import org.apache.maven.plugins.annotations.Mojo;
26  import org.apache.maven.plugins.annotations.Parameter;
27  import org.apache.maven.plugins.annotations.ResolutionScope;
28  import org.codehaus.mojo.jaxb2.AbstractJaxbMojo;
29  import org.codehaus.mojo.jaxb2.shared.FileSystemUtilities;
30  import org.codehaus.mojo.jaxb2.shared.filters.Filter;
31  import org.codehaus.mojo.jaxb2.shared.filters.Filters;
32  import org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter;
33  
34  import java.io.File;
35  import java.net.URL;
36  import java.util.ArrayList;
37  import java.util.Arrays;
38  import java.util.Collections;
39  import java.util.List;
40  
41  /**
42   * <p>Mojo that creates XML schema(s) from compile-scope Java sources or binaries
43   * by invoking the JAXB SchemaGenerator. This implementation is tailored to use the
44   * JAXB Reference Implementation from project Kenai.</p>
45   * <p>Note that the SchemaGenerationMojo was completely re-implemented for the 2.x versions.
46   * Its configuration semantics and parameter set is <strong>not necessarily
47   * backwards compatible</strong> with the 1.x plugin versions. If you are
48   * upgrading from version 1.x of the plugin, read the documentation carefully.</p>
49   *
50   * @author <a href="mailto:lj@jguru.se">Lennart J&ouml;relid</a>
51   * @see <a href="https://jaxb.java.net/">The JAXB Reference Implementation</a>
52   */
53  @Mojo(name = "schemagen",
54          defaultPhase = LifecyclePhase.GENERATE_RESOURCES,
55          requiresDependencyResolution = ResolutionScope.COMPILE,
56          threadSafe = true)
57  public class SchemaGenerationMojo extends AbstractXsdGeneratorMojo {
58  
59      /**
60       * The last part of the stale fileName for this SchemaGenerationMojo.
61       */
62      public static final String STALE_FILENAME = "schemaGenerationStaleFlag";
63  
64      /**
65       * Default exclude file name suffixes for sources, used unless overridden by an
66       * explicit configuration in the {@code sourceExcludeSuffixes} parameter.
67       */
68      public static final List<Filter<File>> STANDARD_SOURCE_EXCLUDE_FILTERS;
69  
70      static {
71  
72          final List<Filter<File>> srcTemp = new ArrayList<Filter<File>>();
73          srcTemp.addAll(AbstractJaxbMojo.STANDARD_EXCLUDE_FILTERS);
74          srcTemp.add(new PatternFileFilter(Arrays.asList("\\.xjb", "\\.xsd", "\\.properties"), true));
75          STANDARD_SOURCE_EXCLUDE_FILTERS = Collections.unmodifiableList(srcTemp);
76      }
77  
78      /**
79       * <p>Parameter holding List of paths to files and/or directories which should be recursively searched
80       * for Java source files. Only files or directories that actually exist will be included (in the case of files)
81       * or recursively searched for source files to include (in the case of directories or JARs).
82       * Configure using standard Maven structure for Lists:</p>
83       * <pre>
84       * <code>
85       *   &lt;configuration>
86       *   ...
87       *       &lt;sources>
88       *          &lt;source>/a/full/absolute/path/to/a/SourceFile.java&lt;/source>
89       *          &lt;source>target/some/sourceJar.jar&lt;/source>
90       *          &lt;source>src/main/java&lt;/source>
91       *      &lt;/sources>
92       *   &lt;/configuration>
93       * </code>
94       * </pre>
95       * <p><strong>Note</strong>: if configured, the sources parameters replace the default
96       * value, which is the single directory {@code getProject().getCompileSourceRoots()}.</p>
97       *
98       * @since 2.0
99       */
100     @Parameter(defaultValue = "${project.compileSourceRoots}", readonly = true, required = true)
101     private List<String> sources;
102 
103     /**
104      * <p>Parameter holding a List of Filters, used to match all files under the {@code sources} directories
105      * which should <strong>not</strong> be considered SchemaGenerator source files. (The filters identify files to
106      * exclude, and hence this parameter is called {@code schemaSourceExcludeFilters}). If a file under any of the
107      * source directories matches at least one of the Filters supplied in the {@code schemaSourceExcludeFilters},
108      * it is not considered an XJC source file, and therefore excluded from processing.</p>
109      * <p>If not explicitly provided, the Mojo uses the value within {@code STANDARD_SOURCE_EXCLUDE_FILTERS}.
110      * The algorithm for finding XJC sources is as follows:</p>
111      * <ol>
112      * <li>Find all files given in the sources List. Any Directories provided are searched for files
113      * recursively.</li>
114      * <li>Exclude any found files matching any of the supplied {@code schemaSourceExcludeFilters} List.</li>
115      * <li>The remaining Files are submitted for processing by the XJC tool.</li>
116      * </ol>
117      * <p><strong>Example:</strong> The following configuration would exclude any sources whose names end with
118      * {@code .txt} or {@code .foo}:</p>
119      * <pre>
120      *     <code>
121      *         &lt;configuration>
122      *         ...
123      *              &lt;schemaSourceExcludeFilters>
124      *                  &lt;filter implementation="org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter">
125      *                      &lt;patterns>
126      *                          &lt;pattern>\.txt&lt;/pattern>
127      *                          &lt;pattern>\.foo&lt;/pattern>
128      *                      &lt;/patterns>
129      *                  &lt;/filter>
130      *              &lt;/schemaSourceExcludeFilters>
131      *         &lt;/configuration>
132      *     </code>
133      * </pre>
134      * <p>Note that inner workings of the Dependency Injection mechanism used by Maven Plugins (i.e. the DI from
135      * the Plexus container) requires that the full class name to the Filter implementation should be supplied for
136      * each filter, as is illustrated in the sample above. This is true also if you implement custom Filters.</p>
137      *
138      * @see #STANDARD_SOURCE_EXCLUDE_FILTERS
139      * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter
140      * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.AbstractPatternFilter
141      * @see org.codehaus.mojo.jaxb2.shared.filters.AbstractFilter
142      * @since 2.0
143      */
144     @Parameter(required = false)
145     private List<Filter<File>> schemaSourceExcludeFilters;
146 
147     /**
148      * <p>The directory where the generated XML Schema file(s) will be
149      * placed, after all transformations are done.</p>
150      */
151     @Parameter(defaultValue = "${project.build.directory}/generated-resources/schemagen", required = true)
152     private File outputDirectory;
153 
154     /**
155      * <p>The directory where the {@code schemagen} tool will output XSDs, episode files - and intermediary bytecode
156      * files. From this directory the XSDs and the episode file (but not the bytecode files) will be copied to the
157      * outputDirectory for further processing.</p>
158      *
159      * @see #outputDirectory
160      */
161     @Parameter(defaultValue = "${project.build.directory}/schemagen-work/compile_scope", required = true)
162     private File workDirectory;
163 
164     /**
165      * {@inheritDoc}
166      */
167     @Override
168     protected List<URL> getCompiledClassNames() {
169 
170         List<Filter<File>> excludeFilters = schemaSourceExcludeFilters == null
171                 ? STANDARD_BYTECODE_EXCLUDE_FILTERS
172                 : schemaSourceExcludeFilters;
173         Filters.initialize(getLog(), excludeFilters);
174 
175         try {
176             return FileSystemUtilities.filterFiles(
177                     getProject().getBasedir(),
178                     null,
179                     getProject().getCompileClasspathElements(),
180                     getLog(),
181                     "compiled bytecode",
182                     excludeFilters);
183         } catch (DependencyResolutionRequiredException e) {
184             throw new IllegalStateException("Could not resolve dependencies.", e);
185         }
186     }
187 
188     /**
189      * {@inheritDoc}
190      */
191     @Override
192     protected List<URL> getSources() {
193 
194         /*
195         // TODO: Add source-classified Artifacts in classpath?
196         for(Artifact current : (Set<Artifact>) getProject().getDependencyArtifacts()) {
197             final ArtifactRepository repository = current.getRepository();
198         }
199         */
200 
201         final List<Filter<File>> sourceExcludes = schemaSourceExcludeFilters == null
202                 ? STANDARD_SOURCE_EXCLUDE_FILTERS
203                 : schemaSourceExcludeFilters;
204         Filters.initialize(getLog(), sourceExcludes);
205 
206         // All Done.
207         return FileSystemUtilities.filterFiles(
208                 getProject().getBasedir(),
209                 sources,
210                 getProject().getCompileSourceRoots(),
211                 getLog(),
212                 "sources",
213                 sourceExcludes);
214     }
215 
216     /**
217      * {@inheritDoc}
218      */
219     @Override
220     protected File getOutputDirectory() {
221         return outputDirectory;
222     }
223 
224     /**
225      * {@inheritDoc}
226      */
227     @Override
228     protected List<String> getClasspath() throws MojoExecutionException {
229 
230         List<String> toReturn = null;
231         try {
232             toReturn = getProject().getCompileClasspathElements();
233         } catch (DependencyResolutionRequiredException e) {
234             throw new MojoExecutionException("Could not acquire compile classpath elements from MavenProject", e);
235         }
236 
237         // All done.
238         return toReturn;
239     }
240 
241     /**
242      * {@inheritDoc}
243      */
244     @Override
245     protected String getStaleFileName() {
246         return STALE_FILENAME;
247     }
248 
249     /**
250      * {@inheritDoc}
251      */
252     @Override
253     protected File getWorkDirectory() {
254         return workDirectory;
255     }
256 }