All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.mojo.license.api.DefaultThirdPartyTool Maven / Gradle / Ivy

There is a newer version: 2.4.0
Show newest version
package org.codehaus.mojo.license.api;

/*
 * #%L
 * License Maven Plugin
 * %%
 * Copyright (C) 2011 CodeLutin, Codehaus, Tony Chemit
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser 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 Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.model.License;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.codehaus.mojo.license.LicenseMojoUtils;
import org.codehaus.mojo.license.model.LicenseMap;
import org.codehaus.mojo.license.utils.FileUtil;
import org.codehaus.mojo.license.utils.MojoHelper;
import org.codehaus.mojo.license.utils.SortedProperties;
import org.codehaus.mojo.license.utils.UrlRequester;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger;

/**
 * Default implementation of the third party tool.
 *
 * @author Tony Chemit
 * @version $Id$
 */
@Component( role = ThirdPartyTool.class, hint = "default" )
public class DefaultThirdPartyTool
        extends AbstractLogEnabled
        implements ThirdPartyTool
{
    /**
     * Classifier of the third-parties descriptor attached to a maven module.
     */
    private static final String DESCRIPTOR_CLASSIFIER = "third-party";

    /**
     * Type of the the third-parties descriptor attached to a maven module.
     */
    private static final String DESCRIPTOR_TYPE = "properties";

    /**
     * Pattern of a GAV plus a type.
     */
    private static final Pattern GAV_PLUS_TYPE_PATTERN = Pattern.compile( "(.+)--(.+)--(.+)--(.+)" );

    /**
     * Pattern of a GAV plus a type plus a classifier.
     */
    private static final Pattern GAV_PLUS_TYPE_AND_CLASSIFIER_PATTERN =
            Pattern.compile( "(.+)--(.+)--(.+)--(.+)--(.+)" );

    static final String LICENSE_DB_TYPE = "license.properties";

    // ----------------------------------------------------------------------
    // Components
    // ----------------------------------------------------------------------

    /**
     * The component that is used to resolve additional artifacts required.
     */
    @Requirement
    private ArtifactResolver artifactResolver;

    /**
     * The component used for creating artifact instances.
     */
    @Requirement
    private ArtifactFactory artifactFactory;

    /**
     * Maven ProjectHelper.
     */
    @Requirement
    private MavenProjectHelper projectHelper;

    /**
     * freeMarker helper.
     */
    private FreeMarkerHelper freeMarkerHelper = FreeMarkerHelper.newDefaultHelper();

    /**
     * Maven project comparator.
     */
    private final Comparator projectComparator = MojoHelper.newMavenProjectComparator();

    private boolean verbose;

    /**
     * {@inheritDoc}
     */
    public boolean isVerbose()
    {
        return verbose;
    }

    /**
     * {@inheritDoc}
     */
    public void setVerbose( boolean verbose )
    {
        this.verbose = verbose;
    }

    /**
     * {@inheritDoc}
     */
    public void attachThirdPartyDescriptor( MavenProject project, File file )
    {
        projectHelper.attachArtifact( project, DESCRIPTOR_TYPE, DESCRIPTOR_CLASSIFIER, file );
    }

    /**
     * {@inheritDoc}
     */
    public SortedSet getProjectsWithNoLicense( LicenseMap licenseMap, boolean doLog )
    {

        Logger log = getLogger();

        // get unsafe dependencies (says with no license)
        SortedSet unsafeDependencies = licenseMap.get( LicenseMap.UNKNOWN_LICENSE_MESSAGE );

        if ( doLog )
        {
            if ( CollectionUtils.isEmpty( unsafeDependencies ) )
            {
                log.debug( "There is no dependency with no license from poms." );
            }
            else
            {
                if ( log.isDebugEnabled() )
                {
                    boolean plural = unsafeDependencies.size() > 1;
                    String message = String.format( "There %s %d %s with no license from poms :",
                        plural ? "are" : "is",
                        unsafeDependencies.size(),
                        plural ? "dependencies" : "dependency" );
                    log.debug( message );
                    for ( MavenProject dep : unsafeDependencies )
                    {

                        // no license found for the dependency
                        log.debug( " - " + MojoHelper.getArtifactId( dep.getArtifact() ) );
                    }
                }
            }
        }

        return unsafeDependencies;
    }

    /**
     * {@inheritDoc}
     */
    public SortedProperties loadThirdPartyDescriptorsForUnsafeMapping( Set topLevelDependencies,
                                                                       String encoding,
                                                                       Collection projects,
                                                                       SortedSet unsafeDependencies,
                                                                       LicenseMap licenseMap,
                                                                       ArtifactRepository localRepository,
                                                                       List remoteRepositories )
            throws ThirdPartyToolException, IOException
    {

        SortedProperties result = new SortedProperties( encoding );
        Map unsafeProjects = new HashMap<>();
        for ( MavenProject unsafeDependency : unsafeDependencies )
        {
            String id = MojoHelper.getArtifactId( unsafeDependency.getArtifact() );
            unsafeProjects.put( id, unsafeDependency );
        }

        for ( MavenProject mavenProject : projects )
        {

            if ( CollectionUtils.isEmpty( unsafeDependencies ) )
            {

                // no more unsafe dependencies to find
                break;
            }

            File thirdPartyDescriptor = resolvThirdPartyDescriptor( mavenProject, localRepository, remoteRepositories );

            if ( thirdPartyDescriptor != null && thirdPartyDescriptor.exists() && thirdPartyDescriptor.length() > 0 )
            {

                if ( getLogger().isInfoEnabled() )
                {
                    getLogger().info( "Detects third party descriptor " + thirdPartyDescriptor );
                }

                // there is a third party file detected form the given dependency
                SortedProperties unsafeMappings = new SortedProperties( encoding );

                if ( thirdPartyDescriptor.exists() )
                {

                    getLogger().info( "Load missing file " + thirdPartyDescriptor );

                    // load the missing file
                    unsafeMappings.load( thirdPartyDescriptor );
                }
                resolveUnsafe( unsafeDependencies, licenseMap, unsafeProjects, unsafeMappings, result );
            }

        }
        try
        {
            loadGlobalLicenses( topLevelDependencies, localRepository, remoteRepositories, unsafeDependencies,
                                licenseMap, unsafeProjects, result );
        }
        catch ( ArtifactNotFoundException e )
        {
            throw new ThirdPartyToolException( "Failed to load global licenses", e );
        }
        catch ( ArtifactResolutionException e )
        {
            throw new ThirdPartyToolException( "Failed to load global licenses", e );
        }
        return result;
    }

    private void resolveUnsafe( SortedSet unsafeDependencies, LicenseMap licenseMap,
                                Map unsafeProjects, SortedProperties unsafeMappings,
                                SortedProperties result )
    {
        for ( String id : unsafeProjects.keySet() )
        {

            if ( unsafeMappings.containsKey( id ) )
            {

                String license = (String) unsafeMappings.get( id );
                if ( StringUtils.isEmpty( license ) )
                {

                    // empty license means not fill, skip it
                    continue;
                }

                // found a resolved unsafe dependency in the missing third party file
                MavenProject resolvedProject = unsafeProjects.get( id );
                unsafeDependencies.remove( resolvedProject );

                // push back to
                result.put( id, license.trim() );

                addLicense( licenseMap, resolvedProject, license );
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public File resolvThirdPartyDescriptor( MavenProject project, ArtifactRepository localRepository,
                                            List repositories )
            throws ThirdPartyToolException
    {
        if ( project == null )
        {
            throw new IllegalArgumentException( "The parameter 'project' can not be null" );
        }
        if ( localRepository == null )
        {
            throw new IllegalArgumentException( "The parameter 'localRepository' can not be null" );
        }
        if ( repositories == null )
        {
            throw new IllegalArgumentException( "The parameter 'remoteArtifactRepositories' can not be null" );
        }

        try
        {
            return resolveThirdPartyDescriptor( project, localRepository, repositories );
        }
        catch ( ArtifactNotFoundException e )
        {
            getLogger().debug( "ArtifactNotFoundException: Unable to locate third party descriptor: " + e );
            return null;
        }
        catch ( ArtifactResolutionException e )
        {
            throw new ThirdPartyToolException(
                    "ArtifactResolutionException: Unable to locate third party descriptor: " + e.getMessage(), e );
        }
        catch ( IOException e )
        {
            throw new ThirdPartyToolException(
                    "IOException: Unable to locate third party descriptor: " + e.getMessage(), e );
        }
    }

    /**
     * {@inheritDoc}
     */
    public void addLicense( LicenseMap licenseMap, MavenProject project, String... licenseNames )
    {
        List licenses = new ArrayList<>();
        for ( String licenseName : licenseNames )
        {
            License license = new License();
            license.setName( licenseName.trim() );
            license.setUrl( licenseName.trim() );
            licenses.add( license );
        }
        addLicense( licenseMap, project, licenses );
    }

    /**
     * {@inheritDoc}
     */
    public void addLicense( LicenseMap licenseMap, MavenProject project, License license )
    {
        addLicense( licenseMap, project, Collections.singletonList( license ) );
    }

    /**
     * {@inheritDoc}
     */
    public void addLicense( LicenseMap licenseMap, MavenProject project, List licenses )
    {

        if ( Artifact.SCOPE_SYSTEM.equals( project.getArtifact().getScope() ) )
        {

            // do NOT treat system dependency
            return;
        }

        if ( CollectionUtils.isEmpty( licenses ) )
        {

            // no license found for the dependency
            licenseMap.put( LicenseMap.UNKNOWN_LICENSE_MESSAGE, project );
            return;
        }

        for ( Object o : licenses )
        {
            String id = MojoHelper.getArtifactId( project.getArtifact() );
            if ( o == null )
            {
                getLogger().warn( "could not acquire the license for " + id );
                continue;
            }
            License license = (License) o;
            String licenseKey = license.getName();

            // tchemit 2010-08-29 Ano #816 Check if the License object is well formed

            if ( StringUtils.isEmpty( license.getName() ) )
            {
                getLogger().warn( "The license for " + id + " has no name (but exist)" );
                licenseKey = license.getUrl();
            }

            if ( StringUtils.isEmpty( licenseKey ) )
            {
                getLogger().warn( "No license url defined for " + id );
                licenseKey = LicenseMap.UNKNOWN_LICENSE_MESSAGE;
            }
            licenseMap.put( licenseKey, project );
        }
    }

    /**
     * {@inheritDoc}
     */
    public void mergeLicenses( LicenseMap licenseMap, String mainLicense, Set licenses )
    {

        if ( licenses.isEmpty() )
        {

            // nothing to merge, is this can really happen ?
            return;
        }

        SortedSet mainSet = licenseMap.get( mainLicense );
        if ( mainSet == null )
        {
            if ( isVerbose() )
            {
                getLogger().warn( "No license [" + mainLicense + "] found, will create it." );
            }
            mainSet = new TreeSet<>( projectComparator );
            licenseMap.put( mainLicense, mainSet );
        }
        for ( String license : licenses )
        {
            SortedSet set = licenseMap.get( license );
            if ( set == null )
            {
                if ( isVerbose() )
                {
                    getLogger().warn( "No license [" + license + "] found, skip the merge to [" + mainLicense + "]" );
                }
                continue;
            }
            if ( isVerbose() )
            {
                getLogger().info(
                        "Merge license [" + license + "] to [" + mainLicense + "] (" + set.size() + " dependencies)." );
            }
            mainSet.addAll( set );
            set.clear();
            licenseMap.remove( license );
        }
    }

    /**
     * {@inheritDoc}
     */
    public SortedProperties loadUnsafeMapping( LicenseMap licenseMap,
                                               SortedMap artifactCache,
                                               String encoding,
                                               File missingFile,
                                               String missingFileUrl ) throws IOException, MojoExecutionException
    {
        Map snapshots = new HashMap<>();

        //find snapshot dependencies
        for ( Map.Entry entry : artifactCache.entrySet() )
        {
            MavenProject mavenProject = entry.getValue();
            if ( mavenProject.getVersion().endsWith( Artifact.SNAPSHOT_VERSION ) )
            {
                snapshots.put( entry.getKey(), mavenProject );
            }
        }

        for ( Map.Entry snapshot : snapshots.entrySet() )
        {
            // remove invalid entries, which contain timestamps in key
            artifactCache.remove( snapshot.getKey() );
            // put corrected keys/entries into artifact cache
            MavenProject mavenProject = snapshot.getValue();

            String id = MojoHelper.getArtifactId( mavenProject.getArtifact() );
            artifactCache.put( id, mavenProject );

        }
        SortedSet unsafeDependencies = getProjectsWithNoLicense( licenseMap, false );

        SortedProperties unsafeMappings = new SortedProperties( encoding );

        if ( missingFile.exists() )
        {
            // there is some unsafe dependencies

            getLogger().info( "Load missing file " + missingFile );

            // load the missing file
            unsafeMappings.load( missingFile );
        }
        if ( UrlRequester.isStringUrl( missingFileUrl ) )
        {
            String httpRequestResult = UrlRequester.getFromUrl( missingFileUrl );
            unsafeMappings.load( new ByteArrayInputStream( httpRequestResult.getBytes() ) );
        }

        // get from the missing file, all unknown dependencies
        List unknownDependenciesId = new ArrayList<>();

        // coming from maven-license-plugin, we used the full g/a/v/c/t. Now we remove classifier and type
        // since GAV is good enough to qualify a license of any artifact of it...
        Map migrateKeys = migrateMissingFileKeys( unsafeMappings.keySet() );

        for ( Object o : migrateKeys.keySet() )
        {
            String id = (String) o;
            String migratedId = migrateKeys.get( id );

            MavenProject project = artifactCache.get( migratedId );
            if ( project == null )
            {
                // now we are sure this is a unknown dependency
                unknownDependenciesId.add( id );
            }
            else
            {
                if ( !id.equals( migratedId ) )
                {

                    // migrates id to migratedId
                    getLogger().info( "Migrates [" + id + "] to [" + migratedId + "] in the missing file." );
                    Object value = unsafeMappings.get( id );
                    unsafeMappings.remove( id );
                    unsafeMappings.put( migratedId, value );
                }
            }
        }

        if ( !unknownDependenciesId.isEmpty() )
        {

            // there is some unknown dependencies in the missing file, remove them
            for ( String id : unknownDependenciesId )
            {
                getLogger().warn(
                        "dependency [" + id + "] does not exist in project, remove it from the missing file." );
                unsafeMappings.remove( id );
            }

            unknownDependenciesId.clear();
        }

        // push back loaded dependencies
        for ( Object o : unsafeMappings.keySet() )
        {
            String id = (String) o;

            MavenProject project = artifactCache.get( id );
            if ( project == null )
            {
                getLogger().warn( "dependency [" + id + "] does not exist in project." );
                continue;
            }

            String license = (String) unsafeMappings.get( id );

            String[] licenses = StringUtils.split( license, '|' );

            if ( ArrayUtils.isEmpty( licenses ) )
            {

                // empty license means not fill, skip it
                continue;
            }

            // add license in map
            addLicense( licenseMap, project, licenses );

            // remove unknown license
            unsafeDependencies.remove( project );
        }

        if ( unsafeDependencies.isEmpty() )
        {

            // no more unknown license in map
            licenseMap.remove( LicenseMap.UNKNOWN_LICENSE_MESSAGE );
        }
        else
        {

            // add a "with no value license" for missing dependencies
            for ( MavenProject project : unsafeDependencies )
            {
                String id = MojoHelper.getArtifactId( project.getArtifact() );
                if ( getLogger().isDebugEnabled() )
                {
                    getLogger().debug( "dependency [" + id + "] has no license, add it in the missing file." );
                }
                unsafeMappings.setProperty( id, "" );
            }
        }
        return unsafeMappings;
    }

    /**
     * {@inheritDoc}
     */
    public void overrideLicenses( LicenseMap licenseMap, SortedMap artifactCache, String encoding,
            String overrideUrl ) throws IOException
    {
        if ( LicenseMojoUtils.isValid( overrideUrl ) )
        {
            final SortedProperties overrideMappings = new SortedProperties( encoding );
            try ( Reader reader = new StringReader( UrlRequester.getFromUrl( overrideUrl, encoding ) ) )
            {
                overrideMappings.load( reader );
            }
            for ( Object o : overrideMappings.keySet() )
            {
                String id = (String) o;

                MavenProject project = artifactCache.get( id );
                if ( project == null )
                {
                    getLogger().warn( "dependency [" + id + "] does not exist in project." );
                    continue;
                }

                String license = (String) overrideMappings.get( id );

                String[] licenses = StringUtils.split( license, '|' );

                if ( ArrayUtils.isEmpty( licenses ) )
                {

                    // empty license means not fill, skip it
                    continue;
                }

                licenseMap.removeProject( project );

                // add license in map
                addLicense( licenseMap, project, licenses );

            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void writeThirdPartyFile( LicenseMap licenseMap, File thirdPartyFile, boolean verbose, String encoding,
                                     String lineFormat )
            throws IOException
    {

        Logger log = getLogger();

        Map properties = new HashMap<>();
        properties.put( "licenseMap", licenseMap.entrySet() );
        properties.put( "dependencyMap", licenseMap.toDependencyMap().entrySet() );
        String content = freeMarkerHelper.renderTemplate( lineFormat, properties );

        log.info( "Writing third-party file to " + thirdPartyFile );
        if ( verbose )
        {
            log.info( content );
        }

        FileUtil.printString( thirdPartyFile, content, encoding );

    }

    /**
     * {@inheritDoc}
     */
    public void writeBundleThirdPartyFile( File thirdPartyFile, File outputDirectory, String bundleThirdPartyPath )
            throws IOException
    {

        // creates the bundled license file
        File bundleTarget = FileUtil.getFile( outputDirectory, bundleThirdPartyPath );
        getLogger().info( "Writing bundled third-party file to " + bundleTarget );
        FileUtil.copyFile( thirdPartyFile, bundleTarget );
    }

    private void loadGlobalLicenses( Set dependencies, ArtifactRepository localRepository,
                                     List repositories, SortedSet unsafeDependencies,
                                     LicenseMap licenseMap, Map unsafeProjects,
                                     SortedProperties result )
            throws IOException, ArtifactNotFoundException, ArtifactResolutionException
    {
        for ( Artifact dep : dependencies )
        {
            if ( LICENSE_DB_TYPE.equals( dep.getType() ) )
            {
                loadOneGlobalSet( unsafeDependencies, licenseMap, unsafeProjects, dep, localRepository, repositories,
                                  result );
            }
        }
    }

    private void loadOneGlobalSet( SortedSet unsafeDependencies, LicenseMap licenseMap,
                                   Map unsafeProjects, Artifact dep,
                                   ArtifactRepository localRepository, List repositories,
                                   SortedProperties result )
            throws IOException, ArtifactNotFoundException, ArtifactResolutionException
    {
        artifactResolver.resolve( dep, repositories, localRepository );
        File propFile = dep.getFile();
        getLogger().info(
                String.format( "Loading global license map from %s: %s", dep.toString(), propFile.getAbsolutePath() ) );
        SortedProperties props = new SortedProperties( "utf-8" );
        InputStream propStream = null;

        try
        {
            propStream = new FileInputStream( propFile );
            props.load( propStream );
        }
        finally
        {
            IOUtils.closeQuietly( propStream );
        }

        for ( Object keyObj : props.keySet() )
        {
            String key = (String) keyObj;
            String val = (String) props.get( key );
            result.put( key, val );
        }

        resolveUnsafe( unsafeDependencies, licenseMap, unsafeProjects, props, result );
    }

    // ----------------------------------------------------------------------
    // Private methods
    // ----------------------------------------------------------------------

    /**
     * @param project         not null
     * @param localRepository not null
     * @param repositories    not null
     * @return the resolved site descriptor
     * @throws IOException                 if any
     * @throws ArtifactResolutionException if any
     * @throws ArtifactNotFoundException   if any
     */
    private File resolveThirdPartyDescriptor( MavenProject project, ArtifactRepository localRepository,
                                              List repositories )
            throws IOException, ArtifactResolutionException, ArtifactNotFoundException
    {
        File result;
        try
        {
            result = resolveArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(),
                                      DESCRIPTOR_TYPE, DESCRIPTOR_CLASSIFIER, localRepository, repositories );

            // we use zero length files to avoid re-resolution (see below)
            if ( result.length() == 0 )
            {
                getLogger().debug( "Skipped third party descriptor" );
            }
        }
        catch ( ArtifactNotFoundException e )
        {
            getLogger().debug( "Unable to locate third party files descriptor : " + e );

            Artifact artifact = e.getArtifact() == null
                    ? artifactFactory.createArtifactWithClassifier(
                    project.getGroupId(), project.getArtifactId(), project.getVersion(),
                    DESCRIPTOR_TYPE, DESCRIPTOR_CLASSIFIER )
                    : e.getArtifact();

            // we can afford to write an empty descriptor here as we don't expect it to turn up later in the remote
            // repository, because the parent was already released (and snapshots are updated automatically if changed)
            result = new File( localRepository.getBasedir(), localRepository.pathOf( artifact ) );
        }

        return result;
    }

    public File resolveMissingLicensesDescriptor( String groupId, String artifactId, String version,
            ArtifactRepository localRepository, List repositories )
            throws IOException, ArtifactResolutionException, ArtifactNotFoundException
    {
        return resolveArtifact( groupId, artifactId, version, DESCRIPTOR_TYPE, DESCRIPTOR_CLASSIFIER, localRepository,
                repositories );
    }

    private File resolveArtifact( String groupId, String artifactId, String version,
            String type, String classifier, ArtifactRepository localRepository, List repositories )
                    throws ArtifactResolutionException, IOException, ArtifactNotFoundException
    {
        // TODO: this is a bit crude - proper type, or proper handling as metadata rather than an artifact in 2.1?
        Artifact artifact = artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type,
                                                                          classifier );

        artifactResolver.resolve( artifact, repositories, localRepository );

        return artifact.getFile();
    }

    private Map migrateMissingFileKeys( Set missingFileKeys )
    {
        Map migrateKeys = new HashMap<>();
        for ( Object object : missingFileKeys )
        {
            String id = (String) object;
            Matcher matcher;

            String newId = id;
            matcher = GAV_PLUS_TYPE_AND_CLASSIFIER_PATTERN.matcher( id );
            if ( matcher.matches() )
            {
                newId = matcher.group( 1 ) + "--" + matcher.group( 2 ) + "--" + matcher.group( 3 );

            }
            else
            {
                matcher = GAV_PLUS_TYPE_PATTERN.matcher( id );
                if ( matcher.matches() )
                {
                    newId = matcher.group( 1 ) + "--" + matcher.group( 2 ) + "--" + matcher.group( 3 );

                }
            }
            migrateKeys.put( id, newId );
        }
        return migrateKeys;
    }
}