001    package org.apache.archiva.converter.artifact;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *  http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.archiva.common.plexusbridge.DigesterUtils;
023    import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
024    import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
025    import org.apache.archiva.transaction.FileTransaction;
026    import org.apache.archiva.transaction.TransactionException;
027    import org.apache.commons.io.FileUtils;
028    import org.apache.commons.io.IOUtils;
029    import org.apache.maven.artifact.Artifact;
030    import org.apache.maven.artifact.factory.ArtifactFactory;
031    import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
032    import org.apache.maven.artifact.repository.ArtifactRepository;
033    import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
034    import org.apache.maven.artifact.repository.metadata.Metadata;
035    import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
036    import org.apache.maven.artifact.repository.metadata.Snapshot;
037    import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
038    import org.apache.maven.artifact.repository.metadata.Versioning;
039    import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
040    import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
041    import org.apache.maven.model.DistributionManagement;
042    import org.apache.maven.model.Model;
043    import org.apache.maven.model.Relocation;
044    import org.apache.maven.model.converter.ModelConverter;
045    import org.apache.maven.model.converter.PomTranslationException;
046    import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
047    import org.codehaus.plexus.digest.Digester;
048    import org.codehaus.plexus.digest.DigesterException;
049    import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
050    import org.springframework.stereotype.Service;
051    
052    import javax.annotation.PostConstruct;
053    import javax.inject.Inject;
054    import java.io.File;
055    import java.io.FileNotFoundException;
056    import java.io.FileReader;
057    import java.io.IOException;
058    import java.io.StringReader;
059    import java.io.StringWriter;
060    import java.nio.charset.Charset;
061    import java.util.ArrayList;
062    import java.util.HashMap;
063    import java.util.List;
064    import java.util.Map;
065    import java.util.Properties;
066    import java.util.regex.Matcher;
067    
068    /**
069     * LegacyToDefaultConverter
070     */
071    @Service ("artifactConverter#legacy-to-default")
072    public class LegacyToDefaultConverter
073        implements ArtifactConverter
074    {
075        /**
076         * {@link List}<{@link Digester}
077         */
078        private List<? extends Digester> digesters;
079    
080        @Inject
081        private PlexusSisuBridge plexusSisuBridge;
082    
083        @Inject
084        private DigesterUtils digesterUtils;
085    
086        /**
087         *
088         */
089        private ModelConverter translator;
090    
091        /**
092         *
093         */
094        private ArtifactFactory artifactFactory;
095    
096        /**
097         *
098         */
099        private ArtifactHandlerManager artifactHandlerManager;
100    
101        /**
102         * default-value="false"
103         */
104        private boolean force;
105    
106        /**
107         * default-value="false"
108         */
109        private boolean dryrun;
110    
111        private Map<Artifact, List<String>> warnings = new HashMap<Artifact, List<String>>();
112    
113        @PostConstruct
114        public void initialize()
115            throws PlexusSisuBridgeException
116        {
117            this.digesters = digesterUtils.getAllDigesters();
118            translator = plexusSisuBridge.lookup( ModelConverter.class );
119            artifactFactory = plexusSisuBridge.lookup( ArtifactFactory.class );
120            artifactHandlerManager = plexusSisuBridge.lookup( ArtifactHandlerManager.class );
121        }
122    
123        public void convert( Artifact artifact, ArtifactRepository targetRepository )
124            throws ArtifactConversionException
125        {
126            if ( artifact.getRepository().getUrl().equals( targetRepository.getUrl() ) )
127            {
128                throw new ArtifactConversionException( Messages.getString( "exception.repositories.match" ) ); //$NON-NLS-1$
129            }
130    
131            if ( !validateMetadata( artifact ) )
132            {
133                addWarning( artifact, Messages.getString( "unable.to.validate.metadata" ) ); //$NON-NLS-1$
134                return;
135            }
136    
137            FileTransaction transaction = new FileTransaction();
138    
139            if ( !copyPom( artifact, targetRepository, transaction ) )
140            {
141                addWarning( artifact, Messages.getString( "unable.to.copy.pom" ) ); //$NON-NLS-1$
142                return;
143            }
144    
145            if ( !copyArtifact( artifact, targetRepository, transaction ) )
146            {
147                addWarning( artifact, Messages.getString( "unable.to.copy.artifact" ) ); //$NON-NLS-1$
148                return;
149            }
150    
151            Metadata metadata = createBaseMetadata( artifact );
152            Versioning versioning = new Versioning();
153            versioning.addVersion( artifact.getBaseVersion() );
154            metadata.setVersioning( versioning );
155            updateMetadata( new ArtifactRepositoryMetadata( artifact ), targetRepository, metadata, transaction );
156    
157            metadata = createBaseMetadata( artifact );
158            metadata.setVersion( artifact.getBaseVersion() );
159            versioning = new Versioning();
160    
161            Matcher matcher = Artifact.VERSION_FILE_PATTERN.matcher( artifact.getVersion() );
162            if ( matcher.matches() )
163            {
164                Snapshot snapshot = new Snapshot();
165                snapshot.setBuildNumber( Integer.parseInt( matcher.group( 3 ) ) );
166                snapshot.setTimestamp( matcher.group( 2 ) );
167                versioning.setSnapshot( snapshot );
168            }
169    
170            // TODO: merge latest/release/snapshot from source instead
171            metadata.setVersioning( versioning );
172            updateMetadata( new SnapshotArtifactRepositoryMetadata( artifact ), targetRepository, metadata, transaction );
173    
174            if ( !dryrun )
175            {
176                try
177                {
178                    transaction.commit();
179                }
180                catch ( TransactionException e )
181                {
182                    throw new ArtifactConversionException( Messages.getString( "transaction.failure", e.getMessage() ),
183                                                           e ); //$NON-NLS-1$
184                }
185            }
186        }
187    
188        @SuppressWarnings ("unchecked")
189        private boolean copyPom( Artifact artifact, ArtifactRepository targetRepository, FileTransaction transaction )
190            throws ArtifactConversionException
191        {
192            Artifact pom = artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
193                                                                  artifact.getVersion() );
194            pom.setBaseVersion( artifact.getBaseVersion() );
195            ArtifactRepository repository = artifact.getRepository();
196            File file = new File( repository.getBasedir(), repository.pathOf( pom ) );
197    
198            boolean result = true;
199            if ( file.exists() )
200            {
201                File targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( pom ) );
202    
203                String contents = null;
204                boolean checksumsValid = false;
205                try
206                {
207                    if ( testChecksums( artifact, file ) )
208                    {
209                        checksumsValid = true;
210                    }
211    
212                    // Even if the checksums for the POM are invalid we should still convert the POM
213                    contents = FileUtils.readFileToString( file, Charset.defaultCharset() );
214                }
215                catch ( IOException e )
216                {
217                    throw new ArtifactConversionException(
218                        Messages.getString( "unable.to.read.source.pom", e.getMessage() ), e ); //$NON-NLS-1$
219                }
220    
221                if ( checksumsValid && contents.indexOf( "modelVersion" ) >= 0 ) //$NON-NLS-1$
222                {
223                    // v4 POM
224                    try
225                    {
226                        boolean matching = false;
227                        if ( !force && targetFile.exists() )
228                        {
229                            String targetContents = FileUtils.readFileToString( targetFile, Charset.defaultCharset() );
230                            matching = targetContents.equals( contents );
231                        }
232                        if ( force || !matching )
233                        {
234                            transaction.createFile( contents, targetFile, digesters );
235                        }
236                    }
237                    catch ( IOException e )
238                    {
239                        throw new ArtifactConversionException(
240                            Messages.getString( "unable.to.write.target.pom", e.getMessage() ), e ); //$NON-NLS-1$
241                    }
242                }
243                else
244                {
245                    // v3 POM
246                    StringReader stringReader = new StringReader( contents );
247                    StringWriter writer = null;
248                    try
249                    {
250                        org.apache.maven.model.v3_0_0.io.xpp3.MavenXpp3Reader v3Reader =
251                            new org.apache.maven.model.v3_0_0.io.xpp3.MavenXpp3Reader();
252                        org.apache.maven.model.v3_0_0.Model v3Model = v3Reader.read( stringReader );
253    
254                        if ( doRelocation( artifact, v3Model, targetRepository, transaction ) )
255                        {
256                            Artifact relocatedPom =
257                                artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
258                                                                       artifact.getVersion() );
259                            targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( relocatedPom ) );
260                        }
261    
262                        Model v4Model = translator.translate( v3Model );
263    
264                        translator.validateV4Basics( v4Model, v3Model.getGroupId(), v3Model.getArtifactId(),
265                                                     v3Model.getVersion(), v3Model.getPackage() );
266    
267                        writer = new StringWriter();
268                        MavenXpp3Writer xpp3Writer = new MavenXpp3Writer();
269                        xpp3Writer.write( writer, v4Model );
270    
271                        transaction.createFile( writer.toString(), targetFile, digesters );
272    
273                        List<String> warnings = translator.getWarnings();
274    
275                        for ( String message : warnings )
276                        {
277                            addWarning( artifact, message );
278                        }
279                    }
280                    catch ( XmlPullParserException e )
281                    {
282                        addWarning( artifact, Messages.getString( "invalid.source.pom", e.getMessage() ) ); //$NON-NLS-1$
283                        result = false;
284                    }
285                    catch ( IOException e )
286                    {
287                        throw new ArtifactConversionException( Messages.getString( "unable.to.write.converted.pom" ),
288                                                               e ); //$NON-NLS-1$
289                    }
290                    catch ( PomTranslationException e )
291                    {
292                        addWarning( artifact, Messages.getString( "invalid.source.pom", e.getMessage() ) ); //$NON-NLS-1$
293                        result = false;
294                    }
295                    finally
296                    {
297                        IOUtils.closeQuietly( writer );
298                    }
299                }
300            }
301            else
302            {
303                addWarning( artifact, Messages.getString( "warning.missing.pom" ) ); //$NON-NLS-1$
304            }
305            return result;
306        }
307    
308        private boolean testChecksums( Artifact artifact, File file )
309            throws IOException
310        {
311            boolean result = true;
312            for ( Digester digester : digesters )
313            {
314                result &= verifyChecksum( file, file.getName() + "." + getDigesterFileExtension( digester ), digester,
315                                          //$NON-NLS-1$
316                                          artifact,
317                                          "failure.incorrect." + getDigesterFileExtension( digester ) ); //$NON-NLS-1$
318            }
319            return result;
320        }
321    
322        private boolean verifyChecksum( File file, String fileName, Digester digester, Artifact artifact, String key )
323            throws IOException
324        {
325            boolean result = true;
326    
327            File checksumFile = new File( file.getParentFile(), fileName );
328            if ( checksumFile.exists() )
329            {
330                String checksum = FileUtils.readFileToString( checksumFile, Charset.defaultCharset() );
331                try
332                {
333                    digester.verify( file, checksum );
334                }
335                catch ( DigesterException e )
336                {
337                    addWarning( artifact, Messages.getString( key ) );
338                    result = false;
339                }
340            }
341            return result;
342        }
343    
344        /**
345         * File extension for checksums
346         * TODO should be moved to plexus-digester ?
347         */
348        private String getDigesterFileExtension( Digester digester )
349        {
350            return digester.getAlgorithm().toLowerCase().replaceAll( "-", "" ); //$NON-NLS-1$ //$NON-NLS-2$
351        }
352    
353        private boolean copyArtifact( Artifact artifact, ArtifactRepository targetRepository, FileTransaction transaction )
354            throws ArtifactConversionException
355        {
356            File sourceFile = artifact.getFile();
357    
358            if ( sourceFile.getAbsolutePath().indexOf( "/plugins/" ) > -1 ) //$NON-NLS-1$
359            {
360                artifact.setArtifactHandler( artifactHandlerManager.getArtifactHandler( "maven-plugin" ) ); //$NON-NLS-1$
361            }
362    
363            File targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( artifact ) );
364    
365            boolean result = true;
366            try
367            {
368                boolean matching = false;
369                if ( !force && targetFile.exists() )
370                {
371                    matching = FileUtils.contentEquals( sourceFile, targetFile );
372                    if ( !matching )
373                    {
374                        addWarning( artifact, Messages.getString( "failure.target.already.exists" ) ); //$NON-NLS-1$
375                        result = false;
376                    }
377                }
378                if ( result )
379                {
380                    if ( force || !matching )
381                    {
382                        if ( testChecksums( artifact, sourceFile ) )
383                        {
384                            transaction.copyFile( sourceFile, targetFile, digesters );
385                        }
386                        else
387                        {
388                            result = false;
389                        }
390                    }
391                }
392            }
393            catch ( IOException e )
394            {
395                throw new ArtifactConversionException( Messages.getString( "error.copying.artifact" ), e ); //$NON-NLS-1$
396            }
397            return result;
398        }
399    
400        private Metadata createBaseMetadata( Artifact artifact )
401        {
402            Metadata metadata = new Metadata();
403            metadata.setArtifactId( artifact.getArtifactId() );
404            metadata.setGroupId( artifact.getGroupId() );
405            return metadata;
406        }
407    
408        private Metadata readMetadata( File file )
409            throws ArtifactConversionException
410        {
411            Metadata metadata;
412            MetadataXpp3Reader reader = new MetadataXpp3Reader();
413            FileReader fileReader = null;
414            try
415            {
416                fileReader = new FileReader( file );
417                metadata = reader.read( fileReader );
418            }
419            catch ( FileNotFoundException e )
420            {
421                throw new ArtifactConversionException( Messages.getString( "error.reading.target.metadata" ),
422                                                       e ); //$NON-NLS-1$
423            }
424            catch ( IOException e )
425            {
426                throw new ArtifactConversionException( Messages.getString( "error.reading.target.metadata" ),
427                                                       e ); //$NON-NLS-1$
428            }
429            catch ( XmlPullParserException e )
430            {
431                throw new ArtifactConversionException( Messages.getString( "error.reading.target.metadata" ),
432                                                       e ); //$NON-NLS-1$
433            }
434            finally
435            {
436                IOUtils.closeQuietly( fileReader );
437            }
438            return metadata;
439        }
440    
441        private boolean validateMetadata( Artifact artifact )
442            throws ArtifactConversionException
443        {
444            ArtifactRepository repository = artifact.getRepository();
445    
446            boolean result = true;
447    
448            RepositoryMetadata repositoryMetadata = new ArtifactRepositoryMetadata( artifact );
449            File file =
450                new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( repositoryMetadata ) );
451            if ( file.exists() )
452            {
453                Metadata metadata = readMetadata( file );
454                result = validateMetadata( metadata, repositoryMetadata, artifact );
455            }
456    
457            repositoryMetadata = new SnapshotArtifactRepositoryMetadata( artifact );
458            file = new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( repositoryMetadata ) );
459            if ( file.exists() )
460            {
461                Metadata metadata = readMetadata( file );
462                result = result && validateMetadata( metadata, repositoryMetadata, artifact );
463            }
464    
465            return result;
466        }
467    
468        @SuppressWarnings ("unchecked")
469        private boolean validateMetadata( Metadata metadata, RepositoryMetadata repositoryMetadata, Artifact artifact )
470        {
471            String groupIdKey;
472            String artifactIdKey = null;
473            String snapshotKey = null;
474            String versionKey = null;
475            String versionsKey = null;
476    
477            if ( repositoryMetadata.storedInGroupDirectory() )
478            {
479                groupIdKey = "failure.incorrect.groupMetadata.groupId"; //$NON-NLS-1$
480            }
481            else if ( repositoryMetadata.storedInArtifactVersionDirectory() )
482            {
483                groupIdKey = "failure.incorrect.snapshotMetadata.groupId"; //$NON-NLS-1$
484                artifactIdKey = "failure.incorrect.snapshotMetadata.artifactId"; //$NON-NLS-1$
485                versionKey = "failure.incorrect.snapshotMetadata.version"; //$NON-NLS-1$
486                snapshotKey = "failure.incorrect.snapshotMetadata.snapshot"; //$NON-NLS-1$
487            }
488            else
489            {
490                groupIdKey = "failure.incorrect.artifactMetadata.groupId"; //$NON-NLS-1$
491                artifactIdKey = "failure.incorrect.artifactMetadata.artifactId"; //$NON-NLS-1$
492                versionsKey = "failure.incorrect.artifactMetadata.versions"; //$NON-NLS-1$
493            }
494    
495            boolean result = true;
496    
497            if ( metadata.getGroupId() == null || !metadata.getGroupId().equals( artifact.getGroupId() ) )
498            {
499                addWarning( artifact, Messages.getString( groupIdKey ) );
500                result = false;
501            }
502            if ( !repositoryMetadata.storedInGroupDirectory() )
503            {
504                if ( metadata.getGroupId() == null || !metadata.getArtifactId().equals( artifact.getArtifactId() ) )
505                {
506                    addWarning( artifact, Messages.getString( artifactIdKey ) );
507                    result = false;
508                }
509                if ( !repositoryMetadata.storedInArtifactVersionDirectory() )
510                {
511                    // artifact metadata
512    
513                    boolean foundVersion = false;
514                    if ( metadata.getVersioning() != null )
515                    {
516                        for ( String version : (List<String>) metadata.getVersioning().getVersions() )
517                        {
518                            if ( version.equals( artifact.getBaseVersion() ) )
519                            {
520                                foundVersion = true;
521                                break;
522                            }
523                        }
524                    }
525    
526                    if ( !foundVersion )
527                    {
528                        addWarning( artifact, Messages.getString( versionsKey ) );
529                        result = false;
530                    }
531                }
532                else
533                {
534                    // snapshot metadata
535                    if ( !artifact.getBaseVersion().equals( metadata.getVersion() ) )
536                    {
537                        addWarning( artifact, Messages.getString( versionKey ) );
538                        result = false;
539                    }
540    
541                    if ( artifact.isSnapshot() )
542                    {
543                        Matcher matcher = Artifact.VERSION_FILE_PATTERN.matcher( artifact.getVersion() );
544                        if ( matcher.matches() )
545                        {
546                            boolean correct = false;
547                            if ( metadata.getVersioning() != null && metadata.getVersioning().getSnapshot() != null )
548                            {
549                                Snapshot snapshot = metadata.getVersioning().getSnapshot();
550                                int build = Integer.parseInt( matcher.group( 3 ) );
551                                String ts = matcher.group( 2 );
552                                if ( build == snapshot.getBuildNumber() && ts.equals( snapshot.getTimestamp() ) )
553                                {
554                                    correct = true;
555                                }
556                            }
557    
558                            if ( !correct )
559                            {
560                                addWarning( artifact, Messages.getString( snapshotKey ) );
561                                result = false;
562                            }
563                        }
564                    }
565                }
566            }
567            return result;
568        }
569    
570        private void updateMetadata( RepositoryMetadata artifactMetadata, ArtifactRepository targetRepository,
571                                     Metadata newMetadata, FileTransaction transaction )
572            throws ArtifactConversionException
573        {
574            File file = new File( targetRepository.getBasedir(),
575                                  targetRepository.pathOfRemoteRepositoryMetadata( artifactMetadata ) );
576    
577            Metadata metadata;
578            boolean changed;
579    
580            if ( file.exists() )
581            {
582                metadata = readMetadata( file );
583                changed = metadata.merge( newMetadata );
584            }
585            else
586            {
587                changed = true;
588                metadata = newMetadata;
589            }
590    
591            if ( changed )
592            {
593                StringWriter writer = null;
594                try
595                {
596                    writer = new StringWriter();
597    
598                    MetadataXpp3Writer mappingWriter = new MetadataXpp3Writer();
599    
600                    mappingWriter.write( writer, metadata );
601    
602                    transaction.createFile( writer.toString(), file, digesters );
603                }
604                catch ( IOException e )
605                {
606                    throw new ArtifactConversionException( Messages.getString( "error.writing.target.metadata" ),
607                                                           e ); //$NON-NLS-1$
608                }
609                finally
610                {
611                    IOUtils.closeQuietly( writer );
612                }
613            }
614        }
615    
616        private boolean doRelocation( Artifact artifact, org.apache.maven.model.v3_0_0.Model v3Model,
617                                      ArtifactRepository repository, FileTransaction transaction )
618            throws IOException
619        {
620            Properties properties = v3Model.getProperties();
621            if ( properties.containsKey( "relocated.groupId" ) || properties.containsKey( "relocated.artifactId" )
622                //$NON-NLS-1$ //$NON-NLS-2$
623                || properties.containsKey( "relocated.version" ) ) //$NON-NLS-1$
624            {
625                String newGroupId = properties.getProperty( "relocated.groupId", v3Model.getGroupId() ); //$NON-NLS-1$
626                properties.remove( "relocated.groupId" ); //$NON-NLS-1$
627    
628                String newArtifactId =
629                    properties.getProperty( "relocated.artifactId", v3Model.getArtifactId() ); //$NON-NLS-1$
630                properties.remove( "relocated.artifactId" ); //$NON-NLS-1$
631    
632                String newVersion = properties.getProperty( "relocated.version", v3Model.getVersion() ); //$NON-NLS-1$
633                properties.remove( "relocated.version" ); //$NON-NLS-1$
634    
635                String message = properties.getProperty( "relocated.message", "" ); //$NON-NLS-1$ //$NON-NLS-2$
636                properties.remove( "relocated.message" ); //$NON-NLS-1$
637    
638                if ( properties.isEmpty() )
639                {
640                    v3Model.setProperties( null );
641                }
642    
643                writeRelocationPom( v3Model.getGroupId(), v3Model.getArtifactId(), v3Model.getVersion(), newGroupId,
644                                    newArtifactId, newVersion, message, repository, transaction );
645    
646                v3Model.setGroupId( newGroupId );
647                v3Model.setArtifactId( newArtifactId );
648                v3Model.setVersion( newVersion );
649    
650                artifact.setGroupId( newGroupId );
651                artifact.setArtifactId( newArtifactId );
652                artifact.setVersion( newVersion );
653    
654                return true;
655            }
656            else
657            {
658                return false;
659            }
660        }
661    
662        private void writeRelocationPom( String groupId, String artifactId, String version, String newGroupId,
663                                         String newArtifactId, String newVersion, String message,
664                                         ArtifactRepository repository, FileTransaction transaction )
665            throws IOException
666        {
667            Model pom = new Model();
668            pom.setGroupId( groupId );
669            pom.setArtifactId( artifactId );
670            pom.setVersion( version );
671    
672            DistributionManagement dMngt = new DistributionManagement();
673    
674            Relocation relocation = new Relocation();
675            relocation.setGroupId( newGroupId );
676            relocation.setArtifactId( newArtifactId );
677            relocation.setVersion( newVersion );
678            if ( message != null && message.length() > 0 )
679            {
680                relocation.setMessage( message );
681            }
682    
683            dMngt.setRelocation( relocation );
684    
685            pom.setDistributionManagement( dMngt );
686    
687            Artifact artifact = artifactFactory.createBuildArtifact( groupId, artifactId, version, "pom" ); //$NON-NLS-1$
688            File pomFile = new File( repository.getBasedir(), repository.pathOf( artifact ) );
689    
690            StringWriter strWriter = new StringWriter();
691            MavenXpp3Writer pomWriter = new MavenXpp3Writer();
692            pomWriter.write( strWriter, pom );
693    
694            transaction.createFile( strWriter.toString(), pomFile, digesters );
695        }
696    
697        private void addWarning( Artifact artifact, String message )
698        {
699            List<String> messages = warnings.get( artifact );
700            if ( messages == null )
701            {
702                messages = new ArrayList<String>( 1 );
703            }
704            messages.add( message );
705            warnings.put( artifact, messages );
706        }
707    
708        public void clearWarnings()
709        {
710            warnings.clear();
711        }
712    
713        public Map<Artifact, List<String>> getWarnings()
714        {
715            return warnings;
716        }
717    
718    
719        public List<? extends Digester> getDigesters()
720        {
721            return digesters;
722        }
723    
724        public void setDigesters( List<Digester> digesters )
725        {
726            this.digesters = digesters;
727        }
728    
729        public ModelConverter getTranslator()
730        {
731            return translator;
732        }
733    
734        public void setTranslator( ModelConverter translator )
735        {
736            this.translator = translator;
737        }
738    
739        public ArtifactFactory getArtifactFactory()
740        {
741            return artifactFactory;
742        }
743    
744        public void setArtifactFactory( ArtifactFactory artifactFactory )
745        {
746            this.artifactFactory = artifactFactory;
747        }
748    
749        public ArtifactHandlerManager getArtifactHandlerManager()
750        {
751            return artifactHandlerManager;
752        }
753    
754        public void setArtifactHandlerManager( ArtifactHandlerManager artifactHandlerManager )
755        {
756            this.artifactHandlerManager = artifactHandlerManager;
757        }
758    
759        public boolean isForce()
760        {
761            return force;
762        }
763    
764        public void setForce( boolean force )
765        {
766            this.force = force;
767        }
768    
769        public boolean isDryrun()
770        {
771            return dryrun;
772        }
773    
774        public void setDryrun( boolean dryrun )
775        {
776            this.dryrun = dryrun;
777        }
778    }