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ö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 * <configuration> 86 * ... 87 * <testSources> 88 * <testSource>/a/full/absolute/path/to/a/SourceFile.java</testSource> 89 * <testSource>target/some/sourceJar.jar</test> 90 * <testSource>src/test/java</test> 91 * </testSources> 92 * </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 * <configuration> 123 * ... 124 * <testSchemaSourceExcludeFilters> 125 * <filter implementation="org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter"> 126 * <patterns> 127 * <pattern>\.txt</pattern> 128 * <pattern>\.foo</pattern> 129 * </patterns> 130 * </filter> 131 * </testSchemaSourceExcludeFilters> 132 * </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 }