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 test-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 TestXjcMojo 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örelid</a> 52 * @see <a href="https://jaxb.java.net/">The JAXB Reference Implementation</a> 53 */ 54 @Mojo(name = "testXjc", 55 defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES, 56 requiresDependencyResolution = ResolutionScope.TEST, 57 threadSafe = false) 58 public class TestXjcMojo extends AbstractJavaGeneratorMojo { 59 60 /** 61 * The last part of the stale fileName for this TestXjcMojo. 62 */ 63 public static final String STALE_FILENAME = "testXjcStaleFlag"; 64 65 /** 66 * Standard directory path (relative to basedir) searched recursively for test 67 * source files (typically XSDs), unless overridden by an <code>testSources</code> configuration element. 68 */ 69 public static final String STANDARD_TEST_SOURCE_DIRECTORY = "src/test/xsd"; 70 71 /** 72 * Default exclude Filters for test sources, used unless overridden by an 73 * explicit configuration in the {@code testSourceExcludeFilters} parameter. 74 */ 75 public static final List<Filter<File>> STANDARD_TEST_SOURCE_EXCLUDE_FILTERS; 76 77 /** 78 * <p>Standard directory path (relative to basedir) searched recursively for XJB 79 * files, unless overridden by an <code>testXjbSources</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_TEST_XJB_DIRECTORY = "src/test/xjb"; 84 85 /** 86 * Default List of exclude Filters for XJB files, unless overridden by providing 87 * an explicit configuration in the {@code testXjbExcludeFilters} parameter. 88 */ 89 public static final List<Filter<File>> STANDARD_TEST_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_TEST_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_TEST_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 test source files are created.</p> 107 */ 108 @Parameter(defaultValue = "${project.build.directory}/generated-test-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 * <configuration> 119 * ... 120 * <testSources> 121 * <testSource>some/explicit/relative/file.xsd</testSource> 122 * <testSource>/another/absolute/path/to/a/specification.xsd</testSource> 123 * <testSource>a/directory/holding/xsds</testSource> 124 * </testSources> 125 * </configuration> 126 * </code> 127 * </pre> 128 * 129 * @see #STANDARD_TEST_SOURCE_DIRECTORY 130 */ 131 @Parameter(required = false) 132 private List<String> testSources; 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 * <configuration> 143 * ... 144 * <testXjbSources> 145 * <testXjbSource>bindings/aBindingConfiguration.xjb</testXjbSource> 146 * <testXjbSource>bindings/config/directory</testXjbSource> 147 * </testXjbSources> 148 * </configuration> 149 * </code> 150 * </pre> 151 * 152 * @see #STANDARD_TEST_XJB_DIRECTORY 153 */ 154 @Parameter(required = false) 155 private List<String> testXjbSources; 156 157 /** 158 * <p>Parameter holding a List of Filters, used to match all files under the {@code testSources} directories 159 * which should <strong>not</strong> be considered XJC test source files. (The filters identify files to 160 * exclude, and hence this parameter is called {@code testS§ourceExcludeFilters}). If a file under any of the 161 * test source directories matches at least one of the Filters supplied in the {@code testSourceExcludeFilters}, 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_TEST_SOURCE_EXCLUDE_FILTERS}. 164 * The algorithm for finding XJC test sources is as follows:</p> 165 * <ol> 166 * <li>Find all files given in the testSources List. Any Directories provided are searched for files 167 * recursively.</li> 168 * <li>Exclude any found files matching any of the supplied {@code testSourceExcludeFilters} 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 * <configuration> 176 * ... 177 * <testSourceExcludeFilters> 178 * <suffixFilter impl="org.codehaus.mojo.jaxb2.shared.filters.source.ExclusionRegularExpressionFileFilter">txt</suffixFilter> 179 * <suffixFilter impl="org.codehaus.mojo.jaxb2.shared.filters.source.ExclusionRegularExpressionFileFilter">foo</suffixFilter> 180 * </testSourceExcludeFilters> 181 * </configuration> 182 * </code> 183 * </pre> 184 * 185 * @see #STANDARD_TEST_SOURCE_EXCLUDE_FILTERS 186 * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter 187 * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.AbstractPatternFilter 188 * @see org.codehaus.mojo.jaxb2.shared.filters.AbstractFilter 189 */ 190 @Parameter(required = false) 191 private List<Filter<File>> testSourceExcludeFilters; 192 193 /*** 194 * <p>Parameter holding a List of Filters, used to match all files under the {@code testXjbSources} directories 195 * which should <strong>not</strong> be considered XJB files. (The filters identify files to exclude, and hence 196 * this parameter is called {@code testXjbExcludeFilters}). If a file matches at least one of the supplied Filters, 197 * it is not considered an XJB file, and therefore excluded from processing.</p> 198 * <p>If not explicitly provided, the Mojo uses the value within {@code STANDARD_TEST_XJB_EXCLUDE_FILTERS}.</p> 199 * <p><strong>Example:</strong> The following configuration would exclude any XJB files whose names end with 200 * {@code xml} or {@code foo}:</p> 201 * <pre> 202 * <code> 203 * <configuration> 204 * ... 205 * <testXjbExcludeFilters> 206 * <suffixFilter impl="org.codehaus.mojo.jaxb2.shared.filters.source.ExclusionRegularExpressionFileFilter">xml</suffixFilter> 207 * <suffixFilter impl="org.codehaus.mojo.jaxb2.shared.filters.source.ExclusionRegularExpressionFileFilter">foo</suffixFilter> 208 * </sourceExcludeFilters> 209 * </testXjbExcludeFilters> 210 * </code> 211 * </pre> 212 * 213 * @see #STANDARD_TEST_XJB_EXCLUDE_FILTERS 214 * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter 215 * @see org.codehaus.mojo.jaxb2.shared.filters.pattern.AbstractPatternFilter 216 * @see org.codehaus.mojo.jaxb2.shared.filters.AbstractFilter 217 */ 218 @Parameter(required = false) 219 private List<Filter<File>> testXjbExcludeFilters; 220 221 /** 222 * Indicate if the XjcMojo execution should be skipped. 223 */ 224 @Parameter(property = "xjc.test.skip", defaultValue = "false") 225 private boolean skipTestXjc; 226 227 /** 228 * {@inheritDoc} 229 */ 230 @Override 231 protected boolean shouldExecutionBeSkipped() { 232 return skipTestXjc; 233 } 234 235 /** 236 * {@inheritDoc} 237 */ 238 @Override 239 protected List<URL> getSources() { 240 241 final List<Filter<File>> excludePatterns = testSourceExcludeFilters == null 242 ? STANDARD_TEST_SOURCE_EXCLUDE_FILTERS 243 : testSourceExcludeFilters; 244 Filters.initialize(getLog(), excludePatterns); 245 246 // All done. 247 return FileSystemUtilities.filterFiles( 248 getProject().getBasedir(), 249 testSources, 250 Arrays.asList(STANDARD_TEST_SOURCE_DIRECTORY), 251 getLog(), 252 "testSources", 253 excludePatterns); 254 } 255 256 /** 257 * {@inheritDoc} 258 */ 259 @Override 260 protected List<File> getSourceXJBs() { 261 262 final List<Filter<File>> excludePatterns = testXjbExcludeFilters == null 263 ? STANDARD_TEST_XJB_EXCLUDE_FILTERS 264 : testXjbExcludeFilters; 265 Filters.initialize(getLog(), excludePatterns); 266 267 return FileSystemUtilities.filterFiles( 268 getProject().getBasedir(), 269 testXjbSources, 270 STANDARD_TEST_XJB_DIRECTORY, 271 getLog(), 272 "testXjbSources", 273 excludePatterns); 274 } 275 276 /** 277 * {@inheritDoc} 278 */ 279 @Override 280 protected String getStaleFileName() { 281 return STALE_FILENAME; 282 } 283 284 /** 285 * {@inheritDoc} 286 */ 287 @Override 288 protected File getOutputDirectory() { 289 return outputDirectory; 290 } 291 292 /** 293 * {@inheritDoc} 294 */ 295 @Override 296 protected List<String> getClasspath() throws MojoExecutionException { 297 try { 298 return (List<String>) getProject().getTestClasspathElements(); 299 } catch (DependencyResolutionRequiredException e) { 300 throw new MojoExecutionException("Could not retrieve Compile classpath.", e); 301 } 302 } 303 304 /** 305 * {@inheritDoc} 306 */ 307 @Override 308 protected void addGeneratedSourcesToProjectSourceRoot() { 309 getProject().addTestCompileSourceRoot(getOutputDirectory().getAbsolutePath()); 310 } 311 312 /** 313 * {@inheritDoc} 314 */ 315 @Override 316 protected void addResource(final Resource resource) { 317 getProject().addTestResource(resource); 318 } 319 }