Resolving issue: MNG-379

o Added support for update-all and update-none when prompting the user.

o Added --update-plugins/-F option to force an update of the plugins used in the project.

o Added autoUpdate setting for the plugin registry. This is used when in non-interactive mode, to determine whether to register plugin updates

o Added updateInterval to determine when/how often to check for updates to registered plugins. Supports three syntaxes:

  - 'never'
  - 'always'
  - 'interval:XXX' (where XXX can be a combination of weeks, days, hours, and minutes in the syntax: 1w1d1h1m)
         > this renders the interval syntax similar to 'interval:1w' to check every week.

  NOTE: update intervals are calculated from the time a particular plugin was last checked.

o Added lastChecked attribute for registered plugins, to use as a basis for calculating update-check interval

o Added RuntimeInfo classes for maven-settings and maven-plugin-registry, to help in tracking the file each instance comes from, in addition to merging info which is useful when extracting the user-level instance from the merged instance (for persisting changes to the user instance, f.e.).

o Changed verifyPlugin(..) to take an instance of Settings, to allow persistent decisions across the session (like update-all, update-none in the plugin version manager)

This should take care of outstanding issues with this new feature. I'm closing the JIRA issue now, and we'll deal with any bugs/shortcomings as separate issues.



git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@191021 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2005-06-16 22:38:57 +00:00
parent f749c3a5aa
commit a3cf96219f
18 changed files with 677 additions and 123 deletions

View File

@ -193,6 +193,11 @@ public class MavenCli
{
settings.setInteractiveMode( false );
}
if ( commandLine.hasOption( CLIManager.FORCE_PLUGIN_UPDATES ) )
{
settings.getRuntimeInfo().setPluginUpdateForced( true );
}
List projectFiles = null;
try
@ -494,6 +499,8 @@ public class MavenCli
public static final char UPDATE_SNAPSHOTS = 'U';
public static final char ACTIVATE_PROFILES = 'P';
public static final char FORCE_PLUGIN_UPDATES = 'F';
public CLIManager()
{
@ -521,6 +528,7 @@ public class MavenCli
options.addOption( OptionBuilder.withLongOpt( "activate-profiles" ).withDescription(
"Comma-delimited list of profiles to activate").hasArg().create( ACTIVATE_PROFILES ) );
options.addOption( OptionBuilder.withLongOpt( "batch-mode" ).withDescription( "Run in non-interactive (batch) mode" ).create( BATCH_MODE ) );
options.addOption( OptionBuilder.withLongOpt( "update-plugins" ).withDescription( "Force upToDate check for any relevant registered plugins" ).create( FORCE_PLUGIN_UPDATES ) );
}
public CommandLine parse( String[] args )

View File

@ -311,7 +311,7 @@ public class DefaultLifecycleExecutor
try
{
pluginDescriptor = pluginManager.verifyPlugin( groupId, artifactId, version, session.getProject(), session
.getLocalRepository(), session.getSettings().isInteractiveMode() );
.getSettings(), session.getLocalRepository() );
}
catch ( PluginManagerException e )
{
@ -579,8 +579,7 @@ public class DefaultLifecycleExecutor
injectHandlerPluginConfiguration( session.getProject(), groupId, artifactId, version );
pluginDescriptor = pluginManager.verifyPlugin( groupId, artifactId, version, session.getProject(),
session.getLocalRepository(), session.getSettings()
.isInteractiveMode() );
session.getSettings(), session.getLocalRepository() );
}
catch ( PluginManagerException e )
{

View File

@ -41,6 +41,7 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.artifact.MavenMetadataSource;
import org.apache.maven.project.path.PathTranslator;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.PlexusContainerException;
@ -177,7 +178,7 @@ public class DefaultPluginManager
}
public PluginDescriptor verifyPlugin( String groupId, String artifactId, String version, MavenProject project,
ArtifactRepository localRepository, boolean interactiveMode )
Settings settings, ArtifactRepository localRepository )
throws ArtifactResolutionException, PluginManagerException, PluginVersionResolutionException
{
String pluginKey = groupId + ":" + artifactId;
@ -192,8 +193,7 @@ public class DefaultPluginManager
{
pluginVersionManager = (PluginVersionManager) container.lookup( PluginVersionManager.ROLE );
version = pluginVersionManager.resolvePluginVersion( groupId, artifactId, project, localRepository,
interactiveMode );
version = pluginVersionManager.resolvePluginVersion( groupId, artifactId, project, settings, localRepository );
}
catch ( ComponentLookupException e )
{

View File

@ -22,6 +22,7 @@ import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
@ -37,6 +38,6 @@ public interface PluginManager
PluginDescriptor verifyPlugin( String prefix );
PluginDescriptor verifyPlugin( String groupId, String artifactId, String version, MavenProject project,
ArtifactRepository localRepository, boolean interactiveMode )
Settings settings, ArtifactRepository localRepository )
throws ArtifactResolutionException, PluginManagerException, PluginVersionResolutionException;
}

View File

@ -13,6 +13,7 @@ import org.apache.maven.plugin.registry.PluginRegistryUtils;
import org.apache.maven.plugin.registry.TrackableBase;
import org.apache.maven.plugin.registry.io.xpp3.PluginRegistryXpp3Writer;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.components.inputhandler.InputHandler;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.IOUtil;
@ -22,6 +23,9 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -56,17 +60,21 @@ public class DefaultPluginVersionManager
private InputHandler inputHandler;
public String resolvePluginVersion( String groupId, String artifactId, MavenProject project,
ArtifactRepository localRepository, boolean interactiveMode )
// calculated.
private PluginRegistry pluginRegistry;
public String resolvePluginVersion( String groupId, String artifactId, MavenProject project, Settings settings,
ArtifactRepository localRepository )
throws PluginVersionResolutionException
{
// first pass...if the plugin is specified in the pom, try to retrieve the version from there.
String version = getVersionFromPluginConfig( groupId, artifactId, project );
// TODO: we're NEVER going to persist POM-derived plugin versions...dunno if this is 'right' or not.
// we're NEVER going to persist POM-derived plugin versions.
String updatedVersion = null;
boolean promptToPersistUpdatedVersion = false;
// we're not going to prompt the user to accept a plugin update until we find one.
boolean promptToPersist = false;
// second pass...if the plugin is listed in the settings.xml, use the version from <useVersion/>.
if ( StringUtils.isEmpty( version ) )
@ -76,21 +84,23 @@ public class DefaultPluginVersionManager
if ( StringUtils.isNotEmpty( version ) )
{
// TODO: 2. check for updates. Determine whether this is the right time to attempt to update the version.
boolean checkForUpdates = true;
boolean forceUpdate = settings.getRuntimeInfo().isPluginUpdateForced();
if ( checkForUpdates )
// 2. check for updates. Determine whether this is the right time to attempt to update the version.
if ( forceUpdate || shouldCheckForUpdates( groupId, artifactId ) )
{
updatedVersion = resolveReleaseVersion( groupId, artifactId, project
.getRemoteArtifactRepositories(), localRepository );
if ( StringUtils.isNotEmpty( updatedVersion ) && !updatedVersion.equals( version ) )
{
// see if this version we've resolved is on our previously rejected list.
boolean isRejected = checkForRejectedStatus( groupId, artifactId, updatedVersion );
// we should only prompt to use this version if the user has not previously rejected it.
promptToPersistUpdatedVersion = !isRejected;
promptToPersist = !isRejected;
// if we've rejected this version previously, forget about updating.
if ( isRejected )
{
updatedVersion = null;
@ -101,22 +111,7 @@ public class DefaultPluginVersionManager
.info( "Plugin {" + constructPluginKey( groupId, artifactId ) + "} has updates." );
}
}
else
{
// let's be very careful about making this code resistant to change...
promptToPersistUpdatedVersion = false;
}
}
else
{
// let's be very careful about making this code resistant to change...
promptToPersistUpdatedVersion = false;
}
}
else
{
// let's be very careful about making this code resistant to change...
promptToPersistUpdatedVersion = false;
}
}
@ -131,7 +126,8 @@ public class DefaultPluginVersionManager
// 2. Set the updatedVersion so the user will be prompted whether to make this version permanent.
updatedVersion = version;
promptToPersistUpdatedVersion = true;
// 3. Tell the system to determine whether this update can/should be persisted.
promptToPersist = true;
}
// if we still haven't found a version, then fail early before we get into the update goop.
@ -141,24 +137,55 @@ public class DefaultPluginVersionManager
"Failed to resolve a valid version for this plugin" );
}
// if we're not in interactive mode, then the default is to update and NOT prompt.
// TODO: replace this with proper update policy-based determination related to batch mode.
boolean persistUpdatedVersion = promptToPersistUpdatedVersion && !interactiveMode;
// determine whether this build is running in interactive mode
// If it's not, then we'll defer to the autoUpdate setting from the registry
// for a decision on updating the plugin in the registry...rather than prompting
// the user.
boolean inInteractiveMode = settings.isInteractiveMode();
// determines what should be done if we're in non-interactive mode.
// if true, then just update the registry with the new versions.
boolean autoUpdate = Boolean.valueOf( pluginRegistry.getAutoUpdate() ).booleanValue();
// We should persist by default if:
// 1. we detected a change in the plugin version from what was in the registry, or
// a. the plugin is not registered
// 2. we're in interactive mode, or
// a. the registry is declared to be in autoUpdate mode
//
// NOTE: This is only the default value; it may be changed as the result of prompting the user.
boolean persistUpdate = promptToPersist && ( inInteractiveMode || autoUpdate );
Boolean applyToAll = settings.getRuntimeInfo().getApplyToAllPluginUpdates();
// Incorporate interactive-mode and previous decisions on apply-to-all, if appropriate.
// don't prompt if not in interactive mode.
if ( promptToPersistUpdatedVersion && interactiveMode )
{
persistUpdatedVersion = promptToPersistPluginUpdate( version, updatedVersion, groupId, artifactId );
}
// don't prompt if the user has selected ALL/NONE previously in this session
//
// NOTE: We're incorporating here, to make the usages of this check more consistent and
// resistant to change.
promptToPersist = promptToPersist && applyToAll == null && inInteractiveMode;
if ( promptToPersist )
{
persistUpdate = promptToPersistPluginUpdate( version, updatedVersion, groupId, artifactId, settings );
}
// if it is determined that we should use this version, persist it as useVersion.
if ( persistUpdatedVersion )
// cases where this version will be persisted:
// 1. the user is prompted and answers yes or all
// 2. the user has previously answeres all in this session
// 3. the build is running in non-interactive mode, and the registry setting is for auto-update
if ( ( applyToAll == null || applyToAll.booleanValue() ) && persistUpdate )
{
updatePluginVersionInRegistry( groupId, artifactId, updatedVersion );
// we're using the updated version of the plugin in this session as well.
version = updatedVersion;
}
// otherwise, if we prompted the user to update, we should treat this as a rejectedVersion, and
// persist it iff the plugin pre-exists and is in the user-level registry.
else if ( promptToPersistUpdatedVersion && interactiveMode )
else if ( promptToPersist )
{
addNewVersionToRejectedListInExisting( groupId, artifactId, updatedVersion );
}
@ -166,6 +193,48 @@ public class DefaultPluginVersionManager
return version;
}
private boolean shouldCheckForUpdates( String groupId, String artifactId )
throws PluginVersionResolutionException
{
PluginRegistry pluginRegistry = getPluginRegistry( groupId, artifactId );
org.apache.maven.plugin.registry.Plugin plugin = getPlugin( groupId, artifactId, pluginRegistry );
if ( plugin == null )
{
return true;
}
else
{
String lastChecked = plugin.getLastChecked();
if ( StringUtils.isEmpty( lastChecked ) )
{
return true;
}
else
{
SimpleDateFormat format = new SimpleDateFormat(
org.apache.maven.plugin.registry.Plugin.LAST_CHECKED_DATE_FORMAT );
try
{
Date lastCheckedDate = format.parse( lastChecked );
return IntervalUtils.isExpired( pluginRegistry.getUpdateInterval(), lastCheckedDate );
}
catch ( ParseException e )
{
getLogger().warn(
"Last-checked date for plugin {" + constructPluginKey( groupId, artifactId )
+ "} is invalid. Checking for updates." );
return true;
}
}
}
}
private boolean checkForRejectedStatus( String groupId, String artifactId, String version )
throws PluginVersionResolutionException
{
@ -177,7 +246,7 @@ public class DefaultPluginVersionManager
}
private boolean promptToPersistPluginUpdate( String version, String updatedVersion, String groupId,
String artifactId )
String artifactId, Settings settings )
throws PluginVersionResolutionException
{
try
@ -206,7 +275,7 @@ public class DefaultPluginVersionManager
message.append( "Detected (NEW) Version: " ).append( updatedVersion ).append( "\n" );
message.append( "\n" );
message.append( "Would you like to use this new version from now on? [Y/n] " );
message.append( "Would you like to use this new version from now on? ( [Y]es, [n]o, [a]ll, n[o]ne ) " );
// TODO: check the GUI-friendliness of this approach to collecting input.
// If we can't port this prompt into a GUI, IDE-integration will not work well.
@ -214,6 +283,28 @@ public class DefaultPluginVersionManager
String persistAnswer = inputHandler.readLine();
boolean shouldPersist = false;
if ( !StringUtils.isEmpty( persistAnswer ) )
{
persistAnswer = persistAnswer.toLowerCase();
if ( persistAnswer.startsWith( "y" ) )
{
shouldPersist = true;
}
else if ( persistAnswer.startsWith( "a" ) )
{
shouldPersist = true;
settings.getRuntimeInfo().setApplyToAllPluginUpdates( Boolean.TRUE );
}
else if ( persistAnswer.indexOf( "o" ) > -1 )
{
settings.getRuntimeInfo().setApplyToAllPluginUpdates( Boolean.FALSE );
}
}
return StringUtils.isEmpty( persistAnswer ) || "y".equalsIgnoreCase( persistAnswer );
}
@ -352,6 +443,10 @@ public class DefaultPluginVersionManager
else
{
plugin.setUseVersion( version );
SimpleDateFormat format = new SimpleDateFormat( org.apache.maven.plugin.registry.Plugin.LAST_CHECKED_DATE_FORMAT );
plugin.setLastChecked(format.format( new Date() ) );
}
}
else
@ -361,7 +456,6 @@ public class DefaultPluginVersionManager
plugin.setGroupId( groupId );
plugin.setArtifactId( artifactId );
plugin.setUseVersion( version );
plugin.setAutoUpdate( false );
pluginRegistry.addPlugin( plugin );
}
@ -372,7 +466,7 @@ public class DefaultPluginVersionManager
private void writeUserRegistry( String groupId, String artifactId, PluginRegistry pluginRegistry )
throws PluginVersionResolutionException
{
File pluginRegistryFile = pluginRegistry.getFile();
File pluginRegistryFile = pluginRegistry.getRuntimeInfo().getFile();
PluginRegistry extractedUserRegistry = PluginRegistryUtils.extractUserPluginRegistry( pluginRegistry );
@ -408,24 +502,25 @@ public class DefaultPluginVersionManager
private PluginRegistry getPluginRegistry( String groupId, String artifactId )
throws PluginVersionResolutionException
{
PluginRegistry pluginRegistry = null;
try
{
pluginRegistry = mavenPluginRegistryBuilder.buildPluginRegistry();
}
catch ( IOException e )
{
throw new PluginVersionResolutionException( groupId, artifactId, "Cannot read plugin registry", e );
}
catch ( XmlPullParserException e )
{
throw new PluginVersionResolutionException( groupId, artifactId, "Cannot parse plugin registry", e );
}
if ( pluginRegistry == null )
{
pluginRegistry = mavenPluginRegistryBuilder.createUserPluginRegistry();
try
{
pluginRegistry = mavenPluginRegistryBuilder.buildPluginRegistry();
}
catch ( IOException e )
{
throw new PluginVersionResolutionException( groupId, artifactId, "Cannot read plugin registry", e );
}
catch ( XmlPullParserException e )
{
throw new PluginVersionResolutionException( groupId, artifactId, "Cannot parse plugin registry", e );
}
if ( pluginRegistry == null )
{
pluginRegistry = mavenPluginRegistryBuilder.createUserPluginRegistry();
}
}
return pluginRegistry;

View File

@ -0,0 +1,115 @@
package org.apache.maven.plugin.version;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public final class IntervalUtils
{
private static final String PERIOD_PART_PATTERN = "[0-9]+[WwDdHhMm]";
private static final Map PART_TYPE_CONTRIBUTIONS;
static
{
Map contributions = new HashMap();
contributions.put( "w", new Long( 7 * 24 * 60 * 60 * 1000 ) );
contributions.put( "d", new Long( 24 * 60 * 60 * 1000 ) );
contributions.put( "h", new Long( 60 * 60 * 1000 ) );
contributions.put( "m", new Long( 60 * 1000 ) );
PART_TYPE_CONTRIBUTIONS = contributions;
}
private IntervalUtils()
{
// don't allow construction
}
public static boolean isExpired( String intervalSpec, Date lastChecked )
{
if( "never".equalsIgnoreCase( intervalSpec ) )
{
return false;
}
else if( "always".equalsIgnoreCase( intervalSpec ) )
{
return true;
}
else if( intervalSpec != null && intervalSpec.toLowerCase().startsWith("interval:") && intervalSpec.length() > "interval:".length())
{
String intervalPart = intervalSpec.substring( "interval:".length() );
// subtract the specified period from now() and see if it's still after the lastChecked date.
long period = IntervalUtils.parseInterval(intervalPart);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis( System.currentTimeMillis() - period );
Date test = cal.getTime();
return lastChecked == null || test.after( lastChecked );
}
else
{
throw new IllegalArgumentException( "Invalid interval specification: \'" + intervalSpec + "\'" );
}
}
public static long parseInterval( String interval )
{
Matcher partMatcher = Pattern.compile(PERIOD_PART_PATTERN).matcher(interval);
long period = 0;
while( partMatcher.find() )
{
String part = partMatcher.group();
period += getPartPeriod( part );
}
return period;
}
private static long getPartPeriod( String part )
{
char type = part.charAt( part.length() - 1 );
int coefficient = Integer.parseInt( part.substring( 0, part.length() -1 ) );
Long period = (Long) PART_TYPE_CONTRIBUTIONS.get( "" + Character.toLowerCase( type ) );
long result = 0;
if( period != null )
{
result = coefficient * period.longValue();
}
return result;
}
}

View File

@ -2,6 +2,7 @@ package org.apache.maven.plugin.version;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
/*
* Copyright 2001-2005 The Apache Software Foundation.
@ -24,8 +25,7 @@ public interface PluginVersionManager
String ROLE = PluginVersionManager.class.getName();
String resolvePluginVersion( String groupId, String artifactId, MavenProject project,
ArtifactRepository localRepository, boolean interactiveMode )
String resolvePluginVersion( String groupId, String artifactId, MavenProject project, Settings settings, ArtifactRepository localRepository )
throws PluginVersionResolutionException;
}

View File

@ -0,0 +1,103 @@
package org.apache.maven.plugin.version;
import java.util.Calendar;
import java.util.Date;
import junit.framework.TestCase;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class IntervalUtilsTest
extends TestCase
{
private static final long ONE_MINUTE = 60 * 1000;
private static final long ONE_HOUR = 60 * ONE_MINUTE;
private static final long ONE_DAY = 24 * ONE_HOUR;
private static final long ONE_WEEK = 7 * ONE_DAY;
public void testOneWeek()
{
assertEquals( ONE_WEEK, IntervalUtils.parseInterval( "1w" ) );
}
public void testTwoWeeks()
{
assertEquals( ( 2 * ONE_WEEK ), IntervalUtils.parseInterval( "2w" ) );
}
public void testOneDay()
{
assertEquals( ONE_DAY, IntervalUtils.parseInterval( "1d" ) );
}
public void testOneHour()
{
assertEquals( ONE_HOUR, IntervalUtils.parseInterval( "1h" ) );
}
public void testOneMinute()
{
assertEquals( ONE_MINUTE, IntervalUtils.parseInterval( "1m" ) );
}
public void testTwoDaysThreeHoursAndOneMinute()
{
assertEquals( 2 * ONE_DAY + 3 * ONE_HOUR + ONE_MINUTE, IntervalUtils.parseInterval( "2d 3h 1m" ) );
}
public void testTwoDaysThreeHoursAndOneMinuteCondensed()
{
assertEquals( 2 * ONE_DAY + 3 * ONE_HOUR + ONE_MINUTE, IntervalUtils.parseInterval( "2d3h1m" ) );
}
public void testTwoDaysThreeHoursAndOneMinuteCommaSeparated()
{
assertEquals( 2 * ONE_DAY + 3 * ONE_HOUR + ONE_MINUTE, IntervalUtils.parseInterval( "2d,3h,1m" ) );
}
public void testTwoDaysThreeHoursAndOneMinuteRearranged()
{
assertEquals( 2 * ONE_DAY + 3 * ONE_HOUR + ONE_MINUTE, IntervalUtils.parseInterval( "1m 2d 3h" ) );
}
public void testThreeDaysPoorlySpecified()
{
assertEquals( 3 * ONE_DAY, IntervalUtils.parseInterval( "1d 2d" ) );
}
public void testNeverInterval()
{
assertFalse( IntervalUtils.isExpired( "never", null ) );
}
public void testAlwaysInterval()
{
assertTrue( IntervalUtils.isExpired( "always", null ) );
}
public void testOneMinuteIntervalShouldBeExpired()
{
Calendar cal = Calendar.getInstance();
cal.add( Calendar.MINUTE, -2 );
Date lastChecked = cal.getTime();
assertTrue( IntervalUtils.isExpired( "interval:1m", lastChecked ) );
}
}

View File

@ -58,6 +58,25 @@
<superClass>TrackableBase</superClass>
<description>Root element of the plugin registry file.</description>
<fields>
<field>
<name>updateInterval</name>
<version>1.0.0</version>
<type>String</type>
<defaultValue>never</defaultValue>
<description><![CDATA[
Specifies how often to check for plugin updates. Valid values are: never, always, interval:XXX.
For the interval specification, XXX denotes a terse interval specification, such as 4h.
Where h=hours, m=minutes, d=days, w=weeks. The interval period should be specified in descending
order of granularity, like this: '[n]w [n]d [n]h [n]m'. Any omitted level of granularity will be
assumed to be a zero value.
]]></description>
</field>
<field>
<name>autoUpdate</name>
<version>1.0.0</version>
<type>String</type>
<description>Specifies whether the user should be prompted to update plugins.</description>
</field>
<field>
<name>plugins</name>
<version>1.0.0</version>
@ -96,16 +115,16 @@
this.pluginsByKey = null;
}
private java.io.File file;
private RuntimeInfo runtimeInfo;
public void setFile( java.io.File file )
public void setRuntimeInfo( RuntimeInfo runtimeInfo )
{
this.file = file;
this.runtimeInfo = runtimeInfo;
}
public java.io.File getFile()
public RuntimeInfo getRuntimeInfo()
{
return file;
return runtimeInfo;
}
]]></code>
</codeSegment>
@ -130,11 +149,10 @@
<type>String</type>
</field>
<field>
<name>autoUpdate</name>
<name>lastChecked</name>
<version>1.0.0</version>
<type>boolean</type>
<default>false</default>
<description>Whether to automatically update this plugin - false means prompt the user.</description>
<type>String</type>
<description>[format: yyyy-MM-dd.HH:mm:ss Z] Specifies the date/time at which this plugin was last checked.</description>
</field>
<field>
<name>useVersion</name>
@ -156,6 +174,8 @@
<codeSegment>
<version>1.0.0</version>
<code><![CDATA[
public static final String LAST_CHECKED_DATE_FORMAT = "yyyy-MM-dd.HH:mm:ss Z";
public String getKey()
{
return getGroupId() + ":" + getArtifactId();

View File

@ -102,7 +102,11 @@ public class DefaultPluginRegistryBuilder
registry = modelReader.read( reader );
registry.setFile( registryFile );
RuntimeInfo rtInfo = new RuntimeInfo( registry );
registry.setRuntimeInfo( rtInfo );
rtInfo.setFile( registryFile );
}
finally
{
@ -155,7 +159,11 @@ public class DefaultPluginRegistryBuilder
{
PluginRegistry registry = new PluginRegistry();
registry.setFile( userRegistryFile );
RuntimeInfo rtInfo = new RuntimeInfo( registry );
registry.setRuntimeInfo( rtInfo );
rtInfo.setFile( userRegistryFile );
return registry;
}

View File

@ -32,15 +32,43 @@ public final class PluginRegistryUtils
public static void merge( PluginRegistry dominant, PluginRegistry recessive, String recessiveSourceLevel )
{
// can't merge into something that doesn't exist...
if ( dominant == null )
// nothing to merge...
if ( dominant == null || recessive == null )
{
return;
}
RuntimeInfo dominantRtInfo = dominant.getRuntimeInfo();
String dominantUpdateInterval = dominant.getUpdateInterval();
if ( dominantUpdateInterval == null )
{
String recessiveUpdateInterval = recessive.getUpdateInterval();
if ( recessiveUpdateInterval != null )
{
dominant.setUpdateInterval( recessiveUpdateInterval );
dominantRtInfo.setUpdateIntervalSourceLevel( recessiveSourceLevel );
}
}
String dominantAutoUpdate = dominant.getAutoUpdate();
if ( dominantAutoUpdate == null )
{
String recessiveAutoUpdate = recessive.getAutoUpdate();
if ( recessiveAutoUpdate != null )
{
dominant.setAutoUpdate( recessiveAutoUpdate );
dominantRtInfo.setAutoUpdateSourceLevel( recessiveSourceLevel );
}
}
List recessivePlugins = null;
if(recessive != null)
if ( recessive != null )
{
recessivePlugins = recessive.getPlugins();
}
@ -48,7 +76,7 @@ public final class PluginRegistryUtils
{
recessivePlugins = Collections.EMPTY_LIST;
}
shallowMergePlugins( dominant, recessivePlugins, recessiveSourceLevel );
}
@ -99,6 +127,22 @@ public final class PluginRegistryUtils
{
userRegistry = new PluginRegistry();
RuntimeInfo rtInfo = new RuntimeInfo( userRegistry );
userRegistry.setRuntimeInfo( rtInfo );
RuntimeInfo oldRtInfo = pluginRegistry.getRuntimeInfo();
if ( TrackableBase.USER_LEVEL.equals( oldRtInfo.getAutoUpdateSourceLevel() ) )
{
userRegistry.setAutoUpdate( pluginRegistry.getAutoUpdate() );
}
if ( TrackableBase.USER_LEVEL.equals( oldRtInfo.getUpdateIntervalSourceLevel() ) )
{
userRegistry.setUpdateInterval( pluginRegistry.getUpdateInterval() );
}
List plugins = new ArrayList();
for ( Iterator it = pluginRegistry.getPlugins().iterator(); it.hasNext(); )
@ -113,7 +157,7 @@ public final class PluginRegistryUtils
userRegistry.setPlugins( plugins );
userRegistry.setFile( pluginRegistry.getFile() );
rtInfo.setFile( pluginRegistry.getRuntimeInfo().getFile() );
}
return userRegistry;

View File

@ -0,0 +1,81 @@
package org.apache.maven.plugin.registry;
import java.io.File;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class RuntimeInfo
{
private File file;
private String autoUpdateSourceLevel;
private String updateIntervalSourceLevel;
private final PluginRegistry registry;
public RuntimeInfo( PluginRegistry registry )
{
this.registry = registry;
}
public String getAutoUpdateSourceLevel()
{
if ( autoUpdateSourceLevel == null )
{
return registry.getSourceLevel();
}
else
{
return autoUpdateSourceLevel;
}
}
public void setAutoUpdateSourceLevel( String autoUpdateSourceLevel )
{
this.autoUpdateSourceLevel = autoUpdateSourceLevel;
}
public File getFile()
{
return file;
}
public void setFile( File file )
{
this.file = file;
}
public String getUpdateIntervalSourceLevel()
{
if ( updateIntervalSourceLevel == null )
{
return registry.getSourceLevel();
}
else
{
return updateIntervalSourceLevel;
}
}
public void setUpdateIntervalSourceLevel( String updateIntervalSourceLevel )
{
this.updateIntervalSourceLevel = updateIntervalSourceLevel;
}
}

View File

@ -15,6 +15,11 @@
<artifactId>maven-core</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-settings</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven.reporting</groupId>
<artifactId>maven-reporting-api</artifactId>

View File

@ -27,6 +27,7 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.MavenReport;
import org.apache.maven.reporting.MavenReportConfiguration;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.i18n.I18N;
import org.codehaus.plexus.siterenderer.Renderer;
import org.codehaus.plexus.siterenderer.RendererException;
@ -80,10 +81,11 @@ public class DoxiaMojo
private static final String DEFAULT_TEMPLATE = RESOURCE_DIR + "/maven-site.vm";
/**
* @parameter expression="${settings.interactiveMode}"
* @parameter expression="${settings}"
* @required
* @readonly
*/
private boolean interactive = true;
private Settings settings;
/**
* @parameter expression="${basedir}/src/site"
@ -724,7 +726,7 @@ public class DoxiaMojo
try
{
pluginManager.verifyPlugin( plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion(),
project, localRepository, interactive );
project, settings, localRepository );
}
catch ( ArtifactResolutionException e )
{

View File

@ -264,49 +264,16 @@
return match;
}
private Map activeProfileToSourceLevel = new HashMap();
private RuntimeInfo runtimeInfo;
public void setActiveProfileSourceLevel( String activeProfile, String sourceLevel )
public void setRuntimeInfo( RuntimeInfo runtimeInfo )
{
activeProfileToSourceLevel.put( activeProfile, sourceLevel );
this.runtimeInfo = runtimeInfo;
}
public String getSourceLevelForActiveProfile( String activeProfile )
public RuntimeInfo getRuntimeInfo()
{
String sourceLevel = (String) activeProfileToSourceLevel.get( activeProfile );
if ( sourceLevel != null )
{
return sourceLevel;
}
else
{
return getSourceLevel();
}
}
private String localRepositorySourceLevel = TrackableBase.USER_LEVEL;
public void setLocalRepositorySourceLevel( String localRepoSourceLevel )
{
this.localRepositorySourceLevel = localRepoSourceLevel;
}
public String getLocalRepositorySourceLevel()
{
return localRepositorySourceLevel;
}
private java.io.File file;
public void setFile( java.io.File file )
{
this.file = file;
}
public java.io.File getFile()
{
return file;
return runtimeInfo;
}
]]></code>
</codeSegment>

View File

@ -86,7 +86,11 @@ public class DefaultMavenSettingsBuilder
settings = modelReader.read( reader );
settings.setFile( settingsFile );
RuntimeInfo rtInfo = new RuntimeInfo( settings );
rtInfo.setFile( settingsFile );
settings.setRuntimeInfo( rtInfo );
}
finally
{

View File

@ -0,0 +1,102 @@
package org.apache.maven.settings;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class RuntimeInfo
{
private File file;
private boolean pluginUpdateForced = false;
// using Boolean for 3VL (null, true-to-all, false-to-all)
private Boolean applyToAllPluginUpdates;
private Map activeProfileToSourceLevel = new HashMap();
private String localRepositorySourceLevel = TrackableBase.USER_LEVEL;
private final Settings settings;
public RuntimeInfo( Settings settings )
{
this.settings = settings;
}
public void setFile( File file )
{
this.file = file;
}
public File getFile()
{
return file;
}
public void setPluginUpdateForced( boolean pluginUpdateForced )
{
this.pluginUpdateForced = pluginUpdateForced;
}
public boolean isPluginUpdateForced()
{
return pluginUpdateForced;
}
public Boolean getApplyToAllPluginUpdates()
{
return applyToAllPluginUpdates;
}
public void setApplyToAllPluginUpdates( Boolean applyToAll )
{
this.applyToAllPluginUpdates = applyToAll;
}
public void setActiveProfileSourceLevel( String activeProfile, String sourceLevel )
{
activeProfileToSourceLevel.put( activeProfile, sourceLevel );
}
public String getSourceLevelForActiveProfile( String activeProfile )
{
String sourceLevel = (String) activeProfileToSourceLevel.get( activeProfile );
if ( sourceLevel != null )
{
return sourceLevel;
}
else
{
return settings.getSourceLevel();
}
}
public void setLocalRepositorySourceLevel( String localRepoSourceLevel )
{
this.localRepositorySourceLevel = localRepoSourceLevel;
}
public String getLocalRepositorySourceLevel()
{
return localRepositorySourceLevel;
}
}

View File

@ -51,7 +51,7 @@ public final class SettingsUtils
{
dominantActiveProfiles.add( profileId );
dominant.setActiveProfileSourceLevel( profileId, recessiveSourceLevel );
dominant.getRuntimeInfo().setActiveProfileSourceLevel( profileId, recessiveSourceLevel );
}
}
@ -59,7 +59,7 @@ public final class SettingsUtils
{
dominant.setLocalRepository( recessive.getLocalRepository() );
dominant.setLocalRepositorySourceLevel( recessiveSourceLevel );
dominant.getRuntimeInfo().setLocalRepositorySourceLevel( recessiveSourceLevel );
}
shallowMergeById( dominant.getMirrors(), recessive.getMirrors(), recessiveSourceLevel );