]> source.dussan.org Git - archiva.git/blob
8ec5c85473bc66952e3051744528888345fb180f
[archiva.git] /
1 package org.apache.maven.archiva.repository.assembly;
2
3 /*
4  * Copyright 2001-2005 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 import org.apache.maven.artifact.Artifact;
20 import org.apache.maven.artifact.factory.ArtifactFactory;
21 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
22 import org.apache.maven.artifact.repository.ArtifactRepository;
23 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
24 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
25 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
26 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
27 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
28 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
29 import org.apache.maven.artifact.resolver.ArtifactResolver;
30 import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
31 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
32 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
33 import org.codehaus.plexus.logging.AbstractLogEnabled;
34 import org.codehaus.plexus.util.FileUtils;
35 import org.apache.commons.io.IOUtils;
36
37 import java.io.File;
38 import java.io.FileWriter;
39 import java.io.IOException;
40 import java.io.Writer;
41 import java.lang.reflect.Field;
42 import java.security.NoSuchAlgorithmException;
43 import java.text.DateFormat;
44 import java.text.SimpleDateFormat;
45 import java.util.ArrayList;
46 import java.util.Date;
47 import java.util.HashMap;
48 import java.util.Iterator;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Set;
52 import java.util.TimeZone;
53
54 /**
55  * @author Jason van Zyl
56  * @plexus.component role="org.apache.maven.archiva.RepositoryAssembler" role-hint="default"
57  */
58
59 // todo will need to pop the processed project cache using reflection
60 public class DefaultRepositoryAssembler
61     extends AbstractLogEnabled
62     implements RepositoryAssembler
63 {
64     protected static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
65
66     protected static final String UTC_TIMESTAMP_PATTERN = "yyyyMMddHHmmss";
67
68     /**
69      * @plexus.requirement
70      */
71     protected ArtifactFactory artifactFactory;
72
73     /**
74      * @plexus.requirement
75      */
76     protected ArtifactResolver artifactResolver;
77
78     /**
79      * @plexus.requirement
80      */
81     protected ArtifactRepositoryLayout repositoryLayout;
82
83     /**
84      * @plexus.requirement
85      */
86     protected ArtifactRepositoryFactory artifactRepositoryFactory;
87
88     /**
89      * @plexus.requirement
90      */
91     protected ArtifactMetadataSource metadataSource;
92
93     public void assemble( Set artifacts,
94                           File localRepository,
95                           Set remoteRepositories,
96                           ArtifactRepositoryLayout layout,
97                           File repositoryDirectory )
98         throws RepositoryAssemblyException
99     {
100
101     }
102
103     public void assemble( Set artifacts,
104                           File localRepository,
105                           Set remoteRepositories,
106                           ArtifactFilter artifactFilter,
107                           ArtifactRepositoryLayout layout,
108                           File repositoryDirectory )
109         throws RepositoryAssemblyException
110     {
111         ArtifactRepository targetRepository = createLocalRepository( repositoryDirectory );
112
113         ArtifactResolutionResult result = null;
114
115         Artifact originatingArtifact = null;
116
117         ArtifactRepository localRepo = createLocalRepository( localRepository );
118         try
119         {
120             // i have to get everything first as a filter or transformation here
121             // doesn't seem to work
122             // to align everything. If I use a filter to change the version on
123             // the fly then I get the
124             // I get JARs but no POMs, and in some directories POMs with no
125             // JARs.
126
127             // FIXME I'm not getting runtime dependencies here
128             result = artifactResolver.resolveTransitively( artifacts, originatingArtifact,
129                                                            new ArrayList( remoteRepositories ),
130                                                            localRepo, metadataSource );
131         }
132         catch ( ArtifactResolutionException e )
133         {
134             throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );
135         }
136         catch ( ArtifactNotFoundException e )
137         {
138             throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );
139         }
140
141         assembleRepositoryArtifacts( result, artifactFilter, localRepo, targetRepository, repositoryDirectory );
142
143         ArtifactRepository centralRepository = findCentralRepository( project );
144
145         assembleRepositoryMetadata( result, artifactFilter, centralRepository, targetRepository );
146     }
147
148     private void assembleRepositoryArtifacts( ArtifactResolutionResult result,
149                                               ArtifactFilter filter,
150                                               List remoteRepositories,
151                                               ArtifactRepository localRepository,
152                                               ArtifactRepository targetRepository,
153                                               File repositoryDirectory )
154         throws RepositoryAssemblyException
155     {
156         try
157         {
158             // Now that we have the graph, let's try to align it to versions
159             // that we want and remove
160             // the assembly we previously populated.
161             FileUtils.deleteDirectory( repositoryDirectory );
162
163             FileUtils.mkdir( repositoryDirectory.getAbsolutePath() );
164
165             for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); )
166             {
167                 Artifact a = (Artifact) i.next();
168
169                 if ( filter.include( a ) )
170                 {
171                     // We need to flip it back to not being resolved so we can
172                     // look for it again!
173                     a.setResolved( false );
174
175                     artifactResolver.resolve( a, remoteRepositories, localRepository );
176
177                     File targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( a ) );
178                     FileUtils.copyFile( a.getFile(), targetFile );
179
180                     writeChecksums( targetFile );
181
182                     if ( !"pom".equals( a.getType() ) )
183                     {
184                         a = artifactFactory.createProjectArtifact( a.getGroupId(), a.getArtifactId(), a.getVersion() );
185
186                         MavenProject p = projectBuilder.buildFromRepository( a, project.getRemoteArtifactRepositories(),
187                                                                              localRepository );
188
189                         do
190                         {
191                             a = artifactFactory.createProjectArtifact( p.getGroupId(), p.getArtifactId(), p
192                                 .getVersion() );
193
194                             setAlignment( a, groupVersionAlignments );
195
196                             File sourceFile = new File( localRepository.getBasedir(), localRepository.pathOf( a ) );
197
198                             if ( !sourceFile.exists() )
199                             {
200                                 break;
201                             }
202
203                             targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( a ) );
204
205                             FileUtils.copyFile( sourceFile, targetFile );
206
207                             writeChecksums( targetFile );
208
209                             p = p.getParent();
210                         }
211                         while ( p != null );
212                     }
213                 }
214             }
215         }
216         catch ( ArtifactResolutionException e )
217         {
218             throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );
219         }
220         catch ( ArtifactNotFoundException e )
221         {
222             throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );
223         }
224         catch ( IOException e )
225         {
226             throw new RepositoryAssemblyException( "Error writing artifact metdata.", e );
227         }
228     }
229
230     private void assembleRepositoryMetadata( ArtifactResolutionResult result,
231                                              ArtifactFilter filter,
232                                              ArtifactRepository centralRepository,
233                                              ArtifactRepository targetRepository )
234         throws RepositoryAssemblyException
235     {
236         for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); )
237         {
238             Artifact a = (Artifact) i.next();
239
240             if ( filter.include( a ) )
241             {
242                 Versioning v = new Versioning();
243
244                 v.setRelease( a.getVersion() );
245
246                 v.setLatest( a.getVersion() );
247
248                 v.addVersion( a.getVersion() );
249
250                 v.setLastUpdated( getUtcDateFormatter().format( new Date() ) );
251
252                 ArtifactRepositoryMetadata metadata = new ArtifactRepositoryMetadata( a, v );
253                 String path = targetRepository.pathOfLocalRepositoryMetadata( metadata, centralRepository );
254                 File metadataFile = new File( targetRepository.getBasedir(), path );
255
256                 MetadataXpp3Writer metadataWriter = new MetadataXpp3Writer();
257
258                 Writer writer = null;
259                 try
260                 {
261                     writer = new FileWriter( metadataFile );
262
263                     metadataWriter.write( writer, metadata.getMetadata() );
264                 }
265                 catch ( IOException e )
266                 {
267                     throw new RepositoryAssemblyException( "Error writing artifact metdata.", e );
268                 }
269                 finally
270                 {
271                     IOUtils.closeQuietly( writer );
272                 }
273
274                 try
275                 {
276                     writeChecksums( metadataFile );
277
278                     File metadataFileRemote = new File( targetRepository.getBasedir(), targetRepository
279                         .pathOfRemoteRepositoryMetadata( metadata ) );
280
281                     FileUtils.copyFile( metadataFile, metadataFileRemote );
282
283                     FileUtils.copyFile( new File( metadataFile.getParentFile(), metadataFile.getName() + ".sha1" ),
284                                         new File( metadataFileRemote.getParentFile(),
285                                                   metadataFileRemote.getName() + ".sha1" ) );
286
287                     FileUtils.copyFile( new File( metadataFile.getParentFile(), metadataFile.getName() + ".md5" ),
288                                         new File( metadataFileRemote.getParentFile(),
289                                                   metadataFileRemote.getName() + ".md5" ) );
290                 }
291                 catch ( IOException e )
292                 {
293                     throw new RepositoryAssemblyException( "Error writing artifact metdata.", e );
294                 }
295             }
296         }
297     }
298
299     private void writeChecksums( File file )
300         throws IOException, RepositoryAssemblyException
301     {
302         try
303         {
304             String md5 = DigestUtils.createChecksum( file, "MD5" );
305             String sha1 = DigestUtils.createChecksum( file, "SHA-1" );
306
307             FileUtils.fileWrite( new File( file.getParentFile(), file.getName() + ".md5" ).getAbsolutePath(), md5
308                 .toLowerCase() );
309             FileUtils.fileWrite( new File( file.getParentFile(), file.getName() + ".sha1" ).getAbsolutePath(), sha1
310                 .toLowerCase() );
311         }
312         catch ( NoSuchAlgorithmException e )
313         {
314             throw new RepositoryAssemblyException( "Unable to get write checksums: " + e.getMessage(), e );
315         }
316     }
317
318     protected static DateFormat getUtcDateFormatter()
319     {
320         DateFormat utcDateFormatter = new SimpleDateFormat( UTC_TIMESTAMP_PATTERN );
321         utcDateFormatter.setTimeZone( UTC_TIME_ZONE );
322         return utcDateFormatter;
323     }
324
325     protected ArtifactRepository createLocalRepository( File directory )
326     {
327         String localRepositoryUrl = directory.getAbsolutePath();
328
329         if ( !localRepositoryUrl.startsWith( "file:" ) )
330         {
331             localRepositoryUrl = "file://" + localRepositoryUrl;
332         }
333
334         return createRepository( "local", localRepositoryUrl, false, true,
335                                  ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
336     }
337
338     public ArtifactRepository createRepository( String repositoryId,
339                                                 String repositoryUrl,
340                                                 boolean offline,
341                                                 boolean updateSnapshots,
342                                                 String globalChecksumPolicy )
343     {
344         ArtifactRepository localRepository =
345             new DefaultArtifactRepository( repositoryId, repositoryUrl, repositoryLayout );
346
347         boolean snapshotPolicySet = false;
348
349         if ( offline )
350         {
351             snapshotPolicySet = true;
352         }
353
354         if ( !snapshotPolicySet && updateSnapshots )
355         {
356             artifactRepositoryFactory.setGlobalUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS );
357         }
358
359         artifactRepositoryFactory.setGlobalChecksumPolicy( globalChecksumPolicy );
360
361         return localRepository;
362     }
363 }