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