KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > launch > FileSpec


1 /*
2  * Copyright (c) 2005, Rob Gordon.
3  */

4 package org.oddjob.launch;
5
6 import java.io.File JavaDoc;
7 import java.io.FileFilter JavaDoc;
8
9 /**
10  *
11  * @author Rob Gordon.
12  */

13 public class FileSpec {
14
15     private File JavaDoc filespec;
16     
17     /**
18      */

19     private boolean caseSensative;
20             
21     public FileSpec(File JavaDoc filespec) {
22         this.filespec = filespec;
23     }
24     
25     /**
26      * Get the files mathcing the filespec.
27      *
28      * @return An array of all files.
29      */

30     public File JavaDoc[] getFiles() {
31         File JavaDoc dir = filespec.getParentFile();
32         File JavaDoc[] result = dir.listFiles(new FileFilter JavaDoc() {
33                 public boolean accept(File JavaDoc pathname) {
34                     return match(filespec.getName(), pathname.getPath(), caseSensative);
35                 }
36             });
37        if (result == null) {
38             result = new File JavaDoc[0];
39        }
40        return result;
41     }
42     
43     // taken as is from ant...
44

45     /**
46      * Tests whether or not a string matches against a pattern.
47      * The pattern may contain two special characters:<br>
48      * '*' means zero or more characters<br>
49      * '?' means one and only one character
50      *
51      * @param pattern The pattern to match against.
52      * Must not be <code>null</code>.
53      * @param str The string which must be matched against the pattern.
54      * Must not be <code>null</code>.
55      * @param isCaseSensitive Whether or not matching should be performed
56      * case sensitively.
57      *
58      *
59      * @return <code>true</code> if the string matches against the pattern,
60      * or <code>false</code> otherwise.
61      */

62     public static boolean match(String JavaDoc pattern, String JavaDoc str,
63                                 boolean isCaseSensitive) {
64         char[] patArr = pattern.toCharArray();
65         char[] strArr = str.toCharArray();
66         int patIdxStart = 0;
67         int patIdxEnd = patArr.length - 1;
68         int strIdxStart = 0;
69         int strIdxEnd = strArr.length - 1;
70         char ch;
71
72         boolean containsStar = false;
73         for (int i = 0; i < patArr.length; i++) {
74             if (patArr[i] == '*') {
75                 containsStar = true;
76                 break;
77             }
78         }
79
80         if (!containsStar) {
81             // No '*'s, so we make a shortcut
82
if (patIdxEnd != strIdxEnd) {
83                 return false; // Pattern and string do not have the same size
84
}
85             for (int i = 0; i <= patIdxEnd; i++) {
86                 ch = patArr[i];
87                 if (ch != '?') {
88                     if (isCaseSensitive && ch != strArr[i]) {
89                         return false; // Character mismatch
90
}
91                     if (!isCaseSensitive && Character.toUpperCase(ch)
92                             != Character.toUpperCase(strArr[i])) {
93                         return false; // Character mismatch
94
}
95                 }
96             }
97             return true; // String matches against pattern
98
}
99
100         if (patIdxEnd == 0) {
101             return true; // Pattern contains only '*', which matches anything
102
}
103
104         // Process characters before first star
105
while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {
106             if (ch != '?') {
107                 if (isCaseSensitive && ch != strArr[strIdxStart]) {
108                     return false; // Character mismatch
109
}
110                 if (!isCaseSensitive && Character.toUpperCase(ch)
111                         != Character.toUpperCase(strArr[strIdxStart])) {
112                     return false; // Character mismatch
113
}
114             }
115             patIdxStart++;
116             strIdxStart++;
117         }
118         if (strIdxStart > strIdxEnd) {
119             // All characters in the string are used. Check if only '*'s are
120
// left in the pattern. If so, we succeeded. Otherwise failure.
121
for (int i = patIdxStart; i <= patIdxEnd; i++) {
122                 if (patArr[i] != '*') {
123                     return false;
124                 }
125             }
126             return true;
127         }
128
129         // Process characters after last star
130
while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {
131             if (ch != '?') {
132                 if (isCaseSensitive && ch != strArr[strIdxEnd]) {
133                     return false; // Character mismatch
134
}
135                 if (!isCaseSensitive && Character.toUpperCase(ch)
136                         != Character.toUpperCase(strArr[strIdxEnd])) {
137                     return false; // Character mismatch
138
}
139             }
140             patIdxEnd--;
141             strIdxEnd--;
142         }
143         if (strIdxStart > strIdxEnd) {
144             // All characters in the string are used. Check if only '*'s are
145
// left in the pattern. If so, we succeeded. Otherwise failure.
146
for (int i = patIdxStart; i <= patIdxEnd; i++) {
147                 if (patArr[i] != '*') {
148                     return false;
149                 }
150             }
151             return true;
152         }
153
154         // process pattern between stars. padIdxStart and patIdxEnd point
155
// always to a '*'.
156
while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
157             int patIdxTmp = -1;
158             for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
159                 if (patArr[i] == '*') {
160                     patIdxTmp = i;
161                     break;
162                 }
163             }
164             if (patIdxTmp == patIdxStart + 1) {
165                 // Two stars next to each other, skip the first one.
166
patIdxStart++;
167                 continue;
168             }
169             // Find the pattern between padIdxStart & padIdxTmp in str between
170
// strIdxStart & strIdxEnd
171
int patLength = (patIdxTmp - patIdxStart - 1);
172             int strLength = (strIdxEnd - strIdxStart + 1);
173             int foundIdx = -1;
174             strLoop:
175             for (int i = 0; i <= strLength - patLength; i++) {
176                 for (int j = 0; j < patLength; j++) {
177                     ch = patArr[patIdxStart + j + 1];
178                     if (ch != '?') {
179                         if (isCaseSensitive && ch != strArr[strIdxStart + i
180                                 + j]) {
181                             continue strLoop;
182                         }
183                         if (!isCaseSensitive
184                             && Character.toUpperCase(ch)
185                                 != Character.toUpperCase(strArr[strIdxStart + i + j])) {
186                             continue strLoop;
187                         }
188                     }
189                 }
190
191                 foundIdx = strIdxStart + i;
192                 break;
193             }
194
195             if (foundIdx == -1) {
196                 return false;
197             }
198
199             patIdxStart = patIdxTmp;
200             strIdxStart = foundIdx + patLength;
201         }
202
203         // All characters in the string are used. Check if only '*'s are left
204
// in the pattern. If so, we succeeded. Otherwise failure.
205
for (int i = patIdxStart; i <= patIdxEnd; i++) {
206             if (patArr[i] != '*') {
207                 return false;
208             }
209         }
210         return true;
211     }
212
213 }
214
Popular Tags