001    package 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    
022    import org.apache.archiva.admin.model.beans.ManagedRepository;
023    import org.apache.archiva.common.plexusbridge.DigesterUtils;
024    import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
025    import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
026    import org.apache.archiva.consumers.AbstractMonitoredConsumer;
027    import org.apache.archiva.consumers.ConsumerException;
028    import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
029    import org.codehaus.plexus.digest.ChecksumFile;
030    import org.codehaus.plexus.digest.Digester;
031    import org.codehaus.plexus.digest.DigesterException;
032    import org.springframework.context.annotation.Scope;
033    import org.springframework.stereotype.Service;
034    
035    import javax.annotation.PostConstruct;
036    import javax.inject.Inject;
037    import java.io.File;
038    import java.io.FileNotFoundException;
039    import java.io.IOException;
040    import java.util.ArrayList;
041    import java.util.Date;
042    import java.util.List;
043    
044    /**
045     * ValidateChecksumConsumer - validate the provided checksum against the file it represents.
046     *
047     *
048     */
049    @Service( "knownRepositoryContentConsumer#validate-checksums" )
050    @Scope( "prototype" )
051    public class ValidateChecksumConsumer
052        extends AbstractMonitoredConsumer
053        implements KnownRepositoryContentConsumer
054    {
055        private static final String NOT_VALID_CHECKSUM = "checksum-not-valid";
056    
057        private static final String CHECKSUM_NOT_FOUND = "checksum-not-found";
058    
059        private static final String CHECKSUM_DIGESTER_FAILURE = "checksum-digester-failure";
060    
061        private static final String CHECKSUM_IO_ERROR = "checksum-io-error";
062    
063        /**
064         * default-value="validate-checksums"
065         */
066        private String id = "validate-checksums";
067    
068        /**
069         * default-value="Validate checksums against file."
070         */
071        private String description = "Validate checksums against file.";
072    
073        /**
074         *
075         */
076        private ChecksumFile checksum;
077    
078        /**
079         *
080         */
081        private List<Digester> allDigesters;
082    
083        @Inject
084        private PlexusSisuBridge plexusSisuBridge;
085    
086        @Inject
087        private DigesterUtils digesterUtils;
088    
089        private File repositoryDir;
090    
091        private List<String> includes;
092    
093        public String getId()
094        {
095            return this.id;
096        }
097    
098        public String getDescription()
099        {
100            return this.description;
101        }
102    
103        public boolean isPermanent()
104        {
105            return false;
106        }
107    
108        public void beginScan( ManagedRepository repository, Date whenGathered )
109            throws ConsumerException
110        {
111            this.repositoryDir = new File( repository.getLocation() );
112        }
113    
114        public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo )
115            throws ConsumerException
116        {
117            beginScan( repository, whenGathered );
118        }
119    
120        public void completeScan()
121        {
122            /* nothing to do */
123        }
124    
125        public void completeScan( boolean executeOnEntireRepo )
126        {
127            completeScan();
128        }
129    
130        public List<String> getExcludes()
131        {
132            return null;
133        }
134    
135        public List<String> getIncludes()
136        {
137            return this.includes;
138        }
139    
140        public void processFile( String path )
141            throws ConsumerException
142        {
143            File checksumFile = new File( this.repositoryDir, path );
144            try
145            {
146                if ( !checksum.isValidChecksum( checksumFile ) )
147                {
148                    triggerConsumerWarning( NOT_VALID_CHECKSUM, "The checksum for " + checksumFile + " is invalid." );
149                }
150            }
151            catch ( FileNotFoundException e )
152            {
153                triggerConsumerError( CHECKSUM_NOT_FOUND, "File not found during checksum validation: " + e.getMessage() );
154            }
155            catch ( DigesterException e )
156            {
157                triggerConsumerError( CHECKSUM_DIGESTER_FAILURE,
158                                      "Digester failure during checksum validation on " + checksumFile );
159            }
160            catch ( IOException e )
161            {
162                triggerConsumerError( CHECKSUM_IO_ERROR, "Checksum I/O error during validation on " + checksumFile );
163            }
164        }
165    
166        public void processFile( String path, boolean executeOnEntireReDpo )
167            throws Exception
168        {
169            processFile( path );
170        }
171    
172        @PostConstruct
173        public void initialize()
174            throws PlexusSisuBridgeException
175        {
176            checksum = plexusSisuBridge.lookup( ChecksumFile.class );
177            List<Digester> allDigesters = new ArrayList<Digester>( digesterUtils.getAllDigesters() );
178            includes = new ArrayList<String>( allDigesters.size() );
179            for ( Digester digester : allDigesters )
180            {
181                includes.add( "**/*" + digester.getFilenameExtension() );
182            }
183        }
184    }