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