package org.codehaus.mojo.pomtools.wrapper.custom;
/*
* Copyright 2005-2006 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.
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.InvalidArtifactRTException;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.Restriction;
import org.apache.maven.model.Dependency;
import org.codehaus.mojo.pomtools.PomToolsPluginContext;
import org.codehaus.mojo.pomtools.PomToolsException;
import org.codehaus.mojo.pomtools.PomToolsVersionException;
import org.codehaus.mojo.pomtools.helpers.MetadataHelper;
import org.codehaus.mojo.pomtools.helpers.ModelHelper;
import org.codehaus.mojo.pomtools.versioning.DefaultVersionInfo;
import org.codehaus.mojo.pomtools.versioning.VersionInfo;
import org.codehaus.mojo.pomtools.wrapper.ObjectWrapper;
import org.codehaus.mojo.pomtools.wrapper.reflection.BeanFields;
import org.codehaus.mojo.pomtools.wrapper.reflection.ModelReflectionException;
import org.codehaus.plexus.util.StringUtils;
/**
*
* @author <a href="mailto:dhawkins@codehaus.org">David Hawkins</a>
* @version $Id$
*/
public class DependencyWrapper
{
public static final String VERSION = "version";
public static final String ARTIFACT_ID = "artifactId";
public static final String GROUP_ID = "groupId";
public static final String TYPE = "type";
public static final String SCOPE = "scope";
private static final String[] FIELDS = new String[] { GROUP_ID, ARTIFACT_ID, VERSION, TYPE, SCOPE };
private final ObjectWrapper objWrapper;
/* groupId and artifactId used when fetching metadata */
private String metadataGroupId;
private String metadataArtifactId;
private LinkedList versions;
private LinkedList parsedVersions;
private LinkedList unparsedVersions;
public DependencyWrapper( ObjectWrapper objWrapper )
{
if ( objWrapper == null )
{
throw new IllegalArgumentException( "ObjectWrapper cannot be null" );
}
this.objWrapper = objWrapper;
BeanFields fields = objWrapper.getFields();
// Validate that the object has all of our relevant fields
for ( int i = 0; i < FIELDS.length; i++ )
{
if ( fields.get( FIELDS[i] ) == null )
{
throw new ModelReflectionException( "Unable to find field in Dependency: " + FIELDS[i] );
}
}
}
/** If groupId and artifactId are equal, only one of them is returned.
* commons-lang:commons-lang => commons-lang
*
*/
public String toString()
{
String groupId = getGroupId();
String artifactId = getArtifactId();
if ( StringUtils.equals( groupId, artifactId ) && groupId != null )
{
return groupId;
}
else
{
return ModelHelper.versionlessKey( groupId, artifactId );
}
}
public String getVersion()
{
return (String) objWrapper.getFieldValue( VERSION );
}
public void setVersion( String version )
{
if ( !StringUtils.equals( getVersion(), version ) )
{
objWrapper.setFieldValue( VERSION, version );
}
}
public String getGroupId()
{
return (String) objWrapper.getFieldValue( GROUP_ID );
}
public String getArtifactId()
{
return (String) objWrapper.getFieldValue( ARTIFACT_ID );
}
public String getType()
{
return (String) objWrapper.getFieldValue( TYPE );
}
public String getScope()
{
return (String) objWrapper.getFieldValue( SCOPE );
}
public void setToLatestVersion( boolean includeSnapshots )
{
String latest = getLatestVersion( includeSnapshots ).getVersionString();
objWrapper.setFieldValue( VERSION, latest );
}
public ModelVersionRange getVersionRange( String version )
{
if ( version == null )
{
return null;
}
try
{
return ModelVersionRange.createFromVersionSpec( version );
}
catch ( InvalidVersionSpecificationException e )
{
throw new PomToolsVersionException( "Unable to parse version: " + version, e );
}
}
public ModelVersionRange getVersionRange()
{
return getVersionRange( (String) objWrapper.getFieldValue( DependencyWrapper.VERSION ) );
}
public ModelVersionRange getResolvedVersionRange()
{
return getVersionRange( getResolvedVersion() );
}
private List getMetadataVersions()
throws PomToolsVersionException
{
metadataGroupId = getGroupId();
metadataArtifactId = getArtifactId();
try
{
PomToolsPluginContext context = PomToolsPluginContext.getInstance();
RepositoryMetadata repoMetadata = context.getMetadataHelper().getMetadata( getArtifact() );
if ( repoMetadata != null )
{
Metadata metadata = repoMetadata.getMetadata();
if ( metadata != null && metadata.getVersioning() != null )
{
return metadata.getVersioning().getVersions();
}
else if ( metadata != null && metadata.getVersion() != null )
{
// Non provided jars like javax.mail and javax.servlet:servlet-api
// don't have versioning sections, so create the list from the single version
// specified by the artifact.
if ( isValidArtifact() )
{
List metadataVersions = new ArrayList();
metadataVersions.add( metadata.getVersion() );
return metadataVersions;
}
}
}
return null;
}
catch ( InvalidArtifactRTException e )
{
throw new PomToolsVersionException( e );
}
catch ( ArtifactMetadataRetrievalException e )
{
throw new PomToolsVersionException( e );
}
}
/** We cache the versions so we want to make sure that we aren't using
* old information if the groupId or artifactId has changed since we last
* fetched the versions
*/
private boolean isMetadataCurrent()
{
return metadataGroupId != null && metadataArtifactId != null
&& StringUtils.equals( metadataGroupId, getGroupId() )
&& StringUtils.equals( metadataArtifactId, getArtifactId() );
}
private void resolveVersions()
{
if ( versions == null || !isMetadataCurrent() )
{
versions = new LinkedList();
parsedVersions = new LinkedList();
unparsedVersions = new LinkedList();
List metadataVersions = getMetadataVersions();
if ( metadataVersions != null )
{
for ( Iterator i = metadataVersions.iterator(); i.hasNext(); )
{
//ArtifactVersion av = (ArtifactVersion) i.next();
DefaultVersionInfo version = new DefaultVersionInfo( (String) i.next() );
versions.add( version );
if ( version.isParsed() )
{
parsedVersions.add( version );
}
else
{
unparsedVersions.add( version );
}
}
Collections.sort( parsedVersions );
}
}
}
private Artifact getArtifact()
{
MetadataHelper metaHelper = PomToolsPluginContext.getInstance().getMetadataHelper();
return metaHelper.createArtifact( getGroupId(),
getArtifactId(),
getVersion(),
getType(),
getScope() );
}
public boolean isValidArtifact()
{
MetadataHelper metaHelper = PomToolsPluginContext.getInstance().getMetadataHelper();
return metaHelper.isValidDependencyArtifact( getArtifact() );
}
public boolean isValidGroupIdArtifactId()
{
MetadataHelper metaHelper = PomToolsPluginContext.getInstance().getMetadataHelper();
return metaHelper.isValidGroupIdArtifactId( getArtifact() );
}
public boolean isValidVersion()
{
return isValidVersion( getVersion() );
}
public boolean isValidVersion( String version )
{
if ( StringUtils.isEmpty( version ) )
{
return false;
}
try
{
List metadataVersions = getMetadataVersions();
ModelVersionRange range = ModelVersionRange.createFromVersionSpec( version );
if ( range.hasRestrictions() )
{
return metadataVersions != null;
}
else
{
return metadataVersions != null && metadataVersions.contains( version );
}
}
catch ( InvalidArtifactRTException e )
{
return false;
}
catch ( PomToolsVersionException e )
{
return false;
}
catch ( InvalidVersionSpecificationException e )
{
return false;
}
}
public boolean setVersionLowerBound( String boundVersionSpec )
throws PomToolsVersionException
{
return setBoundedVersion( boundVersionSpec, true );
}
public boolean setVersionUpperBound( String boundVersionSpec )
throws PomToolsVersionException
{
return setBoundedVersion( boundVersionSpec, false );
}
protected boolean setBoundedVersion( String boundVersionSpec, boolean isLower )
throws PomToolsVersionException
{
boolean isUpper = !isLower;
try
{
ModelVersionRange currentRange = getVersionRange();
ModelVersionRange newRange = ModelVersionRange.createFromVersionSpec( boundVersionSpec );
if ( currentRange != null && currentRange.hasRestrictions() )
{
Restriction curres = (Restriction) currentRange.getRestrictions().get( 0 );
Restriction newres = (Restriction) newRange.getRestrictions().get( 0 );
Restriction r = new Restriction( ( isLower || curres.getLowerBound() == null ) ? newres.getLowerBound()
: curres.getLowerBound(),
( isLower || curres.getLowerBound() == null ) ? newres
.isLowerBoundInclusive() : curres.isLowerBoundInclusive(),
( isUpper || curres.getUpperBound() == null ) ? newres.getUpperBound()
: curres.getUpperBound(),
( isUpper || curres.getUpperBound() == null ) ? newres
.isUpperBoundInclusive() : curres.isUpperBoundInclusive() );
currentRange.getRestrictions().clear();
currentRange.getRestrictions().add( r );
}
else
{
currentRange = newRange;
}
String strVersion = currentRange.toString();
if ( ModelHelper.isParsableVersion( strVersion ) )
{
setVersion( currentRange.toString() );
return true;
}
else
{
return false;
}
}
catch ( InvalidVersionSpecificationException e )
{
throw new PomToolsVersionException( "Unable to parse version: " + boundVersionSpec, e );
}
}
public List getAllVersions()
{
resolveVersions();
return versions;
}
public List getParsedVersions()
{
resolveVersions();
return parsedVersions;
}
public List getUnparsedVersions()
{
resolveVersions();
return unparsedVersions;
}
/**
* Its possible that this dependency has a null version
* because it is inheriting it from the parent. Return the parent's
* version of the dependency if this one is null
*
* @return
*/
public String getResolvedVersion()
{
String version = getVersion();
if ( version != null )
{
return version;
}
else
{
ProjectWrapper project = PomToolsPluginContext.getInstance().getActiveProject();
Dependency tmpDep;
try
{
tmpDep = project.findResolvedDependency( this );
}
catch ( PomToolsException e )
{
throw new PomToolsVersionException( e );
}
if ( tmpDep != null )
{
return tmpDep.getVersion();
}
else
{
return null;
}
}
}
public VersionInfo getLatestVersion( boolean includeSnapshots )
{
try
{
resolveVersions();
}
catch ( PomToolsVersionException e )
{
return null;
}
if ( parsedVersions.isEmpty() )
{
return null;
}
if ( includeSnapshots )
{
return (VersionInfo) parsedVersions.getLast();
}
else
{
VersionInfo latest = null;
int index = parsedVersions.size() - 1;
while ( latest == null && index >= 0 )
{
VersionInfo tmpInfo = (VersionInfo) parsedVersions.get( index-- );
if ( !tmpInfo.isSnapshot() )
{
latest = tmpInfo;
}
}
return latest;
}
}
}