]> source.dussan.org Git - archiva.git/blob
8df8f8e2ee92ba9d23b4411041fad9ff58abd0c6
[archiva.git] /
1 package org.apache.maven.archiva.web.action;
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.codehaus.plexus.xwork.action.PlexusActionSupport;
23 import org.apache.maven.archiva.common.utils.Checksums;
24 import org.apache.maven.archiva.common.utils.VersionComparator;
25 import org.apache.maven.archiva.common.utils.VersionUtil;
26 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
27 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
28 import org.apache.maven.archiva.model.ArchivaProjectModel;
29 import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
30 import org.apache.maven.archiva.model.ArtifactReference;
31 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
32 import org.apache.maven.archiva.repository.RepositoryContentFactory;
33 import org.apache.maven.archiva.repository.RepositoryException;
34 import org.apache.maven.archiva.repository.RepositoryNotFoundException;
35 import org.apache.maven.archiva.repository.metadata.MetadataTools;
36 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
37 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataReader;
38 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataWriter;
39 import org.apache.maven.archiva.repository.project.ProjectModelException;
40 import org.apache.maven.archiva.repository.project.ProjectModelWriter;
41 import org.apache.maven.archiva.security.ArchivaSecurityException;
42 import org.apache.maven.archiva.security.ArchivaUser;
43 import org.apache.maven.archiva.security.PrincipalNotFoundException;
44 import org.apache.maven.archiva.security.UserRepositories;
45
46 import com.opensymphony.xwork.Preparable;
47 import com.opensymphony.xwork.Validateable;
48
49 import java.io.File;
50 import java.io.FileInputStream;
51 import java.io.FileOutputStream;
52 import java.io.IOException;
53 import java.util.ArrayList;
54 import java.util.Calendar;
55 import java.util.Collections;
56 import java.util.List;
57
58 /**
59  * Upload an artifact using Jakarta file upload in webwork. If set by the user a pom will also be generated. Metadata
60  * will also be updated if one exists, otherwise it would be created.
61  * 
62  * @author <a href="mailto:wsmoak@apache.org">Wendy Smoak</a>
63  * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
64  * @plexus.component role="com.opensymphony.xwork.Action" role-hint="uploadAction"
65  */
66 public class UploadAction
67     extends PlexusActionSupport
68     implements Validateable, Preparable
69 {
70     /**
71      * The groupId of the artifact to be deployed.
72      */
73     private String groupId;
74
75     /**
76      * The artifactId of the artifact to be deployed.
77      */
78     private String artifactId;
79
80     /**
81      * The version of the artifact to be deployed.
82      */
83     private String version;
84
85     /**
86      * The packaging of the artifact to be deployed.
87      */
88     private String packaging;
89
90     /**
91      * The classifier of the artifact to be deployed.
92      */
93     private String classifier;
94
95     /**
96      * The artifact to be deployed.
97      */
98     private File file;
99
100     /**
101      * The content type of the artifact to be deployed.
102      */
103     private String contentType;
104
105     /**
106      * The temporary filename of the artifact to be deployed.
107      */
108     private String filename;
109
110     /**
111      * The repository where the artifact is to be deployed.
112      */
113     private String repositoryId;
114
115     /**
116      * Flag whether to generate a pom for the artifact or not.
117      */
118     private boolean generatePom;
119
120     /**
121      * List of managed repositories to deploy to.
122      */
123     private List<String> managedRepoIdList;
124
125     /**
126      * @plexus.requirement role-hint="xwork"
127      */
128     private ArchivaUser archivaUser;
129
130     /**
131      * @plexus.requirement
132      */
133     private UserRepositories userRepositories;
134
135     /**
136      * @plexus.requirement role-hint="default"
137      */
138     private ArchivaConfiguration configuration;
139
140     /**
141      * @plexus.requirement
142      */
143     private RepositoryContentFactory repositoryFactory;
144
145     /**
146      * @plexus.requirement role-hint="model400"
147      */
148     private ProjectModelWriter pomWriter;
149     
150     /**
151      * @plexus.requirement
152      */
153     private Checksums checksums;
154
155     public void setUpload( File file )
156     {
157         this.file = file;
158     }
159
160     public void setUploadContentType( String contentType )
161     {
162         this.contentType = contentType;
163     }
164
165     public void setUploadFileName( String filename )
166     {
167         this.filename = filename;
168     }
169
170     public String getGroupId()
171     {
172         return groupId;
173     }
174
175     public void setGroupId( String groupId )
176     {
177         this.groupId = groupId;
178     }
179
180     public String getArtifactId()
181     {
182         return artifactId;
183     }
184
185     public void setArtifactId( String artifactId )
186     {
187         this.artifactId = artifactId;
188     }
189
190     public String getVersion()
191     {
192         return version;
193     }
194
195     public void setVersion( String version )
196     {
197         this.version = version;
198     }
199
200     public String getPackaging()
201     {
202         return packaging;
203     }
204
205     public void setPackaging( String packaging )
206     {
207         this.packaging = packaging;
208     }
209
210     public String getClassifier()
211     {
212         return classifier;
213     }
214
215     public void setClassifier( String classifier )
216     {
217         this.classifier = classifier;
218     }
219
220     public String getRepositoryId()
221     {
222         return repositoryId;
223     }
224
225     public void setRepositoryId( String repositoryId )
226     {
227         this.repositoryId = repositoryId;
228     }
229
230     public boolean isGeneratePom()
231     {
232         return generatePom;
233     }
234
235     public void setGeneratePom( boolean generatePom )
236     {
237         this.generatePom = generatePom;
238     }
239
240     public List<String> getManagedRepoIdList()
241     {
242         return managedRepoIdList;
243     }
244
245     public void setManagedRepoIdList( List<String> managedRepoIdList )
246     {
247         this.managedRepoIdList = managedRepoIdList;
248     }
249
250     public void prepare()
251     {
252         managedRepoIdList =
253             new ArrayList<String>( configuration.getConfiguration().getManagedRepositoriesAsMap().keySet() );
254     }
255
256     public String input()
257     {
258         return INPUT;
259     }
260
261     public String doUpload()
262     {
263         try
264         {
265             ManagedRepositoryConfiguration repoConfig =
266                 configuration.getConfiguration().findManagedRepositoryById( repositoryId );
267
268             ArtifactReference artifactReference = new ArtifactReference();
269             artifactReference.setArtifactId( artifactId );
270             artifactReference.setGroupId( groupId );
271             artifactReference.setVersion( version );
272             artifactReference.setClassifier( classifier );
273             artifactReference.setType( packaging );
274
275             ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
276
277             String artifactPath = repository.toPath( artifactReference );
278
279             int lastIndex = artifactPath.lastIndexOf( '/' );
280
281             File targetPath = new File( repoConfig.getLocation(), artifactPath.substring( 0, lastIndex ) );
282
283             if ( !targetPath.exists() )
284             {
285                 targetPath.mkdirs();
286             }
287
288             try
289             {
290                 copyFile( targetPath, artifactPath.substring( lastIndex + 1 ) );
291             }
292             catch ( IOException ie )
293             {
294                 addActionError( "Error encountered while uploading file: " + ie.getMessage() );
295                 return ERROR;
296             }
297
298             if ( generatePom )
299             {
300                 try
301                 {
302                     createPom( targetPath, artifactPath.substring( lastIndex + 1 ) );
303                 }
304                 catch ( IOException ie )
305                 {
306                     addActionError( "Error encountered while writing pom file: " + ie.getMessage() );
307                     return ERROR;
308                 }
309                 catch ( ProjectModelException pe )
310                 {
311                     addActionError( "Error encountered while generating pom file: " + pe.getMessage() );
312                     return ERROR;
313                 }
314             }
315
316             updateMetadata( getMetadata( targetPath.getAbsolutePath() ) );
317
318             addActionMessage( "Artifact \'" + groupId + ":" + artifactId + ":" + version +
319                 "\' was successfully deployed to repository \'" + repositoryId + "\'!" );
320
321             return SUCCESS;
322         }
323         catch ( RepositoryNotFoundException re )
324         {
325             addActionError( "Target repository cannot be found: " + re.getMessage() );
326             return ERROR;
327         }
328         catch ( RepositoryException rep )
329         {
330             addActionError( "Repository exception: " + rep.getMessage() );
331             return ERROR;
332         }
333     }
334
335     private String getPrincipal()
336     {
337         return archivaUser.getActivePrincipal();
338     }
339
340     private void copyFile( File targetPath, String artifactFilename )
341         throws IOException
342     {
343         FileOutputStream out = new FileOutputStream( new File( targetPath, artifactFilename ) );
344
345         try
346         {
347             FileInputStream input = new FileInputStream( file );
348             int i = 0;
349             while ( ( i = input.read() ) != -1 )
350             {
351                 out.write( i );
352             }
353             out.flush();
354         }
355         finally
356         {
357             out.close();
358         }
359     }
360
361     private void createPom( File targetPath, String filename )
362         throws IOException, ProjectModelException
363     {
364         ArchivaProjectModel projectModel = new ArchivaProjectModel();
365         projectModel.setGroupId( groupId );
366         projectModel.setArtifactId( artifactId );
367         projectModel.setVersion( version );
368         projectModel.setPackaging( packaging );
369
370         File pomFile = new File( targetPath, filename.replaceAll( packaging, "pom" ) );
371
372         pomWriter.write( projectModel, pomFile );
373     }
374
375     private File getMetadata( String targetPath )
376     {
377         String artifactPath = targetPath.substring( 0, targetPath.lastIndexOf( '/' ) );
378
379         return new File( artifactPath, MetadataTools.MAVEN_METADATA );
380     }
381
382     /**
383      * Update artifact level metadata. If it does not exist, create the metadata.
384      * 
385      * @param targetPath
386      */
387     private void updateMetadata( File metadataFile )
388         throws RepositoryMetadataException
389     {
390         List<String> availableVersions = new ArrayList<String>();
391         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
392
393         if ( metadataFile.exists() )
394         {
395             metadata = RepositoryMetadataReader.read( metadataFile );
396             availableVersions = metadata.getAvailableVersions();
397
398             Collections.sort( availableVersions, VersionComparator.getInstance() );
399
400             if ( !availableVersions.contains( version ) )
401             {
402                 availableVersions.add( version );
403             }
404
405             String latestVersion = availableVersions.get( availableVersions.size() - 1 );
406             metadata.setLatestVersion( latestVersion );
407             metadata.setAvailableVersions( availableVersions );
408             metadata.setLastUpdatedTimestamp( Calendar.getInstance().getTime() );
409
410             if ( !VersionUtil.isSnapshot( version ) )
411             {
412                 metadata.setReleasedVersion( latestVersion );
413             }
414         }
415         else
416         {
417             availableVersions.add( version );
418
419             metadata.setGroupId( groupId );
420             metadata.setArtifactId( artifactId );
421             metadata.setLatestVersion( version );
422             metadata.setLastUpdatedTimestamp( Calendar.getInstance().getTime() );
423             metadata.setAvailableVersions( availableVersions );
424
425             if ( !VersionUtil.isSnapshot( version ) )
426             {
427                 metadata.setReleasedVersion( version );
428             }
429         }
430
431         RepositoryMetadataWriter.write( metadata, metadataFile );
432         
433         checksums.update( metadataFile );
434     }
435     
436     public void validate()
437     {
438         try
439         {
440             // is this enough check for the repository permission?
441             if ( !userRepositories.isAuthorizedToUploadArtifacts( getPrincipal(), repositoryId ) )
442             {
443                 addActionError( "User is not authorized to upload in repository " + repositoryId );
444             }
445
446             if ( file == null || file.length() == 0 )
447             {
448                 addActionError( "Please add a file to upload." );
449             }
450             
451             if ( !VersionUtil.isVersion( version ) )
452             {
453                 addActionError( "Invalid version." );
454             }            
455         }
456         catch ( PrincipalNotFoundException pe )
457         {
458             addActionError( pe.getMessage() );
459         }
460         catch ( ArchivaSecurityException ae )
461         {
462             addActionError( ae.getMessage() );
463         }
464     }
465 }