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