001    package org.apache.maven.plugin.plugin;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.maven.artifact.ArtifactUtils;
023    import org.apache.maven.plugin.AbstractMojo;
024    import org.apache.maven.plugin.MojoExecutionException;
025    import org.apache.maven.plugin.MojoFailureException;
026    import org.apache.maven.plugin.registry.MavenPluginRegistryBuilder;
027    import org.apache.maven.plugin.registry.Plugin;
028    import org.apache.maven.plugin.registry.PluginRegistry;
029    import org.apache.maven.plugin.registry.PluginRegistryUtils;
030    import org.apache.maven.plugin.registry.TrackableBase;
031    import org.apache.maven.plugin.registry.io.xpp3.PluginRegistryXpp3Writer;
032    import org.codehaus.plexus.util.IOUtil;
033    import org.codehaus.plexus.util.WriterFactory;
034    import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
035    
036    import java.io.File;
037    import java.io.IOException;
038    import java.io.Writer;
039    import java.text.SimpleDateFormat;
040    import java.util.Date;
041    
042    /**
043     * Update the user plugin registry (if it's in use) to reflect the version we're installing.
044     *
045     * @version $Id: UpdatePluginRegistryMojo.java 1133737 2011-06-09 09:20:50Z stephenc $
046     * @since 2.0
047     * @goal updateRegistry
048     * @phase install
049     */
050    public class UpdatePluginRegistryMojo
051        extends AbstractMojo
052    {
053        /**
054         * Indicates whether the <code>plugin-registry.xml</code> file is used by Maven or not
055         * to manage plugin versions.
056         *
057         * @parameter default-value="${settings.usePluginRegistry}"
058         * @required
059         * @readonly
060         */
061        private boolean usePluginRegistry;
062    
063        /**
064         * The group id of the project currently being built.
065         *
066         * @parameter default-value="${project.groupId}"
067         * @required
068         * @readonly
069         */
070        private String groupId;
071    
072        /**
073         * The artifact id of the project currently being built.
074         *
075         * @parameter default-value="${project.artifactId}"
076         * @required
077         * @readonly
078         */
079        private String artifactId;
080    
081        /**
082         * The version of the project currently being built.
083         *
084         * @parameter default-value="${project.artifact.version}"
085         * @required
086         * @readonly
087         */
088        private String version;
089    
090        /**
091         * Plexus component for retrieving the plugin registry info.
092         *
093         * @component role="org.apache.maven.plugin.registry.MavenPluginRegistryBuilder"
094         */
095        private MavenPluginRegistryBuilder pluginRegistryBuilder;
096    
097        /**
098         * Set this to "true" to skip invoking any goals or reports of the plugin.
099         *
100         * @parameter default-value="false" expression="${maven.plugin.skip}"
101         * @since 2.8
102         */
103        private boolean skip;
104    
105        /**
106         * Set this to "true" to skip updating the plugin registry.
107         *
108         * @parameter default-value="false" expression="${maven.plugin.update.registry.skip}"
109         * @since 2.8
110         */
111        private boolean skipUpdatePluginRegistry;
112    
113        /** {@inheritDoc} */
114        public void execute()
115            throws MojoExecutionException, MojoFailureException
116        {
117            if ( usePluginRegistry )
118            {
119                if ( skip || skipUpdatePluginRegistry )
120                {
121                    getLog().warn( "Execution skipped" );
122                    return;
123                }
124                updatePluginVersionInRegistry( groupId, artifactId, version );
125            }
126        }
127    
128        /**
129         * @param aGroupId not null
130         * @param anArtifactId not null
131         * @param aVersion not null
132         * @throws MojoExecutionException if any
133         */
134        private void updatePluginVersionInRegistry( String aGroupId, String anArtifactId, String aVersion )
135            throws MojoExecutionException
136        {
137            PluginRegistry pluginRegistry;
138            try
139            {
140                pluginRegistry = getPluginRegistry( aGroupId, anArtifactId );
141            }
142            catch ( IOException e )
143            {
144                throw new MojoExecutionException( "Failed to read plugin registry.", e );
145            }
146            catch ( XmlPullParserException e )
147            {
148                throw new MojoExecutionException( "Failed to parse plugin registry.", e );
149            }
150    
151            String pluginKey = ArtifactUtils.versionlessKey( aGroupId, anArtifactId );
152            Plugin plugin = (Plugin) pluginRegistry.getPluginsByKey().get( pluginKey );
153    
154            // if we can find the plugin, but we've gotten here, the useVersion must be missing; fill it in.
155            if ( plugin != null )
156            {
157                if ( TrackableBase.GLOBAL_LEVEL.equals( plugin.getSourceLevel() ) )
158                {
159                    // do nothing. We don't rewrite the globals, under any circumstances.
160                    getLog().warn( "Cannot update registered version for plugin {" + aGroupId + ":" + anArtifactId
161                        + "}; it is specified in the global registry." );
162                }
163                else
164                {
165                    plugin.setUseVersion( aVersion );
166    
167                    SimpleDateFormat format =
168                        new SimpleDateFormat( org.apache.maven.plugin.registry.Plugin.LAST_CHECKED_DATE_FORMAT );
169    
170                    plugin.setLastChecked( format.format( new Date() ) );
171                }
172            }
173            else
174            {
175                plugin = new org.apache.maven.plugin.registry.Plugin();
176    
177                plugin.setGroupId( aGroupId );
178                plugin.setArtifactId( anArtifactId );
179                plugin.setUseVersion( aVersion );
180    
181                pluginRegistry.addPlugin( plugin );
182    
183                pluginRegistry.flushPluginsByKey();
184            }
185    
186            writeUserRegistry( aGroupId, anArtifactId, pluginRegistry );
187        }
188    
189        /**
190         * @param aGroupId not null
191         * @param anArtifactId not null
192         * @param pluginRegistry not null
193         */
194        private void writeUserRegistry( String aGroupId, String anArtifactId, PluginRegistry pluginRegistry )
195        {
196            File pluginRegistryFile = pluginRegistry.getRuntimeInfo().getFile();
197    
198            PluginRegistry extractedUserRegistry = PluginRegistryUtils.extractUserPluginRegistry( pluginRegistry );
199    
200            // only rewrite the user-level registry if one existed before, or if we've created user-level data here.
201            if ( extractedUserRegistry != null )
202            {
203                Writer fWriter = null;
204    
205                try
206                {
207                    pluginRegistryFile.getParentFile().mkdirs();
208                    fWriter = WriterFactory.newXmlWriter( pluginRegistryFile );
209    
210                    PluginRegistryXpp3Writer writer = new PluginRegistryXpp3Writer();
211    
212                    writer.write( fWriter, extractedUserRegistry );
213                }
214                catch ( IOException e )
215                {
216                    getLog().warn( "Cannot rewrite user-level plugin-registry.xml with new plugin version of plugin: \'"
217                        + aGroupId + ":" + anArtifactId + "\'.", e );
218                }
219                finally
220                {
221                    IOUtil.close( fWriter );
222                }
223            }
224        }
225    
226        /**
227         * @param aGroupId not null
228         * @param anArtifactId not null
229         * @return the plugin registry instance
230         * @throws IOException if any
231         * @throws XmlPullParserException if any
232         */
233        private PluginRegistry getPluginRegistry( String aGroupId, String anArtifactId )
234            throws IOException, XmlPullParserException
235        {
236            PluginRegistry pluginRegistry = null;
237    
238            pluginRegistry = pluginRegistryBuilder.buildPluginRegistry();
239    
240            if ( pluginRegistry == null )
241            {
242                pluginRegistry = pluginRegistryBuilder.createUserPluginRegistry();
243            }
244    
245            return pluginRegistry;
246        }
247    }