<commit_before>package org.apache.maven.artifact.repository.metadata;

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to you 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.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
import org.apache.maven.artifact.repository.RepositoryCache;
import org.apache.maven.artifact.repository.RepositoryRequest;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
import org.apache.maven.repository.legacy.UpdateCheckManager;
import org.apache.maven.repository.legacy.WagonManager;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 * @author <NAME>
 */
@Component(role=RepositoryMetadataManager.class)
public class DefaultRepositoryMetadataManager
    extends AbstractLogEnabled
    implements RepositoryMetadataManager
{
    @Requirement
    private WagonManager wagonManager;

    @Requirement
    private UpdateCheckManager updateCheckManager;

    public void resolve( RepositoryMetadata metadata, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository )
        throws RepositoryMetadataResolutionException
    {
        RepositoryRequest request = new DefaultRepositoryRequest();
        request.setLocalRepository( localRepository );
        request.setRemoteRepositories( remoteRepositories );
        resolve( metadata, request );
    }

    public void resolve( RepositoryMetadata metadata, RepositoryRequest request )
        throws RepositoryMetadataResolutionException
    {
        RepositoryCache cache = request.getCache();

        CacheKey cacheKey = null;

        if ( cache != null )
        {
            cacheKey = new CacheKey( metadata, request );

            CacheRecord cacheRecord = (CacheRecord) cache.get( request, cacheKey );

            if ( cacheRecord != null )
            {
                if ( getLogger().isDebugEnabled() )
                {
                    getLogger().debug( "Resolved metadata from cache: " + metadata + " @ " + cacheRecord.repository );
                }

                metadata.setMetadata( MetadataUtils.cloneMetadata( cacheRecord.metadata ) );

                if ( cacheRecord.repository != null )
                {
                    for ( ArtifactRepository repository : request.getRemoteRepositories() )
                    {
                        if ( cacheRecord.repository.equals( repository.getId() ) )
                        {
                            metadata.setRepository( repository );
                            break;
                        }
                    }
                }

                return;
            }
        }

        ArtifactRepository localRepository = request.getLocalRepository();
        List<ArtifactRepository> remoteRepositories = request.getRemoteRepositories();

        if ( !request.isOffline() )
        {
            for ( ArtifactRepository repository : remoteRepositories )
            {
                ArtifactRepositoryPolicy policy =
                    metadata.isSnapshot() ? repository.getSnapshots() : repository.getReleases();

                File file =
                    new File( localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata( metadata,
                                                                                                           repository ) );

                if ( ( policy.isEnabled() && request.isForceUpdate() )
                    || updateCheckManager.isUpdateRequired( metadata, repository, file ) )
                {
                    getLogger().info( metadata.getKey() + ": checking for updates from " + repository.getId() );
                    try
                    {
                        wagonManager.getArtifactMetadata( metadata, repository, file, policy.getChecksumPolicy() );
                    }
                    catch ( ResourceDoesNotExistException e )
                    {
                        getLogger().debug( metadata + " could not be found on repository: " + repository.getId() );

                        // delete the local copy so the old details aren't used.
                        if ( file.exists() )
                        {
                            file.delete();
                        }
                    }
                    catch ( TransferFailedException e )
                    {
                        getLogger().warn( metadata + " could not be retrieved from repository: " + repository.getId()
                                              + " due to an error: " + e.getMessage() );
                        getLogger().debug( "Exception", e );
                    }
                    finally
                    {
                        updateCheckManager.touch( metadata, repository, file );
                    }
                }

                // TODO: should this be inside the above check?
                // touch file so that this is not checked again until interval has passed
                if ( file.exists() )
                {
                    file.setLastModified( System.currentTimeMillis() );
                }
            }
        }

        try
        {
            mergeMetadata( metadata, remoteRepositories, localRepository );
        }
        catch ( RepositoryMetadataStoreException e )
        {
            throw new RepositoryMetadataResolutionException( "Unable to store local copy of metadata: " + e.getMessage(), e );
        }

        if ( cache != null )
        {
            cache.put( request, cacheKey, new CacheRecord( metadata ) );
        }
    }

    private static final class CacheKey
    {

        final Object metadataKey;

        final ArtifactRepository localRepository;

        final List<ArtifactRepository> remoteRepositories;

        final int hashCode;

        CacheKey( RepositoryMetadata metadata, RepositoryRequest request )
        {
            metadataKey = metadata.getKey();
            localRepository = request.getLocalRepository();
            remoteRepositories = request.getRemoteRepositories();

            int hash = 17;
            hash = hash * 31 + metadata.getKey().hashCode();
            hash = hash * 31 + repoHashCode( localRepository );
            for ( ArtifactRepository remoteRepository : remoteRepositories )
            {
                hash = hash * 31 + repoHashCode( remoteRepository );
            }
            hashCode = hash;
        }<commit_msg>[MNG-4326] Maven should not check snapshot repositories for dependencies in the reactor<commit_after>package org.apache.maven.artifact.repository.metadata;

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to you 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.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
import org.apache.maven.artifact.repository.RepositoryCache;
import org.apache.maven.artifact.repository.RepositoryRequest;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
import org.apache.maven.repository.legacy.UpdateCheckManager;
import org.apache.maven.repository.legacy.WagonManager;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 * @author <NAME>
 */
@Component(role=RepositoryMetadataManager.class)
public class DefaultRepositoryMetadataManager
    extends AbstractLogEnabled
    implements RepositoryMetadataManager
{
    @Requirement
    private WagonManager wagonManager;

    @Requirement
    private UpdateCheckManager updateCheckManager;

    public void resolve( RepositoryMetadata metadata, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository )
        throws RepositoryMetadataResolutionException
    {
        RepositoryRequest request = new DefaultRepositoryRequest();
        request.setLocalRepository( localRepository );
        request.setRemoteRepositories( remoteRepositories );
        resolve( metadata, request );
    }

    public void resolve( RepositoryMetadata metadata, RepositoryRequest request )
        throws RepositoryMetadataResolutionException
    {
        RepositoryCache cache = request.getCache();

        CacheKey cacheKey = null;

        if ( cache != null )
        {
            cacheKey = new CacheKey( metadata, request );

            CacheRecord cacheRecord = (CacheRecord) cache.get( request, cacheKey );

            if ( cacheRecord != null )
            {
                if ( getLogger().isDebugEnabled() )
                {
                    getLogger().debug( "Resolved metadata from cache: " + metadata + " @ " + cacheRecord.repository );
                }

                metadata.setMetadata( MetadataUtils.cloneMetadata( cacheRecord.metadata ) );

                if ( cacheRecord.repository != null )
                {
                    for ( ArtifactRepository repository : request.getRemoteRepositories() )
                    {
                        if ( cacheRecord.repository.equals( repository.getId() ) )
                        {
                            metadata.setRepository( repository );
                            break;
                        }
                    }
                }

                return;
            }
        }

        ArtifactRepository localRepository = request.getLocalRepository();
        List<ArtifactRepository> remoteRepositories = request.getRemoteRepositories();

        if ( !request.isOffline() )
        {
            Date localCopyLastModified = getLocalCopyLastModified( localRepository, metadata );

            for ( ArtifactRepository repository : remoteRepositories )
            {
                ArtifactRepositoryPolicy policy =
                    metadata.isSnapshot() ? repository.getSnapshots() : repository.getReleases();

                File file =
                    new File( localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata( metadata,
                                                                                                           repository ) );
                boolean update;

                if ( !policy.isEnabled() )
                {
                    update = false;

                    if ( getLogger().isDebugEnabled() )
                    {
                        getLogger().debug(
                                           "Skipping update check for " + metadata.getKey() + " (" + file
                                               + ") from disabled repository " + repository.getId() + " ("
                                               + repository.getUrl() + ")" );
                    }
                }
                else if ( request.isForceUpdate() )
                {
                    update = true;
                }
                else if ( localCopyLastModified != null && !policy.checkOutOfDate( localCopyLastModified ) )
                {
                    update = false;

                    if ( getLogger().isDebugEnabled() )
                    {
                        getLogger().debug(
                                           "Skipping update check for " + metadata.getKey() + " (" + file
                                               + ") from repository " + repository.getId() + " (" + repository.getUrl()
                                               + ") in favor of local copy" );
                    }
                }
                else if ( updateCheckManager.isUpdateRequired( metadata, repository, file ) )
                {
                    update = true;
                }
                else
                {
                    update = false;
                }

                if ( update )
                {
                    getLogger().info( metadata.getKey() + ": checking for updates from " + repository.getId() );
                    try
                    {
                        wagonManager.getArtifactMetadata( metadata, repository, file, policy.getChecksumPolicy() );
                    }
                    catch ( ResourceDoesNotExistException e )
                    {
                        getLogger().debug( metadata + " could not be found on repository: " + repository.getId() );

                        // delete the local copy so the old details aren't used.
                        if ( file.exists() )
                        {
                            file.delete();
                        }
                    }
                    catch ( TransferFailedException e )
                    {
                        getLogger().warn( metadata + " could not be retrieved from repository: " + repository.getId()
                                              + " due to an error: " + e.getMessage() );
                        getLogger().debug( "Exception", e );
                    }
                    finally
                    {
                        updateCheckManager.touch( metadata, repository, file );
                    }
                }

                // TODO: should this be inside the above check?
                // touch file so that this is not checked again until interval has passed
                if ( file.exists() )
                {
                    file.setLastModified( System.currentTimeMillis() );
                }
            }
        }

        try
        {
            mergeMetadata( metadata, remoteRepositories, localRepository );
        }
        catch ( RepositoryMetadataStoreException e )
        {
            throw new RepositoryMetadataResolutionException( "Unable to store local copy of metadata: " + e.getMessage(), e );
        }

        if ( cache != null )
        {
            cache.put( request, cacheKey, new CacheRecord( metadata ) );
        }
    }

    private Date getLocalCopyLastModified( ArtifactRepository localRepository, RepositoryMetadata metadata )
    {
        String metadataPath = localRepository.pathOfLocalRepositoryMetadata( metadata, localRepository );
        File metadataFile = new File( localRepository.getBasedir(), metadataPath );
        return metadataFile.isFile() ? new Date( metadataFile.lastModified() ) : null;
    }

    private static final class CacheKey
    {

        final Object metadataKey;

        final ArtifactRepository localRepository;

        final List<ArtifactRepository> remoteRepositories;

        final int hashCode;

        CacheKey( RepositoryMetadata metadata, RepositoryRequest request )
        {
            metadataKey = metadata.getKey();
            localRepository = request.getLocalRepository();
            remoteRepositories = request.getRemoteRepositories();

            int hash = 17;
            hash = hash * 31 + metadata.getKey().hashCode();
            hash = hash * 31 + repoHashCode( localRepository );
            for ( ArtifactRepository remoteRepository : remoteRepositories )
            {
                hash = hash * 31 + repoHashCode( remoteRepository );
            }
            hashCode = hash;
        }
{'fraction_non_alphanumeric': 0.07773989828424524, 'fraction_numerical': 0.0017884088749790421, 'mean_word_length': 1.7937548790007807, 'pattern_counts': {'":': 2, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '540146', 'n_tokens_mistral': 4090, 'n_tokens_neox': 3863, 'n_words': 1023}