View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.resources.remote;
20  
21  import java.io.File;
22  import java.io.FileWriter;
23  import java.io.IOException;
24  import java.io.Writer;
25  import java.util.Arrays;
26  import java.util.List;
27  
28  import org.apache.maven.plugin.AbstractMojo;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.resources.remote.io.xpp3.RemoteResourcesBundleXpp3Writer;
31  import org.apache.maven.plugins.annotations.LifecyclePhase;
32  import org.apache.maven.plugins.annotations.Mojo;
33  import org.apache.maven.plugins.annotations.Parameter;
34  import org.codehaus.plexus.util.DirectoryScanner;
35  import org.codehaus.plexus.util.FileUtils;
36  import org.codehaus.plexus.util.ReaderFactory;
37  import org.codehaus.plexus.util.StringUtils;
38  
39  /**
40   * Bundle up resources that should be considered as a remote-resource,
41   * generating <code>META-INF/maven/remote-resources.xml</code> descriptor.
42   */
43  @Mojo(name = "bundle", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, threadSafe = true)
44  public class BundleRemoteResourcesMojo extends AbstractMojo {
45      public static final String RESOURCES_MANIFEST = "META-INF/maven/remote-resources.xml";
46  
47      private static final String[] DEFAULT_INCLUDES = new String[] {
48          "**/*.txt", "**/*.vm",
49      };
50  
51      /**
52       * The directory which contains the resources you want packaged up in this resource bundle.
53       */
54      @Parameter(defaultValue = "${basedir}/src/main/resources")
55      private File resourcesDirectory;
56  
57      /**
58       * The directory where you want the resource bundle manifest written to.
59       */
60      @Parameter(defaultValue = "${project.build.outputDirectory}", required = true)
61      private File outputDirectory;
62  
63      /**
64       * A list of files to include. Can contain ant-style wildcards and double wildcards.
65       * The default includes are
66       * <code>**&#47;*.txt   **&#47;*.vm</code>
67       *
68       * @since 1.0-alpha-5
69       */
70      @Parameter
71      private String[] includes;
72  
73      /**
74       * A list of files to exclude. Can contain ant-style wildcards and double wildcards.
75       *
76       * @since 1.0-alpha-5
77       */
78      @Parameter
79      private String[] excludes;
80  
81      /**
82       * Encoding of the bundle.
83       *
84       * @since 1.1
85       */
86      @Parameter(defaultValue = "${project.build.sourceEncoding}")
87      private String sourceEncoding;
88  
89      @Override
90      public void execute() throws MojoExecutionException {
91          if (!resourcesDirectory.exists()) {
92              getLog().info("skip non existing resourceDirectory " + resourcesDirectory.getAbsolutePath());
93              return;
94          }
95  
96          if (sourceEncoding == null || sourceEncoding.isEmpty()) {
97              getLog().warn("sourceEncoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
98                      + ", i.e. build is platform dependent!");
99              sourceEncoding = ReaderFactory.FILE_ENCODING;
100         }
101 
102         // Look at the content of the resourcesDirectory and create a manifest of the files
103         // so that velocity can easily process any resources inside the JAR that need to be processed.
104 
105         RemoteResourcesBundle remoteResourcesBundle = new RemoteResourcesBundle();
106         remoteResourcesBundle.setSourceEncoding(sourceEncoding);
107 
108         DirectoryScanner scanner = new DirectoryScanner();
109 
110         scanner.setBasedir(resourcesDirectory);
111         if (includes != null && includes.length != 0) {
112             scanner.setIncludes(includes);
113         } else {
114             scanner.setIncludes(DEFAULT_INCLUDES);
115         }
116 
117         if (excludes != null && excludes.length != 0) {
118             scanner.setExcludes(excludes);
119         }
120 
121         scanner.addDefaultExcludes();
122         scanner.scan();
123 
124         List<String> includedFiles = Arrays.asList(scanner.getIncludedFiles());
125 
126         for (String resource : includedFiles) {
127             remoteResourcesBundle.addRemoteResource(StringUtils.replace(resource, '\\', '/'));
128         }
129 
130         int n = remoteResourcesBundle.getRemoteResources().size();
131         getLog().info("Writing " + RESOURCES_MANIFEST + " descriptor with " + n + " entr" + ((n > 1) ? "ies" : "y"));
132 
133         RemoteResourcesBundleXpp3Writer w = new RemoteResourcesBundleXpp3Writer();
134 
135         File f = new File(outputDirectory, RESOURCES_MANIFEST);
136 
137         FileUtils.mkdir(f.getParentFile().getAbsolutePath());
138 
139         try (Writer writer = new FileWriter(f)) {
140             w.write(writer, remoteResourcesBundle);
141         } catch (IOException e) {
142             throw new MojoExecutionException("Error creating remote resources manifest.", e);
143         }
144     }
145 }