001package org.apache.archiva.consumers.functors; 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.common.utils.BaseFile; 023import org.apache.archiva.consumers.RepositoryContentConsumer; 024import org.apache.archiva.repository.ManagedRepository; 025import org.apache.archiva.repository.features.IndexCreationFeature; 026import org.apache.commons.collections4.Predicate; 027import org.apache.commons.io.FilenameUtils; 028import org.apache.commons.lang3.StringUtils; 029import org.apache.tools.ant.types.selectors.SelectorUtils; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032 033import java.nio.file.Paths; 034import java.util.List; 035 036/** 037 * ConsumerWantsFilePredicate 038 */ 039public class ConsumerWantsFilePredicate 040 implements Predicate<RepositoryContentConsumer> 041{ 042 private BaseFile basefile; 043 044 private boolean isCaseSensitive = true; 045 046 private int wantedFileCount = 0; 047 048 private long changesSince = 0; 049 050 private ManagedRepository managedRepository; 051 052 private Logger logger = LoggerFactory.getLogger( getClass( ) ); 053 054 /** 055 * @deprecated use constructor with ManagedRepository 056 */ 057 public ConsumerWantsFilePredicate( ) 058 { 059 // no-op 060 } 061 062 public ConsumerWantsFilePredicate( ManagedRepository managedRepository ) 063 { 064 this.managedRepository = managedRepository; 065 } 066 067 @Override 068 public boolean evaluate( RepositoryContentConsumer object ) 069 { 070 boolean satisfies = false; 071 072 RepositoryContentConsumer consumer = (RepositoryContentConsumer) object; 073 if ( wantsFile( consumer, FilenameUtils.separatorsToUnix( basefile.getRelativePath( ) ) ) ) 074 { 075 satisfies = true; 076 077 // regardless of the timestamp, we record that it was wanted so it doesn't get counted as invalid 078 wantedFileCount++; 079 080 if ( !consumer.isProcessUnmodified( ) ) 081 { 082 // Timestamp finished points to the last successful scan, not this current one. 083 if ( basefile.lastModified( ) < changesSince ) 084 { 085 // Skip file as no change has occurred. 086 satisfies = false; 087 } 088 } 089 } 090 091 return satisfies; 092 } 093 094 public BaseFile getBasefile( ) 095 { 096 return basefile; 097 } 098 099 public int getWantedFileCount( ) 100 { 101 return wantedFileCount; 102 } 103 104 public boolean isCaseSensitive( ) 105 { 106 return isCaseSensitive; 107 } 108 109 public void setBasefile( BaseFile basefile ) 110 { 111 this.basefile = basefile; 112 this.wantedFileCount = 0; 113 } 114 115 public void setCaseSensitive( boolean isCaseSensitive ) 116 { 117 this.isCaseSensitive = isCaseSensitive; 118 } 119 120 private boolean wantsFile( RepositoryContentConsumer consumer, String relativePath ) 121 { 122 // Test excludes first. 123 List<String> excludes = consumer.getExcludes( ); 124 if ( excludes != null ) 125 { 126 for ( String pattern : excludes ) 127 { 128 if ( SelectorUtils.matchPath( pattern, relativePath, isCaseSensitive ) ) 129 { 130 // Definately does NOT WANT FILE. 131 return false; 132 } 133 } 134 } 135 136 if ( managedRepository != null ) 137 { 138 String indexDirectory; 139 if ( managedRepository.supportsFeature( IndexCreationFeature.class ) ) 140 { 141 IndexCreationFeature icf = managedRepository.getFeature( IndexCreationFeature.class ).get( ); 142 if ( icf.getIndexPath( ) == null ) 143 { 144 indexDirectory = ".index"; 145 } 146 else 147 { 148 indexDirectory = ( icf.getIndexPath( ).getScheme( ) == null ? Paths.get( icf.getIndexPath( ).getPath( ) ) : Paths.get( icf.getIndexPath( ) ) ).toString( ); 149 } 150 } 151 else 152 { 153 indexDirectory = ".index"; 154 } 155 if ( StringUtils.isEmpty( indexDirectory ) ) 156 { 157 indexDirectory = ".index"; 158 } 159 if ( StringUtils.startsWith( relativePath, indexDirectory ) ) 160 { 161 logger.debug( "ignore file {} part of the index directory {}", relativePath, indexDirectory ); 162 return false; 163 } 164 } 165 166 // Now test includes. 167 for ( String pattern : consumer.getIncludes( ) ) 168 { 169 if ( SelectorUtils.matchPath( pattern, relativePath, isCaseSensitive ) ) 170 { 171 // Specifically WANTS FILE. 172 return true; 173 } 174 } 175 176 // Not included, and Not excluded? Default to EXCLUDE. 177 return false; 178 } 179 180 public void setChangesSince( long changesSince ) 181 { 182 this.changesSince = changesSince; 183 } 184}