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ö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 * <configuration> 119 * ... 120 * <sources> 121 * <source>some/explicit/relative/file.xsd</source> 122 * <source>/another/absolute/path/to/a/specification.xsd</source> 123 * <source>a/directory/holding/xsds</source> 124 * </sources> 125 * </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 * <configuration> 143 * ... 144 * <xjbSources> 145 * <xjbSource>bindings/aBindingConfiguration.xjb</xjbSource> 146 * <xjbSource>bindings/config/directory</xjbSource> 147 * </xjbSources> 148 * </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 * <configuration> 176 * ... 177 * <xjcSourceExcludeFilters> 178 * <filter implementation="org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter"> 179 * <patterns> 180 * <pattern>\.txt</pattern> 181 * <pattern>\.foo</pattern> 182 * </patterns> 183 * </filter> 184 * </xjcSourceExcludeFilters> 185 * </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 * <configuration> 211 * ... 212 * <xjbExcludeFilters> 213 * <filter implementation="org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter"> 214 * <patterns> 215 * <pattern>\.txt</pattern> 216 * <pattern>\.foo</pattern> 217 * </patterns> 218 * </filter> 219 * </xjbExcludeFilters> 220 * ... 221 * </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 }