View Javadoc

1   package org.apache.maven.plugin.ear;
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.Artifact;
23  import org.apache.maven.plugin.MojoFailureException;
24  import org.apache.maven.plugin.ear.util.ArtifactRepository;
25  import org.codehaus.plexus.util.xml.XMLWriter;
26  
27  import java.util.Set;
28  
29  /**
30   * A base implementation of an {@link EarModule}.
31   * 
32   * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
33   * @version $Id: AbstractEarModule.java 1542508 2013-11-16 13:21:35Z rfscholte $
34   */
35  public abstract class AbstractEarModule
36      implements EarModule
37  {
38  
39      protected static final String MODULE_ELEMENT = "module";
40  
41      protected static final String JAVA_MODULE = "java";
42  
43      protected static final String ALT_DD = "alt-dd";
44  
45      private Artifact artifact;
46  
47      // Those are set by the configuration
48  
49      private String groupId;
50  
51      private String artifactId;
52  
53      private String classifier;
54  
55      protected String bundleDir;
56  
57      protected String bundleFileName;
58  
59      protected Boolean excluded = Boolean.FALSE;
60  
61      private String uri;
62  
63      protected Boolean unpack = null;
64  
65      protected String altDeploymentDescriptor;
66  
67      private String moduleId;
68  
69      // This is injected once the module has been built.
70  
71      protected EarExecutionContext earExecutionContext;
72  
73      /**
74       * Empty constructor to be used when the module is built based on the configuration.
75       */
76      public AbstractEarModule()
77      {
78      }
79  
80      /**
81       * Creates an ear module from the artifact.
82       * 
83       * @param a the artifact
84       */
85      public AbstractEarModule( Artifact a )
86      {
87          this.artifact = a;
88          this.groupId = a.getGroupId();
89          this.artifactId = a.getArtifactId();
90          this.classifier = a.getClassifier();
91          this.bundleDir = null;
92      }
93  
94      public void setEarExecutionContext( EarExecutionContext earExecutionContext )
95      {
96          this.earExecutionContext = earExecutionContext;
97      }
98  
99      /** {@inheritDoc} */
100     public void resolveArtifact( Set<Artifact> artifacts )
101         throws EarPluginException, MojoFailureException
102     {
103         // If the artifact is already set no need to resolve it
104         if ( artifact == null )
105         {
106             // Make sure that at least the groupId and the artifactId are specified
107             if ( groupId == null || artifactId == null )
108             {
109                 throw new MojoFailureException( "Could not resolve artifact[" + groupId + ":" + artifactId + ":"
110                     + getType() + "]" );
111             }
112             final ArtifactRepository ar = earExecutionContext.getArtifactRepository();
113             artifact = ar.getUniqueArtifact( groupId, artifactId, getType(), classifier );
114             // Artifact has not been found
115             if ( artifact == null )
116             {
117                 Set<Artifact> candidates = ar.getArtifacts( groupId, artifactId, getType() );
118                 if ( candidates.size() > 1 )
119                 {
120                     throw new MojoFailureException( "Artifact[" + this + "] has " + candidates.size()
121                         + " candidates, please provide a classifier." );
122                 }
123                 else
124                 {
125                     throw new MojoFailureException( "Artifact[" + this + "] is not a dependency of the project." );
126                 }
127             }
128         }
129     }
130 
131     public Artifact getArtifact()
132     {
133         return artifact;
134     }
135 
136     public String getModuleId()
137     {
138         return moduleId;
139     }
140 
141     public String getUri()
142     {
143         if ( uri == null )
144         {
145             if ( getBundleDir() == null )
146             {
147                 uri = getBundleFileName();
148             }
149             else
150             {
151                 uri = getBundleDir() + getBundleFileName();
152             }
153         }
154         return uri;
155     }
156 
157     /**
158      * Returns the artifact's groupId.
159      * 
160      * @return the group Id
161      */
162     public String getGroupId()
163     {
164         return groupId;
165     }
166 
167     /**
168      * Returns the artifact's Id.
169      * 
170      * @return the artifact Id
171      */
172     public String getArtifactId()
173     {
174         return artifactId;
175     }
176 
177     /**
178      * Returns the artifact's classifier.
179      * 
180      * @return the artifact classifier
181      */
182     public String getClassifier()
183     {
184         return classifier;
185     }
186 
187     /**
188      * Returns the bundle directory. If null, the module is bundled in the root of the EAR.
189      * 
190      * @return the custom bundle directory
191      */
192     public String getBundleDir()
193     {
194         if ( bundleDir != null )
195         {
196             bundleDir = cleanBundleDir( bundleDir );
197         }
198         return bundleDir;
199     }
200 
201     /**
202      * Returns the bundle file name. If null, the artifact's file name is returned.
203      * 
204      * @return the bundle file name
205      */
206     public String getBundleFileName()
207     {
208         if ( bundleFileName == null )
209         {
210             bundleFileName = earExecutionContext.getFileNameMapping().mapFileName( artifact );
211         }
212         return bundleFileName;
213     }
214 
215     /**
216      * The alt-dd element specifies an optional URI to the post-assembly version of the deployment descriptor file for a
217      * particular Java EE module. The URI must specify the full pathname of the deployment descriptor file relative to
218      * the application's root directory.
219      * 
220      * @return the alternative deployment descriptor for this module
221      */
222     public String getAltDeploymentDescriptor()
223     {
224         return altDeploymentDescriptor;
225     }
226 
227     /**
228      * Specify whether this module should be excluded or not.
229      * 
230      * @return true if this module should be skipped, false otherwise
231      */
232     public boolean isExcluded()
233     {
234         return excluded;
235     }
236 
237     public Boolean shouldUnpack()
238     {
239         return unpack;
240     }
241 
242     /**
243      * Writes the alternative deployment descriptor if necessary.
244      * 
245      * @param writer the writer to use
246      * @param version the java EE version in use
247      */
248     protected void writeAltDeploymentDescriptor( XMLWriter writer, String version )
249     {
250         if ( getAltDeploymentDescriptor() != null )
251         {
252             writer.startElement( ALT_DD );
253             writer.writeText( getAltDeploymentDescriptor() );
254             writer.endElement();
255         }
256     }
257 
258     /**
259      * Starts a new {@link #MODULE_ELEMENT} on the specified writer, possibly including an id attribute.
260      * 
261      * @param writer the XML writer.
262      * @param generateId whether an id should be generated
263      */
264     protected void startModuleElement( XMLWriter writer, Boolean generateId )
265     {
266         writer.startElement( MODULE_ELEMENT );
267 
268         // If a moduleId is specified, always include it
269         if ( getModuleId() != null )
270         {
271             writer.addAttribute( "id", getModuleId() );
272         }
273         else if ( generateId )
274         {
275             // No module id was specified but one should be generated.
276             Artifact artifact = getArtifact();
277             String generatedId =
278                 artifact.getType().toUpperCase() + "_" + artifact.getGroupId() + "." + artifact.getArtifactId();
279             if ( null != artifact.getClassifier() && artifact.getClassifier().trim().length() > 0 )
280             {
281                 generatedId += "-" + artifact.getClassifier().trim();
282             }
283             writer.addAttribute( "id", generatedId );
284         }
285     }
286 
287     public String toString()
288     {
289         StringBuilder sb = new StringBuilder();
290         sb.append( getType() ).append( ":" ).append( groupId ).append( ":" ).append( artifactId );
291         if ( classifier != null )
292         {
293             sb.append( ":" ).append( classifier );
294         }
295         if ( artifact != null )
296         {
297             sb.append( ":" ).append( artifact.getVersion() );
298         }
299         return sb.toString();
300     }
301 
302     /**
303      * Cleans the bundle directory so that it might be used properly.
304      * 
305      * @param bundleDir the bundle directory to clean
306      * @return the cleaned bundle directory
307      */
308     static String cleanBundleDir( String bundleDir )
309     {
310         if ( bundleDir == null )
311         {
312             return null;
313         }
314 
315         // Using slashes
316         bundleDir = bundleDir.replace( '\\', '/' );
317 
318         // Remove '/' prefix if any so that directory is a relative path
319         if ( bundleDir.startsWith( "/" ) )
320         {
321             bundleDir = bundleDir.substring( 1, bundleDir.length() );
322         }
323 
324         if ( bundleDir.length() > 0 && !bundleDir.endsWith( "/" ) )
325         {
326             // Adding '/' suffix to specify a directory structure if it is not empty
327             bundleDir = bundleDir + "/";
328         }
329 
330         return bundleDir;
331     }
332 
333     /**
334      * Specify if the objects are both null or both equal.
335      * 
336      * @param first the first object
337      * @param second the second object
338      * @return true if parameters are either both null or equal
339      */
340     static boolean areNullOrEqual( Object first, Object second )
341     {
342         if ( first != null )
343         {
344             return first.equals( second );
345         }
346         else
347         {
348             return second == null;
349         }
350     }
351 
352     /**
353      * Sets the URI of the module explicitly for testing purposes.
354      * 
355      * @param uri the uri
356      */
357     void setUri( String uri )
358     {
359         this.uri = uri;
360 
361     }
362 
363     public boolean changeManifestClasspath()
364     {
365         return true;
366     }
367 
368     public String getLibDir()
369     {
370         return null;
371     }
372 }