/**
* Copyright (c) 2008-2011 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://www.sonatype.com/products/nexus/attributions.
*
* This program is free software: you can redistribute it and/or modify it only under the terms of the GNU Affero General
* Public License Version 3 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License Version 3
* for more details.
*
* You should have received a copy of the GNU Affero General Public License Version 3 along with this program. If not, see
* http://www.gnu.org/licenses.
*
* Sonatype Nexus (TM) Open Source Version is available from Sonatype, Inc. Sonatype and Sonatype Nexus are trademarks of
* Sonatype, Inc. Apache Maven is a trademark of the Apache Foundation. M2Eclipse is a trademark of the Eclipse Foundation.
* All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.configuration.application.upgrade;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.sonatype.configuration.upgrade.ConfigurationIsCorruptedException;
import org.sonatype.configuration.upgrade.SingleVersionUpgrader;
import org.sonatype.configuration.upgrade.UpgradeMessage;
import org.sonatype.nexus.configuration.model.v1_0_0.Configuration;
import org.sonatype.nexus.configuration.model.v1_0_0.io.xpp3.NexusConfigurationXpp3Reader;
import org.sonatype.nexus.configuration.model.v1_0_1.CAuthSource;
import org.sonatype.nexus.configuration.model.v1_0_1.CAuthzSource;
import org.sonatype.nexus.configuration.model.v1_0_1.CGroupsSetting;
import org.sonatype.nexus.configuration.model.v1_0_1.CGroupsSettingPathMappingItem;
import org.sonatype.nexus.configuration.model.v1_0_1.CLocalStorage;
import org.sonatype.nexus.configuration.model.v1_0_1.CProps;
import org.sonatype.nexus.configuration.model.v1_0_1.CRemoteAuthentication;
import org.sonatype.nexus.configuration.model.v1_0_1.CRemoteConnectionSettings;
import org.sonatype.nexus.configuration.model.v1_0_1.CRemoteHttpProxySettings;
import org.sonatype.nexus.configuration.model.v1_0_1.CRemoteStorage;
import org.sonatype.nexus.configuration.model.v1_0_1.CRepository;
import org.sonatype.nexus.configuration.model.v1_0_1.CRepositoryGroup;
import org.sonatype.nexus.configuration.model.v1_0_1.CRepositoryGrouping;
import org.sonatype.nexus.configuration.model.v1_0_1.CRepositoryShadow;
import org.sonatype.nexus.configuration.model.v1_0_1.CRouting;
import org.sonatype.nexus.configuration.model.v1_0_1.CSecurity;
/**
* Upgrades configuration model from version 1.0.0 (SWX: 1.0) to 1.0.1.
*
* @author cstamas
*/
@Component( role = SingleVersionUpgrader.class, hint = "1.0.0" )
public class Upgrade100to101
implements SingleVersionUpgrader
{
public Object loadConfiguration( File file )
throws IOException,
ConfigurationIsCorruptedException
{
FileReader fr = null;
try
{
// reading without interpolation to preserve user settings as variables
fr = new FileReader( file );
NexusConfigurationXpp3Reader reader = new NexusConfigurationXpp3Reader();
return reader.read( fr );
}
catch ( XmlPullParserException e )
{
throw new ConfigurationIsCorruptedException( file.getAbsolutePath(), e );
}
finally
{
if ( fr != null )
{
fr.close();
}
}
}
public void upgrade( UpgradeMessage message )
{
Configuration oldc = (Configuration) message.getConfiguration();
org.sonatype.nexus.configuration.model.v1_0_1.Configuration newc = new org.sonatype.nexus.configuration.model.v1_0_1.Configuration();
newc.setVersion( org.sonatype.nexus.configuration.model.v1_0_1.Configuration.MODEL_VERSION );
newc.setWorkingDirectory( oldc.getWorkingDirectory() );
newc.setApplicationLogDirectory( oldc.getApplicationLogDirectory() );
CSecurity security = new CSecurity();
security.setEnabled( oldc.getSecurity().isEnabled() );
security.setAnonymousAccessEnabled( oldc.getSecurity().isAnonymousAccessEnabled() );
if ( oldc.getSecurity().getAuthenticationSource() != null )
{
CAuthSource authenticationSource = new CAuthSource();
authenticationSource.setType( oldc.getSecurity().getAuthenticationSource().getType() );
if ( oldc.getSecurity().getAuthenticationSource().getProperties() != null )
{
authenticationSource.setProperties( copyCProps1_0_0( oldc
.getSecurity().getAuthenticationSource().getProperties() ) );
}
security.setAuthenticationSource( authenticationSource );
}
if ( oldc.getSecurity().getRealms() != null )
{
List<CAuthzSource> realms = new ArrayList<CAuthzSource>( oldc.getSecurity().getRealms().size() );
for ( org.sonatype.nexus.configuration.model.v1_0_0.CAuthzSource oldrealm : (List<org.sonatype.nexus.configuration.model.v1_0_0.CAuthzSource>) oldc
.getSecurity().getRealms() )
{
CAuthzSource newrealm = new CAuthzSource();
newrealm.setId( oldrealm.getId() );
newrealm.setType( oldrealm.getType() );
newrealm.setProperties( copyCProps1_0_0( oldrealm.getProperties() ) );
realms.add( newrealm );
}
security.setRealms( realms );
}
newc.setSecurity( security );
if ( oldc.getGlobalConnectionSettings() != null )
{
newc.setGlobalConnectionSettings( copyCRemoteConnectionSettings1_0_0( oldc.getGlobalConnectionSettings() ) );
}
else
{
newc.setGlobalConnectionSettings( new CRemoteConnectionSettings() );
}
if ( oldc.getGlobalHttpProxySettings() != null )
{
newc.setGlobalHttpProxySettings( copyCRemoteHttpProxySettings1_0_0( oldc.getGlobalHttpProxySettings() ) );
}
if ( oldc.getRouting() != null )
{
CRouting routing = new CRouting();
routing.setFollowLinks( oldc.getRouting().getGroups().isFollowLinks() );
routing.setNotFoundCacheTTL( oldc.getRouting().getGroups().getNotFoundCacheTTL() );
if ( oldc.getRouting().getGroups() != null )
{
CGroupsSetting groups = new CGroupsSetting();
groups.setStopItemSearchOnFirstFoundFile( oldc
.getRouting().getGroups().isStopItemSearchOnFirstFoundFile() );
groups.setMergeMetadata( oldc.getRouting().getGroups().isMergeMetadata() );
routing.setGroups( groups );
}
newc.setRouting( routing );
}
else
{
newc.setRouting( new CRouting() );
newc.getRouting().setGroups( new CGroupsSetting() );
}
List<CRepository> repositories = new ArrayList<CRepository>( oldc.getRepositories().size() );
for ( org.sonatype.nexus.configuration.model.v1_0_0.CRepository oldrepos : (List<org.sonatype.nexus.configuration.model.v1_0_0.CRepository>) oldc
.getRepositories() )
{
CRepository newrepos = copyCRepository1_0_0( oldrepos );
if ( oldrepos.isShouldServeReleases() && !oldrepos.isShouldServeSnapshots() )
{
newrepos.setRepositoryPolicy( CRepository.REPOSITORY_TYPE_RELEASE );
}
else if ( !oldrepos.isShouldServeReleases() && oldrepos.isShouldServeSnapshots() )
{
newrepos.setRepositoryPolicy( CRepository.REPOSITORY_TYPE_SNAPSHOT );
}
else if ( !oldrepos.isShouldServeReleases() && !oldrepos.isShouldServeSnapshots() )
{
// this is probably some user error, declaring it release and disabling it
newrepos.setRepositoryPolicy( CRepository.REPOSITORY_TYPE_RELEASE );
newrepos.setAvailable( false );
}
else
{
// the repos is mixed, so we are splitting it automagically
newrepos.setId( newrepos.getId() + "-release" );
newrepos.setName( newrepos.getName() + " release" );
newrepos.setRepositoryPolicy( CRepository.REPOSITORY_TYPE_RELEASE );
CRepository newrepos1 = copyCRepository1_0_0( oldrepos );
newrepos1.setId( newrepos.getId() + "-snapshot" );
newrepos1.setName( newrepos.getName() + " snapshot" );
newrepos1.setRepositoryPolicy( CRepository.REPOSITORY_TYPE_SNAPSHOT );
// now a little background: if oldrepos is both release and snapshot, we are
// forcibly splitting it into two. But, what should we do with it's existing
// storage? The same storage should not be used by release and snapshot repo
// simultaneously (think about metadata fix on the fly, it will always screw it)
}
repositories.add( newrepos );
}
newc.setRepositories( repositories );
if ( oldc.getRepositoryShadows() != null )
{
List<CRepositoryShadow> repositoryShadows = new ArrayList<CRepositoryShadow>( oldc
.getRepositoryShadows().size() );
for ( org.sonatype.nexus.configuration.model.v1_0_0.CRepositoryShadow oldshadow : (List<org.sonatype.nexus.configuration.model.v1_0_0.CRepositoryShadow>) oldc
.getRepositoryShadows() )
{
CRepositoryShadow newshadow = new CRepositoryShadow();
newshadow.setId( oldshadow.getId() );
newshadow.setName( oldshadow.getName() );
newshadow.setAvailable( true );
newshadow.setShadowOf( oldshadow.getShadowOf() );
newshadow.setType( oldshadow.getType() );
newshadow.setSyncAtStartup( oldshadow.isSyncAtStartup() );
newshadow.setRealmId( oldshadow.getRealmId() );
repositoryShadows.add( newshadow );
}
newc.setRepositoryShadows( repositoryShadows );
}
if ( oldc.getRepositoryGroups() != null )
{
CRepositoryGrouping repositoryGrouping = new CRepositoryGrouping();
if ( oldc.getRouting().getGroups().getPathMapping() != null )
{
ArrayList<CGroupsSettingPathMappingItem> mappings = new ArrayList<CGroupsSettingPathMappingItem>();
mappings.addAll( copyPathMappings1_0_0( true, oldc
.getRouting().getGroups().getPathMapping().getInclusions() ) );
mappings.addAll( copyPathMappings1_0_0( false, oldc
.getRouting().getGroups().getPathMapping().getExclusions() ) );
repositoryGrouping.setPathMappings( mappings );
}
List<CRepositoryGroup> repositoryGroups = new ArrayList<CRepositoryGroup>( oldc
.getRepositoryGroups().size() );
for ( org.sonatype.nexus.configuration.model.v1_0_0.CRepositoryGroup oldgroup : (List<org.sonatype.nexus.configuration.model.v1_0_0.CRepositoryGroup>) oldc
.getRepositoryGroups() )
{
CRepositoryGroup newgroup = new CRepositoryGroup();
newgroup.setGroupId( oldgroup.getGroupId() );
// both are List<String>
newgroup.setRepositories( oldgroup.getRepositories() );
repositoryGroups.add( newgroup );
}
repositoryGrouping.setRepositoryGroups( repositoryGroups );
newc.setRepositoryGrouping( repositoryGrouping );
}
message.setModelVersion( org.sonatype.nexus.configuration.model.v1_0_1.Configuration.MODEL_VERSION );
message.setConfiguration( newc );
}
protected List<CProps> copyCProps1_0_0( List<org.sonatype.nexus.configuration.model.v1_0_0.CProps> oldprops )
{
List<CProps> properties = new ArrayList<CProps>( oldprops.size() );
for ( org.sonatype.nexus.configuration.model.v1_0_0.CProps oldprop : oldprops )
{
CProps newprop = new CProps();
newprop.setKey( oldprop.getKey() );
newprop.setValue( oldprop.getValue() );
properties.add( newprop );
}
return properties;
}
protected List<CGroupsSettingPathMappingItem> copyPathMappings1_0_0( boolean isInclusion,
List<org.sonatype.nexus.configuration.model.v1_0_0.CProps> oldprops )
{
List<CGroupsSettingPathMappingItem> mappings = new ArrayList<CGroupsSettingPathMappingItem>( oldprops.size() );
int pathNum = 1;
for ( org.sonatype.nexus.configuration.model.v1_0_0.CProps oldprop : oldprops )
{
CGroupsSettingPathMappingItem item = new CGroupsSettingPathMappingItem();
item.setId( "migrated-" + ( isInclusion ? "I" : "E" ) + ( pathNum++ ) );
item.setRouteType( isInclusion
? CGroupsSettingPathMappingItem.INCLUSION_RULE_TYPE
: CGroupsSettingPathMappingItem.EXCLUSION_RULE_TYPE );
item.setRoutePattern( oldprop.getKey() );
String[] repoIds = oldprop.getValue().split( "," );
item.setRepositories( Arrays.asList( repoIds ) );
mappings.add( item );
}
return mappings;
}
protected CRemoteAuthentication copyCRemoteAuthentication1_0_0(
org.sonatype.nexus.configuration.model.v1_0_0.CRemoteAuthentication oldauth )
{
if ( oldauth != null )
{
CRemoteAuthentication newauth = new CRemoteAuthentication();
newauth.setUsername( oldauth.getUsername() );
newauth.setPassword( oldauth.getPassword() );
newauth.setNtlmHost( oldauth.getNtlmHost() );
newauth.setNtlmDomain( oldauth.getNtlmDomain() );
newauth.setPrivateKey( oldauth.getPrivateKey() );
newauth.setPassphrase( oldauth.getPassphrase() );
return newauth;
}
else
{
return null;
}
}
protected CRemoteConnectionSettings copyCRemoteConnectionSettings1_0_0(
org.sonatype.nexus.configuration.model.v1_0_0.CRemoteConnectionSettings old )
{
CRemoteConnectionSettings cs = new CRemoteConnectionSettings();
cs.setConnectionTimeout( old.getConnectionTimeout() );
cs.setRetrievalRetryCount( old.getRetrievalRetryCount() );
if ( old.getQueryString() != null )
{
cs.setQueryString( old.getQueryString() );
}
if ( old.getUserAgentString() != null )
{
cs.setUserAgentString( old.getUserAgentString() );
}
return cs;
}
protected CRemoteHttpProxySettings copyCRemoteHttpProxySettings1_0_0(
org.sonatype.nexus.configuration.model.v1_0_0.CRemoteHttpProxySettings old )
{
CRemoteHttpProxySettings cs = new CRemoteHttpProxySettings();
cs.setProxyHostname( old.getProxyHostname() );
cs.setProxyPort( old.getProxyPort() );
cs.setAuthentication( copyCRemoteAuthentication1_0_0( old.getAuthentication() ) );
return cs;
}
protected CRepository copyCRepository1_0_0( org.sonatype.nexus.configuration.model.v1_0_0.CRepository oldrepos )
{
CRepository newrepos = new CRepository();
newrepos.setId( oldrepos.getId() );
newrepos.setName( oldrepos.getName() );
newrepos.setAvailable( oldrepos.isAvailable() );
newrepos.setReadOnly( oldrepos.isReadOnly() );
newrepos.setBrowseable( oldrepos.isBrowseable() );
newrepos.setOffline( oldrepos.isOffline() );
newrepos.setIndexable( oldrepos.isIndexable() );
newrepos.setNotFoundCacheTTL( oldrepos.getNotFoundCacheTTL() );
newrepos.setArtifactMaxAge( oldrepos.getItemMaxAge() );
newrepos.setMetadataMaxAge( oldrepos.getItemMaxAge() );
newrepos.setRealmId( oldrepos.getRealmId() );
newrepos.setMaintainProxiedRepositoryMetadata( false );
if ( oldrepos.getLocalStorage() != null )
{
CLocalStorage localStorage = new CLocalStorage();
localStorage.setUrl( oldrepos.getLocalStorage().getUrl() );
newrepos.setLocalStorage( localStorage );
}
if ( oldrepos.getRemoteStorage() != null )
{
CRemoteStorage remoteStorage = new CRemoteStorage();
remoteStorage.setUrl( oldrepos.getRemoteStorage().getUrl() );
if ( oldrepos.getRemoteStorage().getAuthentication() != null )
{
remoteStorage.setAuthentication( copyCRemoteAuthentication1_0_0( oldrepos
.getRemoteStorage().getAuthentication() ) );
}
if ( oldrepos.getRemoteStorage().getConnectionSettings() != null )
{
remoteStorage.setConnectionSettings( copyCRemoteConnectionSettings1_0_0( oldrepos
.getRemoteStorage().getConnectionSettings() ) );
}
if ( oldrepos.getRemoteStorage().getHttpProxySettings() != null )
{
remoteStorage.setHttpProxySettings( copyCRemoteHttpProxySettings1_0_0( oldrepos
.getRemoteStorage().getHttpProxySettings() ) );
}
newrepos.setRemoteStorage( remoteStorage );
}
return newrepos;
}
}