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 */ 017package org.apache.xbean.finder.filter; 018 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.Iterator; 022import java.util.LinkedHashSet; 023import java.util.List; 024import java.util.Set; 025 026/** 027 * @version $Rev$ $Date$ 028 */ 029public class Filters { 030 private static final Filter NONE = new Filter() { 031 public boolean accept(String name) { 032 return false; 033 } 034 }; 035 036 public static Filter packages(String... packages) { 037 List<Filter> filters = new ArrayList<Filter>(); 038 for (String s : packages) { 039 filters.add(new PackageFilter(s)); 040 } 041 042 return optimize(filters); 043 } 044 045 public static Filter classes(String... classes) { 046 List<Filter> filters = new ArrayList<Filter>(); 047 for (String s : classes) { 048 filters.add(new ClassFilter(s)); 049 } 050 051 return optimize(filters); 052 } 053 054 public static Filter prefixes(String... prefixes) { 055 List<Filter> filters = new ArrayList<Filter>(); 056 for (String s : prefixes) { 057 filters.add(new PrefixFilter(s)); 058 } 059 060 return optimize(filters); 061 } 062 063 public static Filter tokens(String... tokens) { 064 List<Filter> filters = new ArrayList<Filter>(); 065 for (String s : tokens) { 066 filters.add(new ContainsFilter(s)); 067 } 068 069 return optimize(filters); 070 } 071 072 public static Filter suffixes(String... suffixes) { 073 List<Filter> filters = new ArrayList<Filter>(); 074 for (String s : suffixes) { 075 filters.add(new SuffixFilter(s)); 076 } 077 078 return optimize(filters); 079 } 080 081 public static Filter patterns(String... patterns) { 082 List<Filter> filters = new ArrayList<Filter>(); 083 for (String s : patterns) { 084 filters.add(new PatternFilter(s)); 085 } 086 087 return optimize(filters); 088 } 089 090 091 public static Filter optimize(Filter... filters) { 092 return optimize(Arrays.asList(filters)); 093 } 094 095 public static Filter optimize(List<Filter>... filterss) { 096 Set<Filter> unwrapped = new LinkedHashSet<Filter>(); 097 098 for (List<Filter> filters : filterss) { 099 unwrap(filters, unwrapped); 100 } 101 102 if (unwrapped.size() > 1) { 103 Iterator<Filter> iterator = unwrapped.iterator(); 104 while (iterator.hasNext()) { 105 Filter filter = iterator.next(); 106 if (filter == NONE) iterator.remove(); 107 } 108 } 109 110 if (unwrapped.size() == 0) return NONE; 111 if (unwrapped.size() == 1) return unwrapped.iterator().next(); 112 return new FilterList(unwrapped); 113 } 114 115 /** 116 * Will invert the meaning of this filter by wrapping it with 117 * a filter that negates the return of the accept method. 118 * 119 * If the passed in filter is already wrapped, it will be 120 * unwrapped and returned. This is to prevent endless wrapping 121 * if the invert method is called many times. 122 * 123 * @param filter 124 * @return 125 */ 126 public static Filter invert(Filter filter) { 127 if (filter instanceof NegativeFilter) { 128 NegativeFilter negativeFilter = (NegativeFilter) filter; 129 return negativeFilter.getFilter(); 130 } 131 132 return new NegativeFilter(filter); 133 } 134 135 private static void unwrap(List<Filter> filters, Set<Filter> unwrapped) { 136 for (Filter filter : filters) { 137 if (filter instanceof FilterList) { 138 FilterList filterList = (FilterList) filter; 139 unwrap(filterList.getFilters(), unwrapped); 140 } else { 141 unwrapped.add(filter); 142 } 143 } 144 } 145 146 private static final class NegativeFilter implements Filter { 147 private final Filter filter; 148 149 public NegativeFilter(Filter filter) { 150 this.filter = filter; 151 } 152 153 public boolean accept(String name) { 154 return !filter.accept(name); 155 } 156 157 public Filter getFilter() { 158 return filter; 159 } 160 } 161 162}