View Javadoc
1   package org.codehaus.mojo.jaxb2.javageneration;
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.model.Resource;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugins.annotations.LifecyclePhase;
26  import org.apache.maven.plugins.annotations.Mojo;
27  import org.apache.maven.plugins.annotations.Parameter;
28  import org.apache.maven.plugins.annotations.ResolutionScope;
29  import org.codehaus.mojo.jaxb2.AbstractJaxbMojo;
30  import org.codehaus.mojo.jaxb2.shared.FileSystemUtilities;
31  import org.codehaus.mojo.jaxb2.shared.filters.Filter;
32  import org.codehaus.mojo.jaxb2.shared.filters.Filters;
33  import org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter;
34  
35  import java.io.File;
36  import java.net.URL;
37  import java.util.ArrayList;
38  import java.util.Arrays;
39  import java.util.Collections;
40  import java.util.List;
41  
42  /**
43   * <p>Mojo that creates compile-scope Java source or binaries from XML schema(s)
44   * by invoking the JAXB XJC binding compiler. This implementation is tailored
45   * to use the JAXB Reference Implementation from project Kenai.</p>
46   * <p>Note that the XjcMojo was completely re-implemented for the 2.x versions.
47   * Its configuration semantics and parameter set is <strong>not necessarily
48   * backwards compatible</strong> with the 1.x plugin versions. If you are
49   * upgrading from version 1.x of the plugin, read the documentation carefully.</p>
50   *
51   * @author <a href="mailto:lj@jguru.se">Lennart J&ouml;relid</a>
52   * @see <a href="https://jaxb.java.net/">The JAXB Reference Implementation</a>
53   */
54  @Mojo(name = "xjc",
55          threadSafe = false,
56          defaultPhase = LifecyclePhase.GENERATE_SOURCES,
57          requiresDependencyResolution = ResolutionScope.COMPILE)
58  public class XjcMojo extends AbstractJavaGeneratorMojo {
59  
60      /**
61       * The last part of the stale fileName for this XjcMojo.
62       */
63      public static final String STALE_FILENAME = "xjcStaleFlag";
64  
65      /**
66       * <p>Standard directory path (relative to basedir) searched recursively for source
67       * files (typically XSDs), unless overridden by an <code>sources</code> configuration element.</p>
68       */
69      public static final String STANDARD_SOURCE_DIRECTORY = "src/main/xsd";
70  
71      /**
72       * Default exclude Filters for sources, used unless overridden by an
73       * explicit configuration in the {@code xjcSourceExcludeFilters} parameter.
74       */
75      public static final List<Filter<File>> STANDARD_SOURCE_EXCLUDE_FILTERS;
76  
77      /**
78       * <p>Standard directory path (relative to basedir) searched recursively for XJB
79       * files, unless overridden by an <code>xjbSources</code> configuration element.
80       * As explained in the JAXB specification, XJB files (JAXB Xml Binding files)
81       * are used to configure parts of the Java source generation.</p>
82       */
83      public static final String STANDARD_XJB_DIRECTORY = "src/main/xjb";
84  
85      /**
86       * Default List of exclude Filters for XJB files, unless overridden by providing
87       * an explicit configuration in the {@code xjbExcludeSuffixes} parameter.
88       */
89      public static final List<Filter<File>> STANDARD_XJB_EXCLUDE_FILTERS;
90  
91      static {
92  
93          final List<Filter<File>> xjbTemp = new ArrayList<Filter<File>>();
94          xjbTemp.addAll(AbstractJaxbMojo.STANDARD_EXCLUDE_FILTERS);
95          xjbTemp.add(new PatternFileFilter(Arrays.asList("\\.xsd"), true));
96          STANDARD_XJB_EXCLUDE_FILTERS = Collections.unmodifiableList(xjbTemp);
97  
98          final List<Filter<File>> xsdTemp = new ArrayList<Filter<File>>();
99          xsdTemp.addAll(AbstractJaxbMojo.STANDARD_EXCLUDE_FILTERS);
100         xsdTemp.add(new PatternFileFilter(Arrays.asList("\\.xjb"), true));
101         STANDARD_SOURCE_EXCLUDE_FILTERS = Collections.unmodifiableList(xsdTemp);
102     }
103 
104     /**
105      * <p>Corresponding XJC parameter: {@code d}.</p>
106      * <p>The working directory where the generated Java source files are created.</p>
107      */
108     @Parameter(defaultValue = "${project.build.directory}/generated-sources/jaxb", required = true)
109     private File outputDirectory;
110 
111     /**
112      * <p>Parameter holding List of XSD paths to files and/or directories which should be recursively searched
113      * for XSD files. Only files or directories that actually exist will be included (in the case of files)
114      * or recursively searched for XSD files to include (in the case of directories).
115      * Configure using standard Maven structure for Lists:</p>
116      * <pre>
117      * <code>
118      *   &lt;configuration>
119      *   ...
120      *       &lt;sources>
121      *          &lt;source>some/explicit/relative/file.xsd&lt;/source>
122      *          &lt;source>/another/absolute/path/to/a/specification.xsd&lt;/source>
123      *          &lt;source>a/directory/holding/xsds&lt;/source>
124      *      &lt;/sources>
125      *   &lt;/configuration>
126      * </code>
127      * </pre>
128      *
129      * @see #STANDARD_SOURCE_DIRECTORY
130      */
131     @Parameter(required = false)
132     private List<String> sources;
133 
134     /**
135      * <p>Parameter holding List of XJB Files and/or directories which should be recursively searched
136      * for XJB files. Only files or directories that actually exist will be included (in the case of files)
137      * or recursively searched for XJB files to include (in the case of directories). JAXB binding files are
138      * used to configure parts of the Java source generation.
139      * Supply the configuration using the standard Maven structure for configuring plugin Lists:</p>
140      * <pre>
141      * <code>
142      *   &lt;configuration>
143      *   ...
144      *       &lt;xjbSources>
145      *          &lt;xjbSource>bindings/aBindingConfiguration.xjb&lt;/xjbSource>
146      *          &lt;xjbSource>bindings/config/directory&lt;/xjbSource>
147      *      &lt;/xjbSources>
148      *   &lt;/configuration>
149      * </code>
150      * </pre>
151      *
152      * @see #STANDARD_XJB_DIRECTORY
153      */
154     @Parameter(required = false)
155     private List<String> xjbSources;
156 
157     /**
158      * <p>Parameter holding a List of Filters, used to match all files under the {@code sources} directories
159      * which should <strong>not</strong> be considered XJC source files. (The filters identify files to
160      * exclude, and hence this parameter is called {@code xjcSourceExcludeFilters}). If a file under any of the
161      * source directories matches at least one of the Filters supplied in the {@code xjcSourceExcludeFilters},
162      * it is not considered an XJC source file, and therefore excluded from processing.</p>
163      * <p>If not explicitly provided, the Mojo uses the value within {@code STANDARD_SOURCE_EXCLUDE_FILTERS}.
164      * The algorithm for finding XJC sources is as follows:</p>
165      * <ol>
166      * <li>Find all files given in the sources List. Any Directories provided are searched for files
167      * recursively.</li>
168      * <li>Exclude any found files matching any of the supplied {@code xjcSourceExcludeFilters} List.</li>
169      * <li>The remaining Files are submitted for processing by the XJC tool.</li>
170      * </ol>
171      * <p><strong>Example:</strong> The following configuration would exclude any sources whose names end with
172      * {@code txt} or {@code foo}:</p>
173      * <pre>
174      *     <code>
175      *         &lt;configuration>
176      *         ...
177      *              &lt;xjcSourceExcludeFilters>
178      *                  &lt;filter implementation="org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter">
179      *                      &lt;patterns>
180      *                          &lt;pattern>\.txt&lt;/pattern>
181      *                          &lt;pattern>\.foo&lt;/pattern>
182      *                      &lt;/patterns>
183      *                  &lt;/filter>
184      *              &lt;/xjcSourceExcludeFilters>
185      *         &lt;/configuration>
186      *     </code>
187      * </pre>
188      * <p>Note that inner workings of the Dependency Injection mechanism used by Maven Plugins (i.e. the DI from
189      * the Plexus container) requires that the full class name to the Filter implementation should be supplied for
190      * each filter, as is illustrated in the sample above. This is true also if you implement custom Filters.</p>
191      *
192      * @see #STANDARD_SOURCE_EXCLUDE_FILTERS
193      * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter
194      * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.AbstractPatternFilter
195      * @see org.codehaus.mojo.jaxb2.shared.filters.AbstractFilter
196      */
197     @Parameter(required = false)
198     private List<Filter<File>> xjcSourceExcludeFilters;
199 
200     /**
201      * <p>Parameter holding a List of Filters, used to match all files under the {@code xjbSources} directories
202      * which should <strong>not</strong> be considered XJB files. (The filters identify files to exclude, and hence
203      * this parameter is called {@code xjbExcludeFilters}). If a file matches at least one of the supplied Filters,
204      * it is not considered an XJB file, and therefore excluded from processing.</p>
205      * <p>If not explicitly provided, the Mojo uses the value within {@code STANDARD_XJB_EXCLUDE_FILTERS}.</p>
206      * <p><strong>Example:</strong> The following configuration would exclude any XJB files whose names end with
207      * {@code xml} or {@code foo}:</p>
208      * <pre>
209      *     <code>
210      *         &lt;configuration>
211      *         ...
212      *              &lt;xjbExcludeFilters>
213      *                  &lt;filter implementation="org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter">
214      *                      &lt;patterns>
215      *                          &lt;pattern>\.txt&lt;/pattern>
216      *                          &lt;pattern>\.foo&lt;/pattern>
217      *                      &lt;/patterns>
218      *                  &lt;/filter>
219      *              &lt;/xjbExcludeFilters>
220      *         ...
221      *         &lt;/configuration>
222      *     </code>
223      * </pre>
224      * <p>Note that inner workings of the Dependency Injection mechanism used by Maven Plugins (i.e. the DI from
225      * the Plexus container) requires that the full class name to the Filter implementation should be supplied for
226      * each filter, as is illustrated in the sample above. This is true also if you implement custom Filters.</p>
227      *
228      * @see #STANDARD_XJB_EXCLUDE_FILTERS
229      * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter
230      * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.AbstractPatternFilter
231      * @see org.codehaus.mojo.jaxb2.shared.filters.AbstractFilter
232      */
233     @Parameter(required = false)
234     private List<Filter<File>> xjbExcludeFilters;
235 
236     /**
237      * Indicate if the XjcMojo execution should be skipped.
238      */
239     @Parameter(property = "xjc.skip", defaultValue = "false")
240     private boolean skipXjc;
241 
242     /**
243      * {@inheritDoc}
244      */
245     @Override
246     protected boolean shouldExecutionBeSkipped() {
247         return skipXjc;
248     }
249 
250     /**
251      * {@inheritDoc}
252      */
253     @Override
254     protected List<URL> getSources() {
255 
256         final List<Filter<File>> excludePatterns = xjcSourceExcludeFilters == null
257                 ? STANDARD_SOURCE_EXCLUDE_FILTERS
258                 : xjcSourceExcludeFilters;
259         Filters.initialize(getLog(), excludePatterns);
260 
261         return FileSystemUtilities.filterFiles(
262                 getProject().getBasedir(),
263                 sources,
264                 Arrays.asList(STANDARD_SOURCE_DIRECTORY),
265                 getLog(),
266                 "sources",
267                 excludePatterns);
268     }
269 
270     /**
271      * {@inheritDoc}
272      */
273     @Override
274     protected List<File> getSourceXJBs() {
275 
276         final List<Filter<File>> excludePatterns = xjbExcludeFilters == null
277                 ? STANDARD_XJB_EXCLUDE_FILTERS
278                 : xjbExcludeFilters;
279         Filters.initialize(getLog(), excludePatterns);
280 
281         return FileSystemUtilities.filterFiles(
282                 getProject().getBasedir(),
283                 xjbSources,
284                 STANDARD_XJB_DIRECTORY,
285                 getLog(),
286                 "xjbSources",
287                 excludePatterns);
288     }
289 
290     /**
291      * {@inheritDoc}
292      */
293     @Override
294     protected String getStaleFileName() {
295         return STALE_FILENAME;
296     }
297 
298     /**
299      * {@inheritDoc}
300      */
301     @Override
302     protected File getOutputDirectory() {
303         return outputDirectory;
304     }
305 
306     /**
307      * {@inheritDoc}
308      */
309     @Override
310     protected List<String> getClasspath() throws MojoExecutionException {
311         try {
312             return (List<String>) getProject().getCompileClasspathElements();
313         } catch (DependencyResolutionRequiredException e) {
314             throw new MojoExecutionException("Could not retrieve Compile classpath.", e);
315         }
316     }
317 
318     /**
319      * {@inheritDoc}
320      */
321     @Override
322     protected void addGeneratedSourcesToProjectSourceRoot() {
323         getProject().addCompileSourceRoot(getOutputDirectory().getAbsolutePath());
324     }
325 
326     /**
327      * {@inheritDoc}
328      */
329     @Override
330     protected void addResource(final Resource resource) {
331         getProject().addResource(resource);
332     }
333 }