| package org.apache.archiva.configuration; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import org.apache.archiva.common.FileTypeUtils; |
| import org.apache.archiva.configuration.functors.FiletypeSelectionPredicate; |
| import org.apache.archiva.configuration.io.registry.ConfigurationRegistryReader; |
| import org.apache.archiva.redback.components.registry.Registry; |
| import org.apache.archiva.redback.components.registry.RegistryException; |
| import org.apache.archiva.redback.components.registry.RegistryListener; |
| import org.apache.archiva.redback.components.registry.commons.CommonsConfigurationRegistry; |
| import org.apache.commons.collections.CollectionUtils; |
| import org.apache.commons.collections.Predicate; |
| import org.apache.commons.configuration.CombinedConfiguration; |
| import org.apache.tools.ant.types.selectors.SelectorUtils; |
| import org.springframework.stereotype.Service; |
| |
| import javax.annotation.PostConstruct; |
| import javax.inject.Inject; |
| import javax.inject.Named; |
| import java.lang.reflect.Field; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * FileTypes |
| */ |
| @Service("fileTypes") |
| public class FileTypes |
| implements RegistryListener |
| { |
| public static final String ARTIFACTS = "artifacts"; |
| |
| public static final String AUTO_REMOVE = "auto-remove"; |
| |
| public static final String INDEXABLE_CONTENT = "indexable-content"; |
| |
| public static final String IGNORED = "ignored"; |
| |
| @Inject |
| @Named(value = "archivaConfiguration#default") |
| private ArchivaConfiguration archivaConfiguration; |
| |
| /** |
| * Map of default values for the file types. |
| */ |
| private Map<String, List<String>> defaultTypeMap = new HashMap<>(); |
| |
| private List<String> artifactPatterns; |
| |
| /** |
| * Default exclusions from artifact consumers that are using the file types. Note that this is simplistic in the |
| * case of the support files (based on extension) as it is elsewhere - it may be better to match these to actual |
| * artifacts and exclude later during scanning. |
| * |
| * @deprecated |
| */ |
| public static final List<String> DEFAULT_EXCLUSIONS = FileTypeUtils.DEFAULT_EXCLUSIONS; |
| |
| public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration ) |
| { |
| this.archivaConfiguration = archivaConfiguration; |
| } |
| |
| /** |
| * Get the list of patterns for a specified filetype. |
| * <p/> |
| * <p/> |
| * You will always get a list. In this order. |
| * <ul> |
| * <li>The Configured List</li> |
| * <li>The Default List</li> |
| * <li>A single item list of <code>"**/*"</code></li> |
| * </ul> |
| * |
| * @param id the id to lookup. |
| * @return the list of patterns. |
| */ |
| public List<String> getFileTypePatterns( String id ) |
| { |
| Configuration config = archivaConfiguration.getConfiguration(); |
| Predicate selectedFiletype = new FiletypeSelectionPredicate( id ); |
| RepositoryScanningConfiguration repositoryScanningConfiguration = config.getRepositoryScanning(); |
| if ( repositoryScanningConfiguration != null ) |
| { |
| FileType filetype = |
| (FileType) CollectionUtils.find( config.getRepositoryScanning().getFileTypes(), selectedFiletype ); |
| |
| if ( ( filetype != null ) && CollectionUtils.isNotEmpty( filetype.getPatterns() ) ) |
| { |
| return filetype.getPatterns(); |
| } |
| } |
| List<String> defaultPatterns = defaultTypeMap.get( id ); |
| |
| if ( CollectionUtils.isEmpty( defaultPatterns ) ) |
| { |
| return Collections.singletonList( "**/*" ); |
| } |
| |
| return defaultPatterns; |
| } |
| |
| public synchronized boolean matchesArtifactPattern( String relativePath ) |
| { |
| // Correct the slash pattern. |
| relativePath = relativePath.replace( '\\', '/' ); |
| |
| if ( artifactPatterns == null ) |
| { |
| artifactPatterns = getFileTypePatterns( ARTIFACTS ); |
| } |
| |
| for ( String pattern : artifactPatterns ) |
| { |
| if ( SelectorUtils.matchPath( pattern, relativePath, false ) ) |
| { |
| // Found match |
| return true; |
| } |
| } |
| |
| // No match. |
| return false; |
| } |
| |
| public boolean matchesDefaultExclusions( String relativePath ) |
| { |
| // Correct the slash pattern. |
| relativePath = relativePath.replace( '\\', '/' ); |
| |
| for ( String pattern : DEFAULT_EXCLUSIONS ) |
| { |
| if ( SelectorUtils.matchPath( pattern, relativePath, false ) ) |
| { |
| // Found match |
| return true; |
| } |
| } |
| |
| // No match. |
| return false; |
| } |
| |
| @PostConstruct |
| public void initialize() |
| { |
| // TODO: why is this done by hand? |
| |
| // TODO: ideally, this would be instantiated by configuration instead, and not need to be a component |
| |
| String errMsg = "Unable to load default archiva configuration for FileTypes: "; |
| |
| try |
| { |
| CommonsConfigurationRegistry commonsRegistry = new CommonsConfigurationRegistry(); |
| |
| // Configure commonsRegistry |
| Field fld = commonsRegistry.getClass().getDeclaredField( "configuration" ); |
| fld.setAccessible( true ); |
| fld.set( commonsRegistry, new CombinedConfiguration() ); |
| commonsRegistry.addConfigurationFromResource( "org/apache/archiva/configuration/default-archiva.xml" ); |
| |
| // Read configuration as it was intended. |
| ConfigurationRegistryReader configReader = new ConfigurationRegistryReader(); |
| Configuration defaultConfig = configReader.read( commonsRegistry ); |
| |
| initialiseTypeMap( defaultConfig ); |
| } |
| catch ( RegistryException e ) |
| { |
| throw new RuntimeException( errMsg + e.getMessage(), e ); |
| } |
| catch ( SecurityException e ) |
| { |
| throw new RuntimeException( errMsg + e.getMessage(), e ); |
| } |
| catch ( NoSuchFieldException e ) |
| { |
| throw new RuntimeException( errMsg + e.getMessage(), e ); |
| } |
| catch ( IllegalArgumentException e ) |
| { |
| throw new RuntimeException( errMsg + e.getMessage(), e ); |
| } |
| catch ( IllegalAccessException e ) |
| { |
| throw new RuntimeException( errMsg + e.getMessage(), e ); |
| } |
| |
| this.archivaConfiguration.addChangeListener( this ); |
| } |
| |
| private void initialiseTypeMap( Configuration configuration ) |
| { |
| defaultTypeMap.clear(); |
| |
| // Store the default file type declaration. |
| List<FileType> filetypes = configuration.getRepositoryScanning().getFileTypes(); |
| for ( FileType filetype : filetypes ) |
| { |
| List<String> patterns = defaultTypeMap.get( filetype.getId() ); |
| if ( patterns == null ) |
| { |
| patterns = new ArrayList<>( filetype.getPatterns().size() ); |
| } |
| patterns.addAll( filetype.getPatterns() ); |
| |
| defaultTypeMap.put( filetype.getId(), patterns ); |
| } |
| } |
| |
| @Override |
| public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue ) |
| { |
| if ( propertyName.contains( "fileType" ) ) |
| { |
| artifactPatterns = null; |
| |
| initialiseTypeMap( archivaConfiguration.getConfiguration() ); |
| } |
| } |
| |
| @Override |
| public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue ) |
| { |
| /* nothing to do */ |
| } |
| } |