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