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 test-scope Java testSources 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 TestSchemaGenerationMojo was completely re-implemented for the 2.x versions.
46   * Its configuration semantics and parameter set is <strong>not backwards compatible</strong>
47   * with the 1.x plugin versions. If you are upgrading from version 1.x of the plugin, read
48   * 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 = "testSchemagen",
54          defaultPhase = LifecyclePhase.GENERATE_TEST_RESOURCES,
55          requiresDependencyResolution = ResolutionScope.TEST,
56          threadSafe = true)
57  public class TestSchemaGenerationMojo extends AbstractXsdGeneratorMojo {
58  
59      /**
60       * The last part of the stale fileName for this TestSchemaGenerationMojo.
61       */
62      public static final String STALE_FILENAME = "testSchemaGenerationStaleFlag";
63  
64      /**
65       * Default exclude file name suffixes for testSources, used unless overridden by an
66       * explicit configuration in the {@code testSchemaSourceExcludeFilters} parameter.
67       */
68      public static final List<Filter<File>> STANDARD_TEST_SOURCE_EXCLUDE_FILTERS;
69  
70      static {
71  
72          final List<Filter<File>> testSrcTemp = new ArrayList<Filter<File>>();
73          testSrcTemp.addAll(AbstractJaxbMojo.STANDARD_EXCLUDE_FILTERS);
74          testSrcTemp.add(new PatternFileFilter(Arrays.asList("\\.xjb", "\\.xsd", "\\.properties"), true));
75          STANDARD_TEST_SOURCE_EXCLUDE_FILTERS = Collections.unmodifiableList(testSrcTemp);
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;testSources>
88       *          &lt;testSource>/a/full/absolute/path/to/a/SourceFile.java&lt;/testSource>
89       *          &lt;testSource>target/some/sourceJar.jar&lt;/test>
90       *          &lt;testSource>src/test/java&lt;/test>
91       *      &lt;/testSources>
92       *   &lt;/configuration>
93       * </code>
94       * </pre>
95       * <p><strong>Note</strong>: if configured, the testSources parameters replace the default
96       * value, which is the single directory {@code getProject().getBuild().getTestSourceDirectory()}.</p>
97       *
98       * @since 2.0
99       */
100     @Parameter(defaultValue = "${project.build.testSource}", readonly = true, required = true)
101     private List<String> testSources;
102 
103     /**
104      * <p>Parameter holding a List of Filters, used to match all files under the {@code testSources} directories
105      * which should <strong>not</strong> be considered SchemaGenerator testSource files. (The filters identify files to
106      * exclude, and hence this parameter is called {@code testSchemaSourceExcludeFilters}). If a file under any of the
107      * testSource directories matches at least one of the Filters supplied in the
108      * {@code testSchemaSourceExcludeFilters}, it is not considered an XJC test source file, and therefore excluded
109      * from processing.</p>
110      * <p>If not explicitly provided, the Mojo uses the value within {@code STANDARD_TEST_SOURCE_EXCLUDE_FILTERS}.
111      * The algorithm for finding XJC sources is as follows:</p>
112      * <ol>
113      * <li>Find all files given in the testSources List. Any Directories provided are searched for files
114      * recursively.</li>
115      * <li>Exclude any found files matching any of the supplied {@code testSchemaSourceExcludeFilters} List.</li>
116      * <li>The remaining Files are submitted for processing by the XJC tool.</li>
117      * </ol>
118      * <p><strong>Example:</strong> The following configuration would exclude any testSources whose names end with
119      * {@code .txt} or {@code .foo}:</p>
120      * <pre>
121      *     <code>
122      *         &lt;configuration>
123      *         ...
124      *              &lt;testSchemaSourceExcludeFilters>
125      *                  &lt;filter implementation="org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter">
126      *                      &lt;patterns>
127      *                          &lt;pattern>\.txt&lt;/pattern>
128      *                          &lt;pattern>\.foo&lt;/pattern>
129      *                      &lt;/patterns>
130      *                  &lt;/filter>
131      *              &lt;/testSchemaSourceExcludeFilters>
132      *         &lt;/configuration>
133      *     </code>
134      * </pre>
135      * <p>Note that inner workings of the Dependency Injection mechanism used by Maven Plugins (i.e. the DI from
136      * the Plexus container) requires that the full class name to the Filter implementation should be supplied for
137      * each filter, as is illustrated in the sample above. This is true also if you implement custom Filters.</p>
138      *
139      * @see #STANDARD_TEST_SOURCE_EXCLUDE_FILTERS
140      * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter
141      * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.AbstractPatternFilter
142      * @see org.codehaus.mojo.jaxb2.shared.filters.AbstractFilter
143      */
144     @Parameter(required = false)
145     private List<Filter<File>> testSchemaSourceExcludeFilters;
146 
147     /**
148      * <p>The directory where the generated XML Schema file(s) will be placed.</p>
149      */
150     @Parameter(defaultValue = "${project.build.directory}/generated-test-resources/schemagen", required = true)
151     private File outputDirectory;
152 
153     /**
154      * <p>The directory where the {@code schemagen} tool will output XSDs, episode files - and intermediary bytecode
155      * files. From this directory the XSDs and the episode file (but not the bytecode files) will be copied to the
156      * outputDirectory for further processing.</p>
157      *
158      * @see #outputDirectory
159      */
160     @Parameter(defaultValue = "${project.build.directory}/schemagen-work/test_scope", required = true)
161     private File testWorkDirectory;
162 
163     /**
164      * {@inheritDoc}
165      */
166     @Override
167     protected List<URL> getCompiledClassNames() {
168 
169         final List<Filter<File>> excludeFilters = testSchemaSourceExcludeFilters == null
170                 ? STANDARD_BYTECODE_EXCLUDE_FILTERS
171                 : testSchemaSourceExcludeFilters;
172         Filters.initialize(getLog(), excludeFilters);
173 
174         try {
175             return FileSystemUtilities.filterFiles(
176                     getProject().getBasedir(),
177                     testSources,
178                     getProject().getTestClasspathElements(),
179                     getLog(),
180                     "test-compiled bytecode",
181                     excludeFilters);
182         } catch (DependencyResolutionRequiredException e) {
183             throw new IllegalStateException("Could not resolve test classpath elements.", e);
184         }
185     }
186 
187     /**
188      * {@inheritDoc}
189      */
190     @Override
191     protected List<String> getClasspath() throws MojoExecutionException {
192 
193         List<String> toReturn = null;
194         try {
195             toReturn = getProject().getTestClasspathElements();
196         } catch (DependencyResolutionRequiredException e) {
197             throw new MojoExecutionException("Could not acquire compile classpath elements from MavenProject", e);
198         }
199 
200         // All done.
201         return toReturn;
202     }
203 
204     /**
205      * {@inheritDoc}
206      */
207     @Override
208     protected List<URL> getSources() {
209 
210         final List<Filter<File>> excludeFilters = testSchemaSourceExcludeFilters == null
211                 ? STANDARD_TEST_SOURCE_EXCLUDE_FILTERS
212                 : testSchemaSourceExcludeFilters;
213         Filters.initialize(getLog(), excludeFilters);
214 
215         return FileSystemUtilities.filterFiles(
216                 getProject().getBasedir(),
217                 testSources,
218                 getProject().getTestCompileSourceRoots(),
219                 getLog(),
220                 "test schema sources",
221                 excludeFilters);
222     }
223 
224     /**
225      * {@inheritDoc}
226      */
227     @Override
228     protected File getOutputDirectory() {
229         return outputDirectory;
230     }
231 
232     /**
233      * {@inheritDoc}
234      */
235     @Override
236     protected String getStaleFileName() {
237         return STALE_FILENAME;
238     }
239 
240     /**
241      * {@inheritDoc}
242      */
243     @Override
244     protected File getWorkDirectory() {
245         return testWorkDirectory;
246     }
247 }