]> source.dussan.org Git - archiva.git/blob
7d3a6ff9b7fd43a339d8f6947813fe9d591f1648
[archiva.git] /
1 package org.apache.archiva.stagerepository.merge;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import org.apache.archiva.metadata.model.ArtifactMetadata;
23 import org.apache.archiva.metadata.repository.MetadataRepository;
24 import org.apache.archiva.metadata.repository.filter.Filter;
25 import org.apache.archiva.metadata.repository.filter.IncludesFilter;
26 import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
27 import org.apache.commons.io.IOUtils;
28 import org.apache.maven.archiva.common.utils.VersionComparator;
29 import org.apache.maven.archiva.common.utils.VersionUtil;
30 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
31 import org.apache.maven.archiva.configuration.Configuration;
32 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
33 import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
34 import org.apache.maven.archiva.repository.RepositoryException;
35 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
36 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataReader;
37 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataWriter;
38
39 import java.io.File;
40 import java.io.FileInputStream;
41 import java.io.FileOutputStream;
42 import java.io.IOException;
43 import java.text.DateFormat;
44 import java.text.SimpleDateFormat;
45 import java.util.ArrayList;
46 import java.util.Calendar;
47 import java.util.Collections;
48 import java.util.Date;
49 import java.util.List;
50 import java.util.TimeZone;
51
52 /**
53  * @plexus.component role="org.apache.archiva.stagerepository.merge.RepositoryMerger" role-hint="maven2"
54  */
55 public class Maven2RepositoryMerger
56     implements RepositoryMerger
57 {
58     /**
59      * @plexus.requirement role-hint="default"
60      */
61     private ArchivaConfiguration configuration;
62
63     /**
64      * @plexus.requirement role-hint="maven2"
65      */
66     private RepositoryPathTranslator pathTranslator;
67
68     private static final String METADATA_FILENAME = "maven-metadata.xml";
69
70     public void setConfiguration( ArchivaConfiguration configuration )
71     {
72         this.configuration = configuration;
73     }
74
75     public void merge( MetadataRepository metadataRepository, String sourceRepoId, String targetRepoId )
76         throws Exception
77     {
78
79         List<ArtifactMetadata> artifactsInSourceRepo = metadataRepository.getArtifacts( sourceRepoId );
80         for ( ArtifactMetadata artifactMetadata : artifactsInSourceRepo )
81         {
82             artifactMetadata.setRepositoryId( targetRepoId );
83             createFolderStructure( sourceRepoId, targetRepoId, artifactMetadata );
84         }
85     }
86
87     // TODO when UI needs a subset to merge
88     public void merge( MetadataRepository metadataRepository, String sourceRepoId, String targetRepoId,
89                        Filter<ArtifactMetadata> filter )
90         throws Exception
91     {
92         List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( sourceRepoId );
93         for ( ArtifactMetadata metadata : sourceArtifacts )
94         {
95             if ( filter.accept( metadata ) )
96             {
97                 createFolderStructure( sourceRepoId, targetRepoId, metadata );
98             }
99         }
100     }
101
102     private void createFolderStructure( String sourceRepoId, String targetRepoId, ArtifactMetadata artifactMetadata )
103         throws IOException, RepositoryException
104     {
105         Configuration config = configuration.getConfiguration();
106
107         ManagedRepositoryConfiguration targetRepoConfig = config.findManagedRepositoryById( targetRepoId );
108
109         ManagedRepositoryConfiguration sourceRepoConfig = config.findManagedRepositoryById( sourceRepoId );
110
111         Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
112
113         TimeZone timezone = TimeZone.getTimeZone( "UTC" );
114
115         DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
116
117         fmt.setTimeZone( timezone );
118
119         String timestamp = fmt.format( lastUpdatedTimestamp );
120
121         String targetRepoPath = targetRepoConfig.getLocation();
122
123         String sourceRepoPath = sourceRepoConfig.getLocation();
124
125         String artifactPath = pathTranslator.toPath( artifactMetadata.getNamespace(), artifactMetadata.getProject(),
126                                                      artifactMetadata.getProjectVersion(), artifactMetadata.getId() );
127
128         File sourceArtifactFile = new File( sourceRepoPath, artifactPath );
129
130         File targetArtifactFile = new File( targetRepoPath, artifactPath );
131
132         int lastIndex = artifactPath.lastIndexOf( '/' );
133
134         File targetFile = new File( targetRepoPath, artifactPath.substring( 0, lastIndex ) );
135
136         if ( !targetFile.exists() )
137         {
138             // create the folder structure when it does not exist
139             targetFile.mkdirs();
140         }
141         // artifact copying
142         copyFile( sourceArtifactFile, targetArtifactFile );
143
144         // pom file copying
145         String fileName = artifactMetadata.getProject() + "-" + artifactMetadata.getVersion() + ".pom";
146
147         // pom file copying
148         // TODO need to use path translator to get the pom file path
149 //        String fileName = artifactMetadata.getProject() + "-" + artifactMetadata.getVersion() + ".pom";
150 //
151 //        File sourcePomFile =
152 //            pathTranslator.toFile( new File( sourceRepoPath ), artifactMetadata.getId(), artifactMetadata.getProject(),
153 //                                   artifactMetadata.getVersion(), fileName );
154 //
155 //        String relativePathToPomFile = sourcePomFile.getAbsolutePath().split( sourceRepoPath )[1];
156 //        File targetPomFile = new File( targetRepoPath, relativePathToPomFile );
157
158         //pom file copying  (file path is taken with out using path translator)
159
160         String index = artifactPath.substring( lastIndex + 1 );
161         int last = index.lastIndexOf( '.' );
162         File sourcePomFile = new File( sourceRepoPath, artifactPath.substring( 0, lastIndex ) + "/" +
163             artifactPath.substring( lastIndex + 1 ).substring( 0, last ) + ".pom" );
164         File targetPomFile = new File( targetRepoPath, artifactPath.substring( 0, lastIndex ) + "/" +
165             artifactPath.substring( lastIndex + 1 ).substring( 0, last ) + ".pom" );
166
167         if ( !targetPomFile.exists() && sourcePomFile.exists() )
168         {
169             copyFile( sourcePomFile, targetPomFile );
170         }
171
172         // explicitly update only if metadata-updater consumer is not enabled!
173         if ( !config.getRepositoryScanning().getKnownContentConsumers().contains( "metadata-updater" ) )
174         {
175
176             // updating version metadata files
177             File versionMetaDataFileInSourceRepo = pathTranslator.toFile( new File( sourceRepoPath ),
178                                                                           artifactMetadata.getNamespace(),
179                                                                           artifactMetadata.getProject(),
180                                                                           artifactMetadata.getVersion(),
181                                                                           METADATA_FILENAME );
182
183             if ( versionMetaDataFileInSourceRepo.exists() )
184             {
185                 String relativePathToVersionMetadataFile = versionMetaDataFileInSourceRepo.getAbsolutePath().split(
186                     sourceRepoPath )[1];
187                 File versionMetaDataFileInTargetRepo = new File( targetRepoPath, relativePathToVersionMetadataFile );
188
189                 if ( !versionMetaDataFileInTargetRepo.exists() )
190                 {
191                     copyFile( versionMetaDataFileInSourceRepo, versionMetaDataFileInTargetRepo );
192                 }
193                 else
194                 {
195                     updateVersionMetadata( versionMetaDataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp );
196
197                 }
198             }
199
200             // updating project meta data file
201             String projectDirectoryInSourceRepo = new File( versionMetaDataFileInSourceRepo.getParent() ).getParent();
202             File projectMetadataFileInSourceRepo = new File( projectDirectoryInSourceRepo, METADATA_FILENAME );
203
204             if ( projectMetadataFileInSourceRepo.exists() )
205             {
206                 String relativePathToProjectMetadataFile = projectMetadataFileInSourceRepo.getAbsolutePath().split(
207                     sourceRepoPath )[1];
208                 File projectMetadataFileInTargetRepo = new File( targetRepoPath, relativePathToProjectMetadataFile );
209
210                 if ( !projectMetadataFileInTargetRepo.exists() )
211                 {
212
213                     copyFile( projectMetadataFileInSourceRepo, projectMetadataFileInSourceRepo );
214                 }
215                 else
216                 {
217                     updateProjectMetadata( projectMetadataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp,
218                                            timestamp );
219                 }
220             }
221         }
222
223     }
224
225     private void copyFile( File sourceFile, File targetFile )
226         throws IOException
227     {
228         FileOutputStream out = new FileOutputStream( targetFile );
229         FileInputStream input = new FileInputStream( sourceFile );
230
231         // IOUtils internally buffers the streams
232         try
233         {
234             IOUtils.copy( input, out );
235         }
236         finally
237         {
238             out.close();
239             input.close();
240         }
241     }
242
243     private void updateProjectMetadata( File projectMetaDataFileIntargetRepo, ArtifactMetadata artifactMetadata,
244                                         Date lastUpdatedTimestamp, String timestamp )
245         throws RepositoryMetadataException
246     {
247         ArrayList<String> availableVersions = new ArrayList<String>();
248         String latestVersion = artifactMetadata.getProjectVersion();
249
250         ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetaDataFileIntargetRepo );
251
252         if ( projectMetaDataFileIntargetRepo.exists() )
253         {
254             availableVersions = (ArrayList<String>) projectMetadata.getAvailableVersions();
255
256             Collections.sort( availableVersions, VersionComparator.getInstance() );
257
258             if ( !availableVersions.contains( artifactMetadata.getVersion() ) )
259             {
260                 availableVersions.add( artifactMetadata.getVersion() );
261             }
262
263             latestVersion = availableVersions.get( availableVersions.size() - 1 );
264         }
265         else
266         {
267             availableVersions.add( artifactMetadata.getProjectVersion() );
268             projectMetadata.setGroupId( artifactMetadata.getNamespace() );
269             projectMetadata.setArtifactId( artifactMetadata.getProject() );
270         }
271
272         if ( projectMetadata.getGroupId() == null )
273         {
274             projectMetadata.setGroupId( artifactMetadata.getNamespace() );
275         }
276
277         if ( projectMetadata.getArtifactId() == null )
278         {
279             projectMetadata.setArtifactId( artifactMetadata.getProject() );
280         }
281
282         projectMetadata.setLatestVersion( latestVersion );
283         projectMetadata.setAvailableVersions( availableVersions );
284         projectMetadata.setLastUpdated( timestamp );
285         projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
286
287         if ( !VersionUtil.isSnapshot( artifactMetadata.getVersion() ) )
288         {
289             projectMetadata.setReleasedVersion( latestVersion );
290         }
291
292         RepositoryMetadataWriter.write( projectMetadata, projectMetaDataFileIntargetRepo );
293
294     }
295
296     private void updateVersionMetadata( File versionMetaDataFileInTargetRepo, ArtifactMetadata artifactMetadata,
297                                         Date lastUpdatedTimestamp )
298         throws RepositoryMetadataException
299     {
300         ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetaDataFileInTargetRepo );
301         if ( !versionMetaDataFileInTargetRepo.exists() )
302         {
303             versionMetadata.setGroupId( artifactMetadata.getNamespace() );
304             versionMetadata.setArtifactId( artifactMetadata.getProject() );
305             versionMetadata.setVersion( artifactMetadata.getProjectVersion() );
306         }
307
308         versionMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
309         RepositoryMetadataWriter.write( versionMetadata, versionMetaDataFileInTargetRepo );
310     }
311
312     private ArchivaRepositoryMetadata getMetadata( File metadataFile )
313         throws RepositoryMetadataException
314     {
315         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
316         if ( metadataFile.exists() )
317         {
318             metadata = RepositoryMetadataReader.read( metadataFile );
319         }
320         return metadata;
321     }
322
323     public List<ArtifactMetadata> getConflictingArtifacts( MetadataRepository metadataRepository, String sourceRepo,
324                                                            String targetRepo )
325         throws Exception
326     {
327         List<ArtifactMetadata> targetArtifacts = metadataRepository.getArtifacts( targetRepo );
328         List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( sourceRepo );
329         List<ArtifactMetadata> conflictsArtifacts = new ArrayList<ArtifactMetadata>();
330
331         for ( ArtifactMetadata targetArtifact : targetArtifacts )
332         {
333             for ( ArtifactMetadata sourceArtifact : sourceArtifacts )
334             {
335                 if ( isEquals( targetArtifact, sourceArtifact ) )
336                 {
337                     if ( !conflictsArtifacts.contains( sourceArtifact ) )
338                     {
339                         conflictsArtifacts.add( sourceArtifact );
340                     }
341                 }
342             }
343         }
344
345         sourceArtifacts.removeAll( conflictsArtifacts );
346         Filter<ArtifactMetadata> artifactsWithOutConflicts = new IncludesFilter<ArtifactMetadata>( sourceArtifacts );
347 //        merge( sourceRepo, targetRepo, artifactsWithOutConflicts );
348         return conflictsArtifacts;
349     }
350
351     private boolean isEquals( ArtifactMetadata sourceArtifact, ArtifactMetadata targetArtifact )
352     {
353         boolean isSame = false;
354
355         if ( ( sourceArtifact.getNamespace().equals( targetArtifact.getNamespace() ) ) &&
356             ( sourceArtifact.getProject().equals( targetArtifact.getProject() ) ) && ( sourceArtifact.getId().equals(
357             targetArtifact.getId() ) ) && ( sourceArtifact.getProjectVersion().equals(
358             targetArtifact.getProjectVersion() ) ) )
359
360         {
361             isSame = true;
362
363         }
364
365         return isSame;
366     }
367 }