View Javadoc

1   package org.apache.maven.plugins.site;
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.model.Site;
23  import org.apache.maven.plugin.MojoExecutionException;
24  import org.apache.maven.plugin.MojoFailureException;
25  import org.apache.maven.project.MavenProject;
26  import org.apache.maven.plugins.site.wagon.repository.Repository;
27  import org.codehaus.plexus.util.PathTool;
28  import org.codehaus.plexus.util.StringUtils;
29  
30  import java.io.File;
31  import java.util.Iterator;
32  import java.util.List;
33  
34  /**
35   * Generates a site in a local staging or mock directory based on the site URL
36   * specified in the <code>&lt;distributionManagement&gt;</code> section of the
37   * POM.
38   * <p>
39   * It can be used to test that links between module sites in a multi module
40   * build works.
41   * </p>
42   *
43   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
44   * @version $Id: SiteStageMojo.html 816554 2012-05-08 11:56:34Z hboutemy $
45   * @goal stage
46   * @requiresDependencyResolution test
47   */
48  public class SiteStageMojo
49      extends SiteMojo
50  {
51      protected static final String DEFAULT_STAGING_DIRECTORY = "staging";
52  
53      /**
54       * Staging directory location. This needs to be an absolute path, like
55       * <code>C:\stagingArea\myProject\</code> on Windows or
56       * <code>/stagingArea/myProject/</code> on Unix.
57       *
58       * @parameter expression="${stagingDirectory}"
59       */
60      protected File stagingDirectory;
61  
62      /**
63       * @see org.apache.maven.plugin.Mojo#execute()
64       */
65      public void execute()
66          throws MojoExecutionException, MojoFailureException
67      {
68          String structureProject = getStructure( project, false );
69  
70          if ( structureProject == null )
71          {
72              throw new MojoExecutionException( "Missing site information." );
73          }
74  
75          stagingDirectory = getStagingDirectory( project, reactorProjects, stagingDirectory );
76          getLog().info( "Using this directory for staging: " + stagingDirectory );
77  
78          outputDirectory = new File( stagingDirectory, structureProject );
79  
80          // Safety
81          if ( !outputDirectory.exists() )
82          {
83              outputDirectory.mkdirs();
84          }
85  
86          String outputRelativePath = PathTool.getRelativePath( stagingDirectory.getAbsolutePath(), new File(
87              outputDirectory, "dummy.html" ).getAbsolutePath() );
88          project.setUrl( outputRelativePath + "/" + structureProject );
89  
90          MavenProject parent = siteTool.getParentProject( project, reactorProjects, localRepository );
91          if ( parent != null )
92          {
93              String structureParentProject = getStructure( parent, true );
94              if ( structureParentProject != null )
95              {
96                  parent.setUrl( outputRelativePath + "/" + structureParentProject );
97              }
98          }
99  
100         if ( reactorProjects != null && reactorProjects.size() > 1 )
101         {
102             Iterator reactorItr = reactorProjects.iterator();
103 
104             while ( reactorItr.hasNext() )
105             {
106                 MavenProject reactorProject = (MavenProject) reactorItr.next();
107 
108                 if ( reactorProject != null && reactorProject.getParent() != null
109                     && project.getArtifactId().equals( reactorProject.getParent().getArtifactId() ) )
110                 {
111                     String structureReactorProject = getStructure( reactorProject, false );
112                     reactorProject.setUrl( outputRelativePath + "/" + structureReactorProject );
113                 }
114             }
115         }
116 
117         super.execute();
118     }
119 
120     /**
121      * Find the directory where staging will take place.
122      *
123      * @param currentProject        The currently executing project
124      * @param reactorProjects       The projects in the reactor
125      * @param usersStagingDirectory The staging directory as suggested by the user's configuration
126      * @return the directory for staging
127      */
128     protected File getStagingDirectory( MavenProject currentProject, List reactorProjects, File usersStagingDirectory )
129     {
130         // Check if the user has specified a stagingDirectory
131         if ( usersStagingDirectory != null )
132         {
133             getLog().debug( "stagingDirectory specified by the user." );
134             return usersStagingDirectory;
135         }
136         getLog().debug( "stagingDirectory NOT specified by the user." );
137 
138         // Find the top level project in the reactor
139         MavenProject topLevelProject = getTopLevelProject( reactorProjects );
140 
141         // Use the top level project's build directory if there is one, otherwise use this project's build directory
142         File buildDirectory;
143         if ( topLevelProject == null )
144         {
145             getLog().debug( "No top level project found in the reactor, using the current project." );
146             buildDirectory = new File( currentProject.getBuild().getDirectory() );
147         }
148         else
149         {
150             getLog().debug( "Using the top level project found in the reactor." );
151             buildDirectory = new File( topLevelProject.getBuild().getDirectory() );
152         }
153 
154         return new File( buildDirectory, DEFAULT_STAGING_DIRECTORY );
155     }
156 
157     /**
158      * Find the top level parent in the reactor, i.e. the execution root.
159      *
160      * @param reactorProjects The projects in the reactor
161      * @return The top level project in the reactor, or <code>null</code> if none can be found
162      */
163     protected MavenProject getTopLevelProject( List reactorProjects )
164     {
165         MavenProject topLevelProject = null;
166         if ( reactorProjects != null )
167         {
168             Iterator iterator = reactorProjects.iterator();
169             while ( iterator.hasNext() )
170             {
171                 MavenProject reactorProject = (MavenProject) iterator.next();
172                 if ( reactorProject.isExecutionRoot() )
173                 {
174                     topLevelProject = reactorProject;
175                 }
176             }
177         }
178         return topLevelProject;
179     }
180 
181     /**
182      * Generates the site structure using the project hiearchy (project and its modules) or using the
183      * distributionManagement elements from the pom.xml.
184      *
185      * @param project
186      * @param ignoreMissingSiteUrl
187      * @return the structure relative path
188      * @throws MojoFailureException if any
189      */
190     protected static String getStructure( MavenProject project, boolean ignoreMissingSiteUrl )
191         throws MojoFailureException
192     {
193         if ( project.getDistributionManagement() == null )
194         {
195             String hierarchy = project.getArtifactId();
196 
197             MavenProject parent = project.getParent();
198             while ( parent != null )
199             {
200                 hierarchy = parent.getArtifactId() + "/" + hierarchy;
201                 parent = parent.getParent();
202             }
203 
204             return hierarchy;
205         }
206 
207         Site site = project.getDistributionManagement().getSite();
208         if ( site == null )
209         {
210             if ( !ignoreMissingSiteUrl )
211             {
212                 throw new MojoFailureException(
213                     "Missing site information in the distribution management element in the project: '"
214                     + project.getName() + "'." );
215             }
216 
217             return null;
218         }
219 
220         if ( StringUtils.isEmpty( site.getUrl() ) )
221         {
222             if ( !ignoreMissingSiteUrl )
223             {
224                 throw new MojoFailureException( "The URL in the site is missing in the project descriptor." );
225             }
226 
227             return null;
228         }
229 
230         Repository repository = new Repository( site.getId(), site.getUrl() );
231         StringBuffer hierarchy = new StringBuffer( 1024 );
232         hierarchy.append( repository.getHost() );
233         if ( !StringUtils.isEmpty( repository.getBasedir() ) )
234         {
235             if ( !repository.getBasedir().startsWith( "/" ) )
236             {
237                 hierarchy.append( '/' );
238             }
239             hierarchy.append( repository.getBasedir() );
240         }
241 
242         return hierarchy.toString().replaceAll( "[\\:\\?\\*]", "" );
243     }
244 }