001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.impl.scan;
018
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.List;
022
023 import org.apache.camel.spi.PackageScanFilter;
024 import org.springframework.util.AntPathMatcher;
025
026 /**
027 * <code>PatternBasedPackageScanFilter</code> uses an underlying
028 * {@link AntPathMatcher} to filter scanned files according to include and
029 * exclude patterns.
030 *
031 * @see AntPathMatcher
032 */
033 public class PatternBasedPackageScanFilter implements PackageScanFilter {
034 private AntPathMatcher matcher = new AntPathMatcher();
035
036 private List<String> excludePatterns;
037 private List<String> includePatterns;
038
039 /**
040 * add and exclude pattern to the filter. Classes matching this pattern will
041 * not match the filter
042 *
043 * @param excludePattern
044 */
045 public void addExcludePattern(String excludePattern) {
046 if (excludePatterns == null) {
047 excludePatterns = new ArrayList<String>();
048 }
049 excludePatterns.add(excludePattern);
050 }
051
052 /**
053 * add and include pattern to the filter. Classes must match one of supplied
054 * include patterns to match the filter
055 *
056 * @param includePattern
057 */
058 public void addIncludePattern(String includePattern) {
059 if (includePatterns == null) {
060 includePatterns = new ArrayList<String>();
061 }
062 includePatterns.add(includePattern);
063 }
064
065 public void addIncludePatterns(Collection<String> includes) {
066 if (includePatterns == null) {
067 includePatterns = new ArrayList<String>();
068 }
069 includePatterns.addAll(includes);
070 }
071
072 public void addExcludePatterns(Collection<String> excludes) {
073 if (excludePatterns == null) {
074 excludePatterns = new ArrayList<String>();
075 }
076 excludePatterns.addAll(excludes);
077 }
078
079 /**
080 * Tests if a given class matches the patterns in this filter. Patterns are
081 * specified by {@link AntPathMatcher}
082 * <p>
083 * if no include or exclude patterns are set then all classes match.
084 * <p>
085 * If the filter contains only include filters, then the candidate class
086 * must match one of the include patterns to match the filter and return
087 * true.
088 * <p>
089 * If the filter contains only exclude filters, then the filter will return
090 * true unless the candidate class matches an exclude pattern.
091 * <p>
092 * if this contains both include and exclude filters, then the above rules
093 * apply with excludes taking precedence over includes i.e. an include
094 * pattern of java.util.* and an exclude pattern of java.util.jar.* will
095 * include a file only if it is in the util pkg and not in the util.jar
096 * package.
097 *
098 * @return true if candidate class matches according to the above rules
099 */
100 public boolean matches(Class candidateClass) {
101 String candidate = candidateClass.getName();
102 if (includePatterns != null || excludePatterns != null) {
103
104 if (excludePatterns != null && excludePatterns.size() > 0) {
105 if (matchesAny(excludePatterns, candidate)) {
106 return false;
107 }
108 }
109
110 if (includePatterns != null && includePatterns.size() > 0) {
111 return matchesAny(includePatterns, candidate);
112 }
113
114 }
115 return true;
116 }
117
118 private boolean matchesAny(List<String> patterns, String candidate) {
119 for (String pattern : patterns) {
120 if (matcher.match(pattern, candidate)) {
121 return true;
122 }
123 }
124 return false;
125 }
126
127 }