PageRenderTime 31ms CodeModel.GetById 22ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/maven-site-plugin/src/main/java/org/apache/maven/plugins/site/SiteStageDeployMojo.java

https://github.com/SciSysUK/maven-plugins
Java | 276 lines | 136 code | 33 blank | 107 comment | 22 complexity | 2e578605f66575ece028f62ce5f6e95f MD5 | raw file
  1package 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
 23import java.util.Map;
 24import org.apache.commons.lang.StringUtils;
 25import org.apache.maven.model.Build;
 26import org.apache.maven.model.Plugin;
 27import org.apache.maven.model.PluginManagement;
 28import org.apache.maven.model.Site;
 29import org.apache.maven.plugin.MojoExecutionException;
 30import org.apache.maven.project.MavenProject;
 31import org.codehaus.plexus.util.xml.Xpp3Dom;
 32
 33/**
 34 * Deploys the generated site to a staging or mock directory to the site URL
 35 * specified in the <code>&lt;distributionManagement&gt;</code> section of the
 36 * POM. It supports <code>scp</code> and <code>file</code> protocols for
 37 * deployment.
 38 *
 39 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 40 * @version $Id$
 41 * @goal stage-deploy
 42 * @requiresDependencyResolution test
 43 */
 44public class SiteStageDeployMojo
 45    extends AbstractDeployMojo
 46{
 47    /**
 48     * The staged site will be deployed to this URL.
 49     *
 50     * If you don't specify this, the default-value will be
 51     * "${project.distributionManagement.site.url}/staging", where "project" is
 52     * either the current project or, in a reactor build, the top level project
 53     * in the reactor.
 54     * <p>
 55     * Note that even if you specify this plugin parameter you still need to indicate
 56     * ${project.distributionManagement.site.url} at least in your top level project
 57     * in order for relative links between modules to be resolved correctly.
 58     * </p>
 59     *
 60     * @parameter expression="${stagingSiteURL}"
 61     * @see <a href="http://maven.apache.org/maven-model/maven.html#class_site">MavenModel#class_site</a>
 62     */
 63    private String stagingSiteURL;
 64
 65    /**
 66     * The identifier of the repository where the staging site will be deployed. This id will be used to lookup a
 67     * corresponding <code>&lt;server&gt;</code> entry from the <code>settings.xml</code>. If a matching
 68     * <code>&lt;server&gt;</code> entry is found, its configured credentials will be used for authentication.
 69     *
 70     * If this is not specified, then the corresponding value of <code>distributionManagement.site.id</code>
 71     * will be taken as default, unless this is not defined either then the String
 72     * <code>"stagingSite"</code> is used. (<strong>Note</strong>:
 73     * until v. 2.3 and 3.0-beta-3 the String <code>"stagingSite"</code> is always used.)
 74     *
 75     * @parameter expression="${stagingRepositoryId}"
 76     *
 77     * @since 2.0.1
 78     */
 79    private String stagingRepositoryId;
 80
 81    @Override
 82    /**
 83     * Find the relative path between the distribution URLs of the parent that
 84     * supplied the staging deploy URL and the current project.
 85     *
 86     * @return the relative path or "./" if the two URLs are the same.
 87     *
 88     * @throws MojoExecutionException
 89     */
 90    protected String getDeployModuleDirectory()
 91        throws MojoExecutionException
 92    {
 93        // MSITE-602: If the user specified an explicit stagingSiteURL, use a special relative path
 94        if( StringUtils.isNotEmpty( stagingSiteURL ) )
 95        {
 96            // We need to calculate the relative path between this project and
 97            // the first one that supplied a stagingSiteURL
 98            String relative = siteTool.getRelativePath( getSite( project ).getUrl(),
 99                getSiteForTopMostParentWithStagingSiteURL( project ).getUrl() );
100
101            // SiteTool.getRelativePath() uses File.separatorChar,
102            // so we need to convert '\' to '/' in order for the URL to be valid for Windows users
103            relative = relative.replace( '\\', '/' );
104
105            getLog().debug( "The stagingSiteURL is configured, using special way to calculate relative path." );
106            return ( "".equals( relative ) ) ? "./" : relative;
107        }
108        else
109        {
110            getLog().debug( "No stagingSiteURL is configured, using standard way to calculate relative path." );
111            return super.getDeployModuleDirectory();
112        }
113    }
114
115    @Override
116    protected String getDeployRepositoryID()
117        throws MojoExecutionException
118    {
119        stagingRepositoryId =  stagingRepoId ( stagingRepositoryId );
120
121        getLog().info( "Using this server ID for stage deploy: " + stagingRepositoryId );
122
123        return stagingRepositoryId;
124    }
125
126    @Override
127    protected String getDeployRepositoryURL()
128        throws MojoExecutionException
129    {
130        String stagingURL = determineStagingSiteURL( stagingSiteURL );
131
132        getLog().info( "Using this base URL for stage deploy: " + stagingURL );
133
134        return stagingURL;
135    }
136
137    /**
138     * Extract the distributionManagement.site of the top most project in the
139     * hierarchy that specifies a stagingSiteURL, starting at the given
140     * MavenProject.
141     * <p/>
142     * This climbs up the project hierarchy and returns the site of the top most
143     * project for which
144     * {@link #getStagingSiteURL(org.apache.maven.project.MavenProject)} returns
145     * a URL.
146     *
147     * @param project the MavenProject. Not null.
148     * @return the site for the top most project that has a stagingSiteURL. Not null.
149     */
150    private Site getSiteForTopMostParentWithStagingSiteURL( MavenProject project )
151    {
152        Site site = project.getDistributionManagement().getSite();
153
154        MavenProject parent = project;
155
156        // @todo Should we check that the stagingSiteURL equals the one in this project instead of being non-empty?
157        while ( parent != null
158                && StringUtils.isNotEmpty( getStagingSiteURL( parent ) ) )
159        {
160            site = parent.getDistributionManagement().getSite();
161
162            // MSITE-585, MNG-1943
163            parent = siteTool.getParentProject( parent, reactorProjects, localRepository );
164        }
165
166        return site;
167    }
168
169    /**
170     * Extract the value of the stagingSiteURL configuration parameter of
171     * maven-site-plugin for the given project.
172     *
173     * @param project The MavenProject, not null
174     * @return The stagingSiteURL for the project, or null if it doesn't have one
175     */
176    private String getStagingSiteURL( MavenProject project )
177    {
178        final String sitePluginKey = "org.apache.maven.plugins:maven-site-plugin";
179
180        if ( project == null )
181        {
182            return null;
183        }
184
185        final Build build = project.getBuild();
186        if ( build == null )
187        {
188            return null;
189        }
190
191        Map<String, Plugin> plugins = build.getPluginsAsMap();
192
193        Plugin sitePlugin = plugins.get( sitePluginKey );
194        if ( sitePlugin == null ) {
195            final PluginManagement buildPluginManagement = build.getPluginManagement();
196            if ( buildPluginManagement == null )
197            {
198                return null;
199            }
200
201            plugins = buildPluginManagement.getPluginsAsMap();
202            sitePlugin = plugins.get( sitePluginKey );
203        }
204
205        if( sitePlugin == null )
206        {
207            return null;
208        }
209
210        final Xpp3Dom sitePluginConfiguration = (Xpp3Dom) sitePlugin.getConfiguration();
211        if ( sitePluginConfiguration == null )
212        {
213            return null;
214        }
215
216        final Xpp3Dom child = sitePluginConfiguration.getChild( "stagingSiteURL" );
217        if ( child == null )
218        {
219            return null;
220        }
221        else
222        {
223            return child.getValue();
224        }
225    }
226
227    /**
228     * Find the URL where staging will take place.
229     *
230     * @param usersStagingSiteURL The staging site URL as suggested by the user's configuration
231     * 
232     * @return the site URL for staging
233     */
234    private String determineStagingSiteURL( final String usersStagingSiteURL )
235        throws MojoExecutionException
236    {
237        String topLevelURL = null;
238
239        if ( usersStagingSiteURL != null )
240        {
241            // the user has specified a stagingSiteURL - use it
242            getLog().debug( "stagingSiteURL specified by the user: " + usersStagingSiteURL );
243            topLevelURL = usersStagingSiteURL;
244        }
245        else
246        {
247            // The user didn't specify a URL, use the top level site distribution URL and add "[/]staging/" to it
248            topLevelURL = appendSlash( getRootSite( project ).getUrl() )
249                + DEFAULT_STAGING_DIRECTORY;
250            getLog().debug( "stagingSiteURL NOT specified, using the top level project: " + topLevelURL );
251        }
252
253        // Return either
254        //   usersURL
255        // or
256        //   topLevelProjectURL + "staging"
257        return topLevelURL;
258    }
259
260    private String stagingRepoId( final String stagingRepoId )
261    {
262        if ( stagingRepoId != null )
263        {
264            return stagingRepoId;
265        }
266
267        try
268        {
269            return getSite( project ).getId();
270        }
271        catch ( MojoExecutionException ex )
272        {
273            return "stagingSite";
274        }
275    }
276}