001    package org.apache.archiva.rest.services;
002    /*
003     * Licensed to the Apache Software Foundation (ASF) under one
004     * or more contributor license agreements.  See the NOTICE file
005     * distributed with this work for additional information
006     * regarding copyright ownership.  The ASF licenses this file
007     * to you under the Apache License, Version 2.0 (the
008     * "License"); you may not use this file except in compliance
009     * with the License.  You may obtain a copy of the License at
010     *
011     *   http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing,
014     * software distributed under the License is distributed on an
015     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016     * KIND, either express or implied.  See the License for the
017     * specific language governing permissions and limitations
018     * under the License.
019     */
020    
021    import org.apache.archiva.admin.model.RepositoryAdminException;
022    import org.apache.archiva.admin.model.beans.ManagedRepository;
023    import org.apache.archiva.audit.AuditEvent;
024    import org.apache.archiva.common.utils.VersionUtil;
025    import org.apache.archiva.maven2.model.Artifact;
026    import org.apache.archiva.metadata.model.ArtifactMetadata;
027    import org.apache.archiva.metadata.repository.MetadataRepository;
028    import org.apache.archiva.metadata.repository.MetadataRepositoryException;
029    import org.apache.archiva.metadata.repository.RepositorySession;
030    import org.apache.archiva.metadata.repository.filter.Filter;
031    import org.apache.archiva.metadata.repository.filter.IncludesFilter;
032    import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
033    import org.apache.archiva.rest.api.services.MergeRepositoriesService;
034    import org.apache.archiva.stagerepository.merge.Maven2RepositoryMerger;
035    import org.apache.archiva.stagerepository.merge.RepositoryMergerException;
036    import org.springframework.stereotype.Service;
037    
038    import javax.inject.Inject;
039    import javax.inject.Named;
040    import java.util.ArrayList;
041    import java.util.List;
042    
043    /**
044     * @author Olivier Lamy
045     * @since 1.4-M3
046     */
047    @Service ( "mergeRepositoriesService#rest" )
048    public class DefaultMergeRepositoriesService
049        extends AbstractRestService
050        implements MergeRepositoriesService
051    {
052    
053        // FIXME check archiva-merge-repository to sourceRepoId
054    
055        @Inject
056        @Named ( value = "repositoryMerger#maven2" )
057        private Maven2RepositoryMerger repositoryMerger;
058    
059    
060        public List<Artifact> getMergeConflictedArtifacts( String sourceRepositoryId, String targetRepositoryId )
061            throws ArchivaRestServiceException
062        {
063            RepositorySession repositorySession = repositorySessionFactory.createSession();
064            try
065            {
066                List<ArtifactMetadata> artifactMetadatas =
067                    repositoryMerger.getConflictingArtifacts( repositorySession.getRepository(), sourceRepositoryId,
068                                                              targetRepositoryId );
069    
070                return buildArtifacts( artifactMetadatas, sourceRepositoryId );
071            }
072            catch ( RepositoryMergerException e )
073            {
074                throw new ArchivaRestServiceException( e.getMessage(), e );
075            }
076            finally
077            {
078                repositorySession.close();
079            }
080        }
081    
082        public void mergeRepositories( String sourceRepositoryId, String targetRepositoryId, boolean skipConflicts )
083            throws ArchivaRestServiceException
084        {
085            try
086            {
087                if ( skipConflicts )
088                {
089                    mergeBySkippingConflicts( sourceRepositoryId, targetRepositoryId );
090                }
091                else
092                {
093                    doMerge( sourceRepositoryId, targetRepositoryId );
094                }
095    
096            }
097            catch ( RepositoryMergerException e )
098            {
099                throw new ArchivaRestServiceException( e.getMessage(), e );
100            }
101    
102        }
103    
104    
105        protected void doMerge( String sourceRepositoryId, String targetRepositoryId )
106            throws RepositoryMergerException, ArchivaRestServiceException
107        {
108            RepositorySession repositorySession = repositorySessionFactory.createSession();
109    
110            try
111            {
112                ManagedRepository repository = managedRepositoryAdmin.getManagedRepository( targetRepositoryId );
113                MetadataRepository metadataRepository = repositorySession.getRepository();
114                List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( sourceRepositoryId );
115    
116                if ( repository.isReleases() && !repository.isSnapshots() )
117                {
118                    mergeWithOutSnapshots( metadataRepository, sourceArtifacts, sourceRepositoryId, targetRepositoryId );
119                }
120                else
121                {
122                    repositoryMerger.merge( metadataRepository, sourceRepositoryId, targetRepositoryId );
123    
124                    for ( ArtifactMetadata metadata : sourceArtifacts )
125                    {
126                        triggerAuditEvent( targetRepositoryId, metadata.getId(), AuditEvent.MERGING_REPOSITORIES );
127                    }
128                }
129    
130                doScanRepository( targetRepositoryId, false );
131            }
132            catch ( MetadataRepositoryException e )
133            {
134                throw new ArchivaRestServiceException( e.getMessage(), e );
135            }
136            catch ( RepositoryAdminException e )
137            {
138                throw new ArchivaRestServiceException( e.getMessage(), e );
139            }
140            finally
141            {
142                repositorySession.close();
143            }
144        }
145    
146        public void mergeBySkippingConflicts( String sourceRepositoryId, String targetRepositoryId )
147            throws RepositoryMergerException, ArchivaRestServiceException
148        {
149    
150            RepositorySession repositorySession = repositorySessionFactory.createSession();
151            try
152            {
153                List<ArtifactMetadata> conflictSourceArtifacts =
154                    repositoryMerger.getConflictingArtifacts( repositorySession.getRepository(), sourceRepositoryId,
155                                                              targetRepositoryId );
156                MetadataRepository metadataRepository = repositorySession.getRepository();
157                List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( sourceRepositoryId );
158                sourceArtifacts.removeAll( conflictSourceArtifacts );
159    
160                ManagedRepository repository = managedRepositoryAdmin.getManagedRepository( targetRepositoryId );
161    
162                if ( repository.isReleases() && !repository.isSnapshots() )
163                {
164                    mergeWithOutSnapshots( metadataRepository, sourceArtifacts, sourceRepositoryId, targetRepositoryId );
165                }
166                else
167                {
168    
169                    Filter<ArtifactMetadata> artifactsWithOutConflicts =
170                        new IncludesFilter<ArtifactMetadata>( sourceArtifacts );
171                    repositoryMerger.merge( metadataRepository, sourceRepositoryId, targetRepositoryId,
172                                            artifactsWithOutConflicts );
173                    for ( ArtifactMetadata metadata : sourceArtifacts )
174                    {
175                        triggerAuditEvent( targetRepositoryId, metadata.getId(), AuditEvent.MERGING_REPOSITORIES );
176                    }
177                }
178    
179                doScanRepository( targetRepositoryId, false );
180            }
181            catch ( MetadataRepositoryException e )
182            {
183                throw new ArchivaRestServiceException( e.getMessage(), e );
184            }
185            catch ( RepositoryAdminException e )
186            {
187                throw new ArchivaRestServiceException( e.getMessage(), e );
188    
189            }
190            finally
191            {
192                repositorySession.close();
193            }
194        }
195    
196        private void mergeWithOutSnapshots( MetadataRepository metadataRepository, List<ArtifactMetadata> sourceArtifacts,
197                                            String sourceRepoId, String repoid )
198            throws RepositoryMergerException
199        {
200            List<ArtifactMetadata> artifactsWithOutSnapshots = new ArrayList<ArtifactMetadata>();
201            for ( ArtifactMetadata metadata : sourceArtifacts )
202            {
203                if ( VersionUtil.isSnapshot( metadata.getProjectVersion() ) )
204                //if ( metadata.getProjectVersion().contains( VersionUtil.SNAPSHOT ) )
205                {
206                    artifactsWithOutSnapshots.add( metadata );
207                }
208                else
209                {
210                    triggerAuditEvent( repoid, metadata.getId(), AuditEvent.MERGING_REPOSITORIES );
211                }
212    
213            }
214            sourceArtifacts.removeAll( artifactsWithOutSnapshots );
215    
216            Filter<ArtifactMetadata> artifactListWithOutSnapShots = new IncludesFilter<ArtifactMetadata>( sourceArtifacts );
217            repositoryMerger.merge( metadataRepository, sourceRepoId, repoid, artifactListWithOutSnapShots );
218        }
219    }