This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.consumers.core;
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
022import org.apache.archiva.admin.model.beans.ManagedRepository;
023import org.apache.archiva.configuration.ArchivaConfiguration;
024import org.apache.archiva.configuration.FileTypes;
025import org.apache.archiva.consumers.AbstractMonitoredConsumer;
026import org.apache.archiva.consumers.ConsumerException;
027import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
028import org.apache.archiva.model.ArtifactReference;
029import org.apache.archiva.model.ProjectReference;
030import org.apache.archiva.model.VersionedReference;
031import org.apache.archiva.repository.ContentNotFoundException;
032import org.apache.archiva.repository.ManagedRepositoryContent;
033import org.apache.archiva.repository.RepositoryContentFactory;
034import org.apache.archiva.repository.RepositoryException;
035import org.apache.archiva.repository.RepositoryNotFoundException;
036import org.apache.archiva.repository.layout.LayoutException;
037import org.apache.archiva.repository.metadata.MetadataTools;
038import org.apache.archiva.repository.metadata.RepositoryMetadataException;
039import org.slf4j.Logger;
040import org.slf4j.LoggerFactory;
041import org.springframework.context.annotation.Scope;
042import org.springframework.stereotype.Service;
043
044import javax.annotation.PostConstruct;
045import javax.inject.Inject;
046import java.io.File;
047import java.io.IOException;
048import java.util.ArrayList;
049import java.util.Date;
050import java.util.List;
051
052/**
053 * MetadataUpdaterConsumer will create and update the metadata present within the repository.
054 */
055@Service( "knownRepositoryContentConsumer#metadata-updater" )
056@Scope( "prototype" )
057public class MetadataUpdaterConsumer
058    extends AbstractMonitoredConsumer
059    implements KnownRepositoryContentConsumer
060    // it's prototype bean so we assume configuration won't change during a run
061    //, RegistryListener
062{
063    private Logger log = LoggerFactory.getLogger( MetadataUpdaterConsumer.class );
064
065    /**
066     * default-value="metadata-updater"
067     */
068    private String id = "metadata-updater";
069
070    private String description = "Update / Create maven-metadata.xml files";
071
072    @Inject
073    private RepositoryContentFactory repositoryFactory;
074
075    @Inject
076    private MetadataTools metadataTools;
077
078    @Inject
079    private ArchivaConfiguration configuration;
080
081    @Inject
082    private FileTypes filetypes;
083
084    private static final String TYPE_METADATA_BAD_INTERNAL_REF = "metadata-bad-internal-ref";
085
086    private static final String TYPE_METADATA_WRITE_FAILURE = "metadata-write-failure";
087
088    private static final String TYPE_METADATA_IO = "metadata-io-warning";
089
090    private ManagedRepositoryContent repository;
091
092    private File repositoryDir;
093
094    private List<String> includes = new ArrayList<>( 0 );
095
096    private long scanStartTimestamp = 0;
097
098    @Override
099    public String getDescription( )
100    {
101        return description;
102    }
103
104    @Override
105    public String getId( )
106    {
107        return id;
108    }
109
110    public void setIncludes( List<String> includes )
111    {
112        this.includes = includes;
113    }
114
115    @Override
116    public void beginScan( ManagedRepository repoConfig, Date whenGathered )
117        throws ConsumerException
118    {
119        try
120        {
121            this.repository = repositoryFactory.getManagedRepositoryContent( repoConfig.getId( ) );
122            this.repositoryDir = new File( repository.getRepoRoot( ) );
123            this.scanStartTimestamp = System.currentTimeMillis( );
124        }
125        catch ( RepositoryNotFoundException e )
126        {
127            throw new ConsumerException( e.getMessage( ), e );
128        }
129        catch ( RepositoryException e )
130        {
131            throw new ConsumerException( e.getMessage( ), e );
132        }
133    }
134
135    @Override
136    public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo )
137        throws ConsumerException
138    {
139        beginScan( repository, whenGathered );
140    }
141
142    @Override
143    public void completeScan( )
144    {
145        /* do nothing here */
146    }
147
148    @Override
149    public void completeScan( boolean executeOnEntireRepo )
150    {
151        completeScan( );
152    }
153
154    @Override
155    public List<String> getExcludes( )
156    {
157        return getDefaultArtifactExclusions( );
158    }
159
160    @Override
161    public List<String> getIncludes( )
162    {
163        return this.includes;
164    }
165
166    @Override
167    public void processFile( String path )
168        throws ConsumerException
169    {
170        // Ignore paths like .index etc
171        if ( !path.startsWith( "." ) )
172        {
173            try
174            {
175                ArtifactReference artifact = repository.toArtifactReference( path );
176                updateVersionMetadata( artifact, path );
177                updateProjectMetadata( artifact, path );
178            }
179            catch ( LayoutException e )
180            {
181                log.info( "Not processing path that is not an artifact: {} ({})", path, e.getMessage( ) );
182            }
183        }
184    }
185
186    @Override
187    public void processFile( String path, boolean executeOnEntireRepo )
188        throws Exception
189    {
190        processFile( path );
191    }
192
193    private void updateProjectMetadata( ArtifactReference artifact, String path )
194    {
195        ProjectReference projectRef = new ProjectReference( );
196        projectRef.setGroupId( artifact.getGroupId( ) );
197        projectRef.setArtifactId( artifact.getArtifactId( ) );
198
199        try
200        {
201            String metadataPath = this.metadataTools.toPath( projectRef );
202
203            File projectMetadata = new File( this.repositoryDir, metadataPath );
204
205            if ( projectMetadata.exists( ) && ( projectMetadata.lastModified( ) >= this.scanStartTimestamp ) )
206            {
207                // This metadata is up to date. skip it.
208                log.debug( "Skipping uptodate metadata: {}", this.metadataTools.toPath( projectRef ) );
209                return;
210            }
211
212            metadataTools.updateMetadata( this.repository, projectRef );
213            log.debug( "Updated metadata: {}", this.metadataTools.toPath( projectRef ) );
214        }
215        catch ( LayoutException e )
216        {
217            log.warn( "Unable to convert path [{}] to an internal project reference: ", path, e );
218            triggerConsumerWarning( TYPE_METADATA_BAD_INTERNAL_REF,
219                "Unable to convert path [" + path + "] to an internal project reference: "
220                    + e.getMessage( ) );
221        }
222        catch ( RepositoryMetadataException e )
223        {
224            log.error( "Unable to write project metadat for artifact [{}]:", path, e );
225            triggerConsumerError( TYPE_METADATA_WRITE_FAILURE,
226                "Unable to write project metadata for artifact [" + path + "]: " + e.getMessage( ) );
227        }
228        catch ( IOException e )
229        {
230            log.warn( "Project metadata not written due to IO warning: ", e );
231            triggerConsumerWarning( TYPE_METADATA_IO,
232                "Project metadata not written due to IO warning: " + e.getMessage( ) );
233        }
234        catch ( ContentNotFoundException e )
235        {
236            log.warn( "Project metadata not written because no versions were found to update: ", e );
237            triggerConsumerWarning( TYPE_METADATA_IO,
238                "Project metadata not written because no versions were found to update: "
239                    + e.getMessage( ) );
240        }
241    }
242
243    private void updateVersionMetadata( ArtifactReference artifact, String path )
244    {
245        VersionedReference versionRef = new VersionedReference( );
246        versionRef.setGroupId( artifact.getGroupId( ) );
247        versionRef.setArtifactId( artifact.getArtifactId( ) );
248        versionRef.setVersion( artifact.getVersion( ) );
249
250        try
251        {
252            String metadataPath = this.metadataTools.toPath( versionRef );
253
254            File projectMetadata = new File( this.repositoryDir, metadataPath );
255
256            if ( projectMetadata.exists( ) && ( projectMetadata.lastModified( ) >= this.scanStartTimestamp ) )
257            {
258                // This metadata is up to date. skip it.
259                log.debug( "Skipping uptodate metadata: {}", this.metadataTools.toPath( versionRef ) );
260                return;
261            }
262
263            metadataTools.updateMetadata( this.repository, versionRef );
264            log.debug( "Updated metadata: {}", this.metadataTools.toPath( versionRef ) );
265        }
266        catch ( LayoutException e )
267        {
268            log.warn( "Unable to convert path [{}] to an internal version reference: ", path, e );
269            triggerConsumerWarning( TYPE_METADATA_BAD_INTERNAL_REF,
270                "Unable to convert path [" + path + "] to an internal version reference: "
271                    + e.getMessage( ) );
272        }
273        catch ( RepositoryMetadataException e )
274        {
275            log.error( "Unable to write version metadata for artifact [{}]: ", path, e );
276            triggerConsumerError( TYPE_METADATA_WRITE_FAILURE,
277                "Unable to write version metadata for artifact [" + path + "]: " + e.getMessage( ) );
278        }
279        catch ( IOException e )
280        {
281            log.warn( "Version metadata not written due to IO warning: ", e );
282            triggerConsumerWarning( TYPE_METADATA_IO,
283                "Version metadata not written due to IO warning: " + e.getMessage( ) );
284        }
285        catch ( ContentNotFoundException e )
286        {
287            log.warn( "Version metadata not written because no versions were found to update: ", e );
288            triggerConsumerWarning( TYPE_METADATA_IO,
289                "Version metadata not written because no versions were found to update: "
290                    + e.getMessage( ) );
291        }
292    }
293
294    /*
295    @Override
296    public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
297    {
298        if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
299        {
300            initIncludes();
301        }
302    }
303
304    @Override
305    public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
306    {
307        // do nothing here
308    }
309    */
310
311    private void initIncludes( )
312    {
313        includes = new ArrayList<>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );
314    }
315
316    @PostConstruct
317    public void initialize( )
318    {
319        //configuration.addChangeListener( this );
320
321        initIncludes( );
322    }
323}