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