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