View Javadoc
1   package org.apache.maven.plugin.assembly.utils;
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.project.MavenProject;
24  import org.codehaus.plexus.logging.Logger;
25  
26  import javax.annotation.Nonnull;
27  import javax.annotation.Nullable;
28  import java.io.File;
29  import java.io.IOException;
30  import java.util.Collections;
31  import java.util.Iterator;
32  import java.util.LinkedHashSet;
33  import java.util.List;
34  import java.util.Set;
35  
36  /**
37   * @version $Id: ProjectUtils.java 1517906 2013-08-27 18:25:03Z krosenvold $
38   */
39  public final class ProjectUtils
40  {
41  
42      private ProjectUtils()
43      {
44      }
45  
46      @Nullable
47      public static String getClassifier( @Nonnull Artifact artifact )
48      {
49          String classifier = artifact.getClassifier();
50          if ( classifier != null && classifier.length() == 0 )
51          {
52              classifier = null;
53          }
54          return classifier;
55      }
56  
57      @Nonnull public static Set<MavenProject> getProjectModules( @Nonnull final MavenProject project,
58                                                         @Nonnull final List<MavenProject> reactorProjects,
59                                                         final boolean includeSubModules, @Nonnull final Logger logger )
60          throws IOException
61      {
62          final Set<MavenProject> singleParentSet = Collections.singleton( project );
63  
64          final Set<MavenProject> moduleCandidates = new LinkedHashSet<MavenProject>( reactorProjects );
65  
66          final Set<MavenProject> modules = new LinkedHashSet<MavenProject>();
67  
68          // we temporarily add the master project to the modules set, since this
69          // set is pulling double duty as a set of
70          // potential module parents in the tree rooted at the master
71          // project...this allows us to use the same looping
72          // algorithm below to discover both direct modules of the master project
73          // AND modules of those direct modules.
74          modules.add( project );
75  
76          int changed;
77  
78          do
79          {
80              changed = 0;
81  
82              for ( final Iterator<MavenProject> candidateIterator = moduleCandidates.iterator(); candidateIterator.hasNext(); )
83              {
84                  final MavenProject moduleCandidate = candidateIterator.next();
85  
86                  if ( moduleCandidate.getFile() == null )
87                  {
88                      logger.warn( "Cannot compute whether " + moduleCandidate.getId() + " is a module of: "
89                                      + project.getId()
90                                      + "; it does not have an associated POM file on the local filesystem." );
91                      continue;
92                  }
93  
94                  Set<MavenProject> currentPotentialParents;
95                  if ( includeSubModules )
96                  {
97                      currentPotentialParents = new LinkedHashSet<MavenProject>( modules );
98                  }
99                  else
100                 {
101                     currentPotentialParents = singleParentSet;
102                 }
103 
104                 for ( final MavenProject potentialParent : currentPotentialParents )
105                 {
106                     if ( potentialParent.getFile() == null )
107                     {
108                         logger.warn( "Cannot use: " + moduleCandidate.getId()
109                                          + " as a potential module-parent while computing the module set for: "
110                                          + project.getId()
111                                          + "; it does not have an associated POM file on the local filesystem." );
112                         continue;
113                     }
114 
115                     // if this parent has an entry for the module candidate in
116                     // the path adjustments map, it's a direct
117                     // module of that parent.
118                     if ( projectContainsModule( potentialParent, moduleCandidate ) )
119                     {
120                         // add the candidate to the list of modules (and
121                         // potential parents)
122                         modules.add( moduleCandidate );
123 
124                         // remove the candidate from the candidate pool, because
125                         // it's been verified.
126                         candidateIterator.remove();
127 
128                         // increment the change counter, to show that we
129                         // verified a new module on this pass.
130                         changed++;
131                     }
132                 }
133             }
134         }
135         while ( changed != 0 );
136 
137         // remove the master project from the modules set, now that we're done
138         // using it as a set of potential module
139         // parents...
140         modules.remove( project );
141 
142         return modules;
143     }
144 
145     private static boolean projectContainsModule( @Nonnull final MavenProject mainProject,
146                                                   @Nonnull final MavenProject moduleProject )
147         throws IOException
148     {
149         @SuppressWarnings( "unchecked" )
150         final List<String> modules = mainProject.getModules();
151         final File basedir = mainProject.getBasedir();
152 
153         final File moduleFile = moduleProject.getFile()
154                                              .getCanonicalFile();
155 
156         File moduleBasedir = moduleProject.getBasedir();
157 
158         if ( moduleBasedir == null )
159         {
160             moduleBasedir = moduleFile.getParentFile();
161 
162             if ( moduleBasedir == null )
163             {
164                 moduleBasedir = new File( "." );
165             }
166         }
167 
168         moduleBasedir = moduleBasedir.getCanonicalFile();
169 
170         for ( final String moduleSubpath : modules )
171         {
172             final File moduleDir = new File( basedir, moduleSubpath ).getCanonicalFile();
173 
174             if ( moduleDir.equals( moduleFile ) || moduleDir.equals( moduleBasedir ) )
175             {
176                 return true;
177             }
178         }
179 
180         return false;
181     }
182 
183 }