/* * Copyright (c) 2010 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see * <http://www.gnu.org/licenses>. */ package com.redhat.rcm.version.mgr.session; import static com.redhat.rcm.version.util.InputUtils.parseProperties; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.apache.maven.mae.project.key.FullProjectKey; import org.apache.maven.mae.project.key.ProjectKey; import org.apache.maven.mae.project.key.VersionlessProjectKey; import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; import org.apache.maven.model.Parent; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginManagement; import org.apache.maven.project.MavenProject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.redhat.rcm.version.Cli; import com.redhat.rcm.version.VManException; import com.redhat.rcm.version.maven.WildcardProjectKey; import com.redhat.rcm.version.model.DependencyManagementKey; import com.redhat.rcm.version.model.Project; class ManagedInfo { private final Logger logger = LoggerFactory.getLogger( getClass() ); private static final String RELOCATIONS_KEY = "relocations"; private static final String MAPPINGS_KEY = "mapping"; private final Map<FullProjectKey, File> peekedPoms = new HashMap<FullProjectKey, File>(); private final Map<File, FullProjectKey> peekedPomsReverse = new HashMap<File, FullProjectKey>(); private final LinkedHashMap<FullProjectKey, MavenProject> bomProjects = new LinkedHashMap<FullProjectKey, MavenProject>(); private final CoordinateRelocations relocatedCoords; private final PropertyMappings propertyMappings; private final Map<DependencyManagementKey, Dependency> depMap = new HashMap<DependencyManagementKey, Dependency>(); private final Map<File, Map<DependencyManagementKey, String>> bomDepMap = new HashMap<File, Map<DependencyManagementKey, String>>(); private final Map<VersionlessProjectKey, Plugin> managedPlugins = new LinkedHashMap<VersionlessProjectKey, Plugin>(); private final Map<VersionlessProjectKey, Plugin> injectedPlugins = new LinkedHashMap<VersionlessProjectKey, Plugin>(); private FullProjectKey toolchainKey; private final Set<VersionlessProjectKey> removedPlugins = new HashSet<VersionlessProjectKey>(); private final List<WildcardProjectKey> removedTests = new ArrayList<WildcardProjectKey>(); private final Set<VersionlessProjectKey> extensionsWhitelist = new HashSet<VersionlessProjectKey>(); private final LinkedHashSet<Project> currentProjects = new LinkedHashSet<Project>(); private final Map<VersionlessProjectKey, Project> currentProjectsByKey = new LinkedHashMap<VersionlessProjectKey, Project>(); private final List<String> modderKeys = new ArrayList<String>(); private MavenProject toolchainProject; private final Set<VersionlessProjectKey> excludedModulePoms; private final Map<String, String> userProperties; ManagedInfo( final VersionManagerSession session, final Collection<String> removedPlugins, final Collection<String> removedTests, final Collection<String> extensionsWhitelist, final List<String> modderKeys, final Map<String, String> relocatedCoords, final Map<String, String> propertyMappings, final Set<VersionlessProjectKey> excludedModulePoms, final Map<String, String> userProperties ) { this.excludedModulePoms = excludedModulePoms; this.userProperties = userProperties; this.relocatedCoords = new CoordinateRelocations( relocatedCoords, session ); this.propertyMappings = new PropertyMappings( propertyMappings ); if ( removedPlugins != null ) { for ( final String rm : removedPlugins ) { this.removedPlugins.add( new VersionlessProjectKey( rm ) ); } } if ( removedTests != null ) { for ( final String rm : removedTests ) { this.removedTests.add( new WildcardProjectKey( rm ) ); } } if ( extensionsWhitelist != null ) { for ( final String rm : extensionsWhitelist ) { this.extensionsWhitelist.add( new VersionlessProjectKey( rm ) ); } } if ( modderKeys != null ) { for ( final String key : modderKeys ) { this.modderKeys.add( key ); } } } boolean hasDependencyMap() { return !depMap.isEmpty(); } Dependency getManagedDependency( final DependencyManagementKey key ) { return depMap.get( key ); } Map<File, Map<DependencyManagementKey, String>> getMappedDependenciesByBom() { return bomDepMap; } void mapDependency( final File srcBom, final Dependency dep ) { final DependencyManagementKey key = new DependencyManagementKey( dep ); final String version = dep.getVersion(); if ( !depMap.containsKey( key ) ) { depMap.put( key, dep ); Map<DependencyManagementKey, String> bomMap = bomDepMap.get( srcBom ); if ( bomMap == null ) { bomMap = new HashMap<DependencyManagementKey, String>(); bomDepMap.put( srcBom, bomMap ); } bomMap.put( key, version ); } } private void startBomMap( final File srcBom, final String groupId, final String artifactId, final String version ) { final DependencyManagementKey bomKey = new DependencyManagementKey( groupId, artifactId, "pom", null ); final Dependency dep = new Dependency(); dep.setGroupId( groupId ); dep.setArtifactId( artifactId ); dep.setVersion( version ); dep.setScope( "import" ); dep.setType( "pom" ); depMap.put( bomKey, dep ); Map<DependencyManagementKey, String> bomMap = bomDepMap.get( srcBom ); if ( bomMap == null ) { bomMap = new HashMap<DependencyManagementKey, String>(); bomDepMap.put( srcBom, bomMap ); } bomMap.put( bomKey, version ); } void addBOM( final File bom, final MavenProject project ) throws VManException { final FullProjectKey key = new FullProjectKey( project.getGroupId(), project.getArtifactId(), project.getVersion() ); if ( bomProjects.containsKey( key ) ) { return; } bomProjects.put( key, project ); startBomMap( bom, project.getGroupId(), project.getArtifactId(), project.getVersion() ); if ( project.getDependencyManagement() != null && project.getDependencyManagement() .getDependencies() != null ) { for ( final Dependency dep : project.getDependencyManagement() .getDependencies() ) { mapDependency( bom, dep ); } } final Properties properties = project.getProperties(); if ( properties != null ) { final String relocations = properties.getProperty( RELOCATIONS_KEY ); if ( relocations != null ) { logger.info( "Got relocations:\n\n" + relocations ); logger.warn( "[DEPRECATED] BOM-based coordinate relocations have been replaced by the " + Cli.RELOCATIONS_PROPERTY + " configuration, which specifies a URL to a properties file. Please use this instead." ); relocatedCoords.addBomRelocations( bom, parseProperties( relocations ) ); } final String mappings = properties.getProperty( MAPPINGS_KEY ); if ( mappings != null ) { logger.info( "Got mappings:\n\n" + mappings ); logger.warn( "[DEPRECATED] BOM-based property mappings have been replaced by the " + Cli.PROPERTY_MAPPINGS_PROPERTY + " configuration, which specifies a URL to a properties file. Please use this instead." ); propertyMappings.addBomPropertyMappings( bom, project.getProperties(), parseProperties( mappings ) ); } else { propertyMappings.addBomPropertyMappings( bom, project.getProperties ()); } } logger.info( "Updating property mappings from " + project.getId() ); // NOTE: parent properties are inherited into the BOM by the time the MavenProject instance // is created, so we don't need to traverse up to the parent; we should have everything here. propertyMappings.updateProjectMap( project.getProperties() ); } FullProjectKey getRelocation( final ProjectKey key ) { return relocatedCoords.getRelocation( key ); } List<FullProjectKey> getBomCoords() { return new ArrayList<FullProjectKey>( bomProjects.keySet() ); } CoordinateRelocations getRelocations() { return relocatedCoords; } void setToolchain( final File toolchainFile, final MavenProject project ) { toolchainKey = new FullProjectKey( project ); this.toolchainProject = project; final PluginManagement pm = project.getPluginManagement(); if ( pm != null ) { for ( final Plugin plugin : pm.getPlugins() ) { managedPlugins.put( new VersionlessProjectKey( plugin ), plugin ); } } final Model model = project.getOriginalModel(); final Build build = model.getBuild(); if ( build != null ) { final List<Plugin> plugins = build.getPlugins(); if ( plugins != null ) { for ( final Plugin plugin : plugins ) { final VersionlessProjectKey key = new VersionlessProjectKey( plugin ); injectedPlugins.put( key, plugin ); if ( !managedPlugins.containsKey( key ) && plugin.getVersion() != null ) { injectedPlugins.put( key, plugin ); } } } } } Set<VersionlessProjectKey> getRemovedPlugins() { return removedPlugins; } List<WildcardProjectKey> getRemovedTests() { return removedTests; } /** NEVER null. */ Set<VersionlessProjectKey> getExtensionsWhitelist() { return extensionsWhitelist; } List<String> getModderKeys() { return modderKeys; } FullProjectKey getToolchainKey() { return toolchainKey; } Plugin getManagedPlugin( final VersionlessProjectKey key ) { return managedPlugins.get( key ); } Map<VersionlessProjectKey, Plugin> getInjectedPlugins() { return injectedPlugins; } boolean hasBom( final FullProjectKey key ) { return bomProjects.containsKey( key ); } boolean isToolchainReference( final Parent parent ) { return toolchainKey == null ? false : new VersionlessProjectKey( toolchainKey ).equals( new VersionlessProjectKey( parent ) ); } synchronized void setCurrentProjects( final Set<Project> projects ) { currentProjects.clear(); currentProjectsByKey.clear(); for ( final Project project : projects ) { currentProjects.add( project ); currentProjectsByKey.put( toVersionlessKey( project.getKey() ), project ); } } synchronized void setPeekedPoms( final Map<FullProjectKey, File> peekedPoms ) { if ( peekedPoms == null || peekedPoms.isEmpty() ) { return; } this.peekedPoms.clear(); for ( final Map.Entry<FullProjectKey, File> entry : peekedPoms.entrySet() ) { // if ( excludedModulePoms != null // && excludedModulePoms.contains( new VersionlessProjectKey( entry.getKey() ) ) ) // { // continue; // } this.peekedPoms.put( entry.getKey(), entry.getValue() ); this.peekedPomsReverse.put( entry.getValue(), entry.getKey() ); } } boolean isExcludedModulePom( final File pom ) { final FullProjectKey key = peekedPomsReverse.get( pom ); if ( key == null ) { return false; } final VersionlessProjectKey vpk = new VersionlessProjectKey( key ); return excludedModulePoms.contains( vpk ); } LinkedHashSet<Project> getCurrentProjects() { return currentProjects; } boolean isCurrentProject( final ProjectKey key ) { final VersionlessProjectKey vk = toVersionlessKey( key ); return currentProjectsByKey.containsKey( vk ); } PropertyMappings getPropertyMapping() { return propertyMappings; } Project getCurrentProject( final ProjectKey key ) { return currentProjectsByKey.get( toVersionlessKey( key ) ); } File getPeekedPom( final FullProjectKey key ) { logger.info( "STORE: Peeked POM for: '{}' is: {}", key, peekedPoms.get( key ) ); return peekedPoms.get( key ); } private VersionlessProjectKey toVersionlessKey( final ProjectKey key ) { return (VersionlessProjectKey) ( key instanceof FullProjectKey ? new VersionlessProjectKey( key ) : key ); } MavenProject getToolchainProject() { return toolchainProject; } MavenProject getBOMProject( final FullProjectKey key ) { return bomProjects.get( key ); } Map<FullProjectKey, File> getPeekedPoms() { return peekedPoms; } void addPeekPom( final FullProjectKey key, final File pom ) { peekedPoms.put( key, pom ); } Set<VersionlessProjectKey> getExcludedModulePoms() { return excludedModulePoms; } String getUserProperty( final String key ) { return userProperties == null ? null : userProperties.get( key ); } }