KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > tools > NamePatternMatcher


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.tools;
57
58 import java.util.ArrayList JavaDoc;
59 import java.util.Iterator JavaDoc;
60 import java.util.List JavaDoc;
61 import java.util.StringTokenizer JavaDoc;
62
63 import org.apache.oro.text.perl.Perl5Util;
64 import org.apache.tools.ant.Project;
65 import org.apache.tools.ant.Task;
66 import org.objectstyle.cayenne.util.CayenneMapEntry;
67
68 /**
69  * Provides name pattern matching functionality.
70  *
71  * @author Andrei Adamchik, Mike Kienenberger
72  * @since 1.2
73  */

74 public class NamePatternMatcher {
75
76     protected Task parentTask;
77     private static final Perl5Util regexUtil = new Perl5Util();
78     private static final String JavaDoc[] emptyArray = new String JavaDoc[0];
79
80     protected String JavaDoc[] itemIncludeFilters;
81     protected String JavaDoc[] itemExcludeFilters;
82
83     public NamePatternMatcher(Task parentTask, String JavaDoc includePattern,
84             String JavaDoc excludePattern) {
85         this.parentTask = parentTask;
86         this.itemIncludeFilters = tokenizePattern(includePattern);
87         this.itemExcludeFilters = tokenizePattern(excludePattern);
88     }
89
90     /**
91      * Returns an array of valid Jakarta ORO regular expressions. Takes a
92      * comma-separated list of patterns, attempting to convert them to the ORO
93      * syntax. E.g.
94      * <p>
95      * <code>"billing_*,user?"</code> will become a set of two expressions:
96      * <p>
97      * <code>/billing_.* /</code><br>
98      * <code>/user.?/</code><br>
99      */

100     public String JavaDoc[] tokenizePattern(String JavaDoc pattern) {
101         if (pattern != null && pattern.length() > 0) {
102             StringTokenizer JavaDoc toks = new StringTokenizer JavaDoc(pattern, ",");
103
104             int len = toks.countTokens();
105             if (len == 0) {
106                 return emptyArray;
107             }
108
109             List JavaDoc patterns = new ArrayList JavaDoc(len);
110             for (int i = 0; i < len; i++) {
111                 String JavaDoc nextPattern = toks.nextToken();
112                 StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
113
114                 // convert * into regex syntax
115
// e.g. abc*x becomes /^abc.*x$/
116
// or abc?x becomes /^abc.?x$/
117
buffer.append("/^");
118                 for (int j = 0; j < nextPattern.length(); j++) {
119                     char nextChar = nextPattern.charAt(j);
120                     if (nextChar == '*' || nextChar == '?') {
121                         buffer.append('.');
122                     }
123                     buffer.append(nextChar);
124                 }
125                 buffer.append("$/");
126
127                 String JavaDoc finalPattern = buffer.toString();
128
129                 // test the pattern
130
try {
131                     regexUtil.match(finalPattern, "abc_123");
132                 }
133                 catch (Exception JavaDoc e) {
134                     parentTask.log("Ignoring invalid pattern ["
135                             + nextPattern
136                             + "], reason: "
137                             + e.getMessage(), Project.MSG_WARN);
138                     continue;
139                 }
140
141                 patterns.add(finalPattern);
142             }
143
144             return (String JavaDoc[]) patterns.toArray(new String JavaDoc[patterns.size()]);
145         }
146         else {
147             return emptyArray;
148         }
149     }
150
151     /**
152      * Applies preconfigured list of filters to the list, removing entities that
153      * do not pass the filter.
154      */

155     protected List JavaDoc filter(List JavaDoc items) {
156         if (items == null || items.isEmpty()) {
157             return items;
158         }
159
160         if ((itemIncludeFilters.length == 0) && (itemExcludeFilters.length == 0)) {
161             return items;
162         }
163
164         Iterator JavaDoc it = items.iterator();
165         while (it.hasNext()) {
166             CayenneMapEntry entity = (CayenneMapEntry) it.next();
167
168             if (!passedIncludeFilter(entity)) {
169                 it.remove();
170                 continue;
171             }
172
173             if (!passedExcludeFilter(entity)) {
174                 it.remove();
175                 continue;
176             }
177         }
178
179         return items;
180     }
181
182     /**
183      * Returns true if the entity matches any one of the "include" patterns, or
184      * if there is no "include" patterns defined.
185      */

186     protected boolean passedIncludeFilter(CayenneMapEntry item) {
187         if (itemIncludeFilters.length == 0) {
188             return true;
189         }
190
191         String JavaDoc itemName = item.getName();
192         for (int i = 0; i < itemIncludeFilters.length; i++) {
193             if (regexUtil.match(itemIncludeFilters[i], itemName)) {
194                 return true;
195             }
196         }
197
198         return false;
199     }
200
201     /**
202      * Returns true if the entity does not match any one of the "exclude"
203      * patterns, or if there is no "exclude" patterns defined.
204      */

205     protected boolean passedExcludeFilter(CayenneMapEntry item) {
206         if (itemExcludeFilters.length == 0) {
207             return true;
208         }
209
210         String JavaDoc itemName = item.getName();
211         for (int i = 0; i < itemExcludeFilters.length; i++) {
212             if (regexUtil.match(itemExcludeFilters[i], itemName)) {
213                 return false;
214             }
215         }
216
217         return true;
218     }
219
220     public static String JavaDoc replaceWildcardInStringWithString(
221             String JavaDoc wildcard,
222             String JavaDoc pattern,
223             String JavaDoc replacement) {
224         if (null == pattern || null == wildcard)
225             return pattern;
226
227         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
228         int lastPos = 0;
229         int wildCardPos = pattern.indexOf(wildcard);
230         while (-1 != wildCardPos) {
231             if (lastPos != wildCardPos) {
232                 buffer.append(pattern.substring(lastPos, wildCardPos));
233             }
234             buffer.append(replacement);
235             lastPos += wildCardPos + wildcard.length();
236             wildCardPos = pattern.indexOf(wildcard, lastPos);
237         }
238
239         if (lastPos < pattern.length()) {
240             buffer.append(pattern.substring(lastPos));
241         }
242
243         return buffer.toString();
244     }
245 }
Popular Tags