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.checksum.ChecksumAlgorithm; 024 import org.apache.archiva.checksum.ChecksummedFile; 025 import org.apache.archiva.configuration.ArchivaConfiguration; 026 import org.apache.archiva.configuration.ConfigurationNames; 027 import org.apache.archiva.configuration.FileTypes; 028 import org.apache.archiva.consumers.AbstractMonitoredConsumer; 029 import org.apache.archiva.consumers.ConsumerException; 030 import org.apache.archiva.consumers.KnownRepositoryContentConsumer; 031 import org.apache.archiva.redback.components.registry.Registry; 032 import org.apache.archiva.redback.components.registry.RegistryListener; 033 import org.springframework.context.annotation.Scope; 034 import org.springframework.stereotype.Service; 035 036 import javax.annotation.PostConstruct; 037 import javax.inject.Inject; 038 import java.io.File; 039 import java.io.IOException; 040 import java.util.ArrayList; 041 import java.util.Date; 042 import java.util.List; 043 044 /** 045 * ArtifactMissingChecksumsConsumer - Create missing and/or fix invalid checksums for the artifact. 046 * 047 * 048 */ 049 @Service( "knownRepositoryContentConsumer#create-missing-checksums" ) 050 @Scope( "prototype" ) 051 public class ArtifactMissingChecksumsConsumer 052 extends AbstractMonitoredConsumer 053 implements KnownRepositoryContentConsumer, RegistryListener 054 { 055 private String id = "create-missing-checksums"; 056 057 private String description = "Create Missing and/or Fix Invalid Checksums (.sha1, .md5)"; 058 059 private ArchivaConfiguration configuration; 060 061 private FileTypes filetypes; 062 063 private ChecksummedFile checksum; 064 065 private static final String TYPE_CHECKSUM_NOT_FILE = "checksum-bad-not-file"; 066 067 private static final String TYPE_CHECKSUM_CANNOT_CALC = "checksum-calc-failure"; 068 069 private static final String TYPE_CHECKSUM_CANNOT_CREATE = "checksum-create-failure"; 070 071 private File repositoryDir; 072 073 private List<String> includes = new ArrayList<String>( 0 ); 074 075 @Inject 076 public ArtifactMissingChecksumsConsumer( ArchivaConfiguration configuration, FileTypes filetypes ) 077 { 078 this.configuration = configuration; 079 this.filetypes = filetypes; 080 081 configuration.addChangeListener( this ); 082 083 initIncludes(); 084 } 085 086 public String getId() 087 { 088 return this.id; 089 } 090 091 public String getDescription() 092 { 093 return this.description; 094 } 095 096 public boolean isPermanent() 097 { 098 return false; 099 } 100 101 public void beginScan( ManagedRepository repo, Date whenGathered ) 102 throws ConsumerException 103 { 104 this.repositoryDir = new File( repo.getLocation() ); 105 } 106 107 public void beginScan( ManagedRepository repo, Date whenGathered, boolean executeOnEntireRepo ) 108 throws ConsumerException 109 { 110 beginScan( repo, whenGathered ); 111 } 112 113 public void completeScan() 114 { 115 /* do nothing */ 116 } 117 118 public void completeScan( boolean executeOnEntireRepo ) 119 { 120 completeScan(); 121 } 122 123 public List<String> getExcludes() 124 { 125 return getDefaultArtifactExclusions(); 126 } 127 128 public List<String> getIncludes() 129 { 130 return includes; 131 } 132 133 public void processFile( String path ) 134 throws ConsumerException 135 { 136 createFixChecksum( path, new ChecksumAlgorithm[]{ ChecksumAlgorithm.SHA1 } ); 137 createFixChecksum( path, new ChecksumAlgorithm[]{ ChecksumAlgorithm.MD5 } ); 138 } 139 140 public void processFile( String path, boolean executeOnEntireRepo ) 141 throws ConsumerException 142 { 143 processFile( path ); 144 } 145 146 private void createFixChecksum( String path, ChecksumAlgorithm checksumAlgorithm[] ) 147 { 148 File artifactFile = new File( this.repositoryDir, path ); 149 File checksumFile = new File( this.repositoryDir, path + checksumAlgorithm[0].getExt() ); 150 151 if ( checksumFile.exists() ) 152 { 153 checksum = new ChecksummedFile( artifactFile ); 154 try 155 { 156 if ( !checksum.isValidChecksum( checksumAlgorithm[0] ) ) 157 { 158 checksum.fixChecksums( checksumAlgorithm ); 159 triggerConsumerInfo( "Fixed checksum file " + checksumFile.getAbsolutePath() ); 160 } 161 } 162 catch ( IOException e ) 163 { 164 triggerConsumerError( TYPE_CHECKSUM_CANNOT_CALC, "Cannot calculate checksum for file " + checksumFile + 165 ": " + e.getMessage() ); 166 } 167 } 168 else if ( !checksumFile.exists() ) 169 { 170 checksum = new ChecksummedFile( artifactFile ); 171 try 172 { 173 checksum.createChecksum( checksumAlgorithm[0] ); 174 triggerConsumerInfo( "Created missing checksum file " + checksumFile.getAbsolutePath() ); 175 } 176 catch ( IOException e ) 177 { 178 triggerConsumerError( TYPE_CHECKSUM_CANNOT_CREATE, "Cannot create checksum for file " + checksumFile + 179 ": " + e.getMessage() ); 180 } 181 } 182 else 183 { 184 triggerConsumerWarning( TYPE_CHECKSUM_NOT_FILE, 185 "Checksum file " + checksumFile.getAbsolutePath() + " is not a file." ); 186 } 187 } 188 189 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 190 { 191 if ( ConfigurationNames.isRepositoryScanning( propertyName ) ) 192 { 193 initIncludes(); 194 } 195 } 196 197 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 198 { 199 /* do nothing */ 200 } 201 202 private void initIncludes() 203 { 204 includes = new ArrayList<String>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) ); 205 206 } 207 208 @PostConstruct 209 public void initialize() 210 { 211 configuration.addChangeListener( this ); 212 213 initIncludes(); 214 } 215 }