KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > directory > ldapstudio > browser > core > model > filter > parser > LdapFilterScanner


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  *
19  */

20
21 package org.apache.directory.ldapstudio.browser.core.model.filter.parser;
22
23
24 public class LdapFilterScanner
25 {
26
27     // From RFC 2254:
28
// -------------
29
// The string representation of an LDAP search filter is defined by the
30
// following grammar, following the ABNF notation defined in [5]. The
31
// filter format uses a prefix notation.
32
//
33
// filter = "(" filtercomp ")"
34
// filtercomp = and / or / not / item
35
// and = "&" filterlist
36
// or = "|" filterlist
37
// not = "!" filter
38
// filterlist = 1*filter
39
// item = simple / present / substring / extensible
40
// simple = attr filtertype value
41
// filtertype = equal / approx / greater / less
42
// equal = "="
43
// approx = "~="
44
// greater = ">="
45
// less = "<="
46
// extensible = attr [":dn"] [":" matchingrule] ":=" value
47
// / [":dn"] ":" matchingrule ":=" value
48
// present = attr "=*"
49
// substring = attr "=" [initial] any [final]
50
// initial = value
51
// any = "*" *(value "*")
52
// final = value
53
// attr = AttributeDescription from Section 4.1.5 of [1]
54
// matchingrule = MatchingRuleId from Section 4.1.9 of [1]
55
// value = AttributeValue from Section 4.1.6 of [1]
56
//
57
// The attr, matchingrule, and value constructs are as described in the
58
// corresponding section of [1] given above.
59
//
60
// If a value should contain any of the following characters
61
//
62
// Character ASCII value
63
// ---------------------------
64
// * 0x2a
65
// ( 0x28
66
// ) 0x29
67
// \ 0x5c
68
// NUL 0x00
69
//
70
// the character must be encoded as the backslash '\' character (ASCII
71
// 0x5c) followed by the two hexadecimal digits representing the ASCII
72
// value of the encoded character. The case of the two hexadecimal
73
// digits is not significant.
74

75     private String JavaDoc filter;
76
77     private int pos;
78
79     private int lastTokenType;
80
81
82     public LdapFilterScanner()
83     {
84         super();
85         this.filter = "";
86     }
87
88
89     public void setFilter( String JavaDoc filter )
90     {
91         this.filter = filter;
92         this.pos = -1;
93         this.lastTokenType = LdapFilterToken.NEW;
94     }
95
96
97     private char currentChar()
98     {
99         return 0 <= pos && pos < filter.length() ? filter.charAt( pos ) : '\u0000';
100     }
101
102
103     private char nextChar()
104     {
105         pos++;
106         return currentChar();
107     }
108
109
110     private char prevChar()
111     {
112         pos--;
113         return currentChar();
114     }
115
116
117     private char nextNonLinebreakChar()
118     {
119         while ( nextChar() == '\n' );
120         return currentChar();
121     }
122
123
124     private char prevNonLinebreakChar()
125     {
126         while ( prevChar() == '\n' );
127         return currentChar();
128     }
129
130
131     // private char nextNonWhitespaceChar() {
132
// while(Character.isWhitespace(nextChar()));
133
// return currentChar();
134
// }
135
// private char prevNonWhitespaceChar() {
136
// while(Character.isWhitespace(prevChar()));
137
// return currentChar();
138
// }
139

140     public LdapFilterToken nextToken()
141     {
142         char c;
143
144         // check for EOF
145
c = nextChar();
146         if ( c == '\u0000' )
147         {
148             return new LdapFilterToken( LdapFilterToken.EOF, "", pos );
149         }
150         else
151         {
152             prevChar();
153         }
154
155         // check for ignorable whitespaces
156
c = nextChar();
157         if ( Character.isWhitespace( c )
158             && ( lastTokenType == LdapFilterToken.RPAR || lastTokenType == LdapFilterToken.AND
159                 || lastTokenType == LdapFilterToken.OR || lastTokenType == LdapFilterToken.NOT ) )
160         {
161             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
162             while ( Character.isWhitespace( c ) )
163             {
164                 sb.append( c );
165                 c = nextChar();
166             }
167             prevChar();
168             return new LdapFilterToken( LdapFilterToken.WHITESPACE, sb.toString(), pos - sb.length() + 1 );
169         }
170         else
171         {
172             prevChar();
173         }
174
175         // check special characters
176
c = nextChar();
177         switch ( c )
178         {
179             case '(':
180                 this.lastTokenType = LdapFilterToken.LPAR;
181                 return new LdapFilterToken( this.lastTokenType, "(", pos );
182             case ')':
183                 this.lastTokenType = LdapFilterToken.RPAR;
184                 return new LdapFilterToken( this.lastTokenType, ")", pos );
185             case '&':
186                 if ( lastTokenType == LdapFilterToken.LPAR )
187                 {
188                     // if(nextNonWhitespaceChar()=='(') {
189
// prevNonWhitespaceChar();
190
this.lastTokenType = LdapFilterToken.AND;
191                     return new LdapFilterToken( this.lastTokenType, "&", pos );
192                     // }
193
// else {
194
// prevNonWhitespaceChar();
195
// }
196
}
197                 break;
198             case '|':
199                 if ( lastTokenType == LdapFilterToken.LPAR )
200                 {
201                     // if(nextNonWhitespaceChar()=='(') {
202
// prevNonWhitespaceChar();
203
this.lastTokenType = LdapFilterToken.OR;
204                     return new LdapFilterToken( this.lastTokenType, "|", pos );
205                     // }
206
// else {
207
// prevNonWhitespaceChar();
208
// }
209
}
210                 break;
211             case '!':
212                 if ( lastTokenType == LdapFilterToken.LPAR )
213                 {
214                     // if(nextNonWhitespaceChar()=='(') {
215
// prevNonWhitespaceChar();
216
this.lastTokenType = LdapFilterToken.NOT;
217                     return new LdapFilterToken( this.lastTokenType, "!", pos );
218                     // }
219
// else {
220
// prevNonWhitespaceChar();
221
// }
222
}
223                 break;
224             case '=':
225                 if ( lastTokenType == LdapFilterToken.ATTRIBUTE )
226                 {
227                     if ( nextChar() == '*' )
228                     {
229                         char t = nextChar();
230                         if ( t == ')' || t == '\u0000' )
231                         {
232                             prevChar();
233                             this.lastTokenType = LdapFilterToken.PRESENT;
234                             return new LdapFilterToken( this.lastTokenType, "=*", pos - 1 );
235                         }
236                         else
237                         {
238                             prevChar();
239                             prevChar();
240                             this.lastTokenType = LdapFilterToken.EQUAL;
241                             return new LdapFilterToken( this.lastTokenType, "=", pos );
242                         }
243                     }
244                     else
245                     {
246                         prevChar();
247                         this.lastTokenType = LdapFilterToken.EQUAL;
248                         return new LdapFilterToken( this.lastTokenType, "=", pos );
249                     }
250                 }
251                 break;
252             case '>':
253                 if ( lastTokenType == LdapFilterToken.ATTRIBUTE )
254                 {
255                     if ( nextChar() == '=' )
256                     {
257                         this.lastTokenType = LdapFilterToken.GREATER;
258                         return new LdapFilterToken( this.lastTokenType, ">=", pos - 1 );
259                     }
260                     else
261                     {
262                         prevChar();
263                     }
264                 }
265                 break;
266             case '<':
267                 if ( lastTokenType == LdapFilterToken.ATTRIBUTE )
268                 {
269                     if ( nextChar() == '=' )
270                     {
271                         this.lastTokenType = LdapFilterToken.LESS;
272                         return new LdapFilterToken( this.lastTokenType, "<=", pos - 1 );
273                     }
274                     else
275                     {
276                         prevChar();
277                     }
278                 }
279                 break;
280             case '~':
281                 if ( lastTokenType == LdapFilterToken.ATTRIBUTE )
282                 {
283                     if ( nextChar() == '=' )
284                     {
285                         this.lastTokenType = LdapFilterToken.APROX;
286                         return new LdapFilterToken( this.lastTokenType, "~=", pos - 1 );
287                     }
288                     else
289                     {
290                         prevChar();
291                     }
292                 }
293                 break;
294         } // switch
295
prevChar();
296
297         // check attribute
298
if ( this.lastTokenType == LdapFilterToken.LPAR )
299         {
300             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
301
302             // first char must be non-whitespace
303
c = nextChar();
304             while ( c != '=' && c != '<' && c != '>' && c != '~' && c != '(' && c != ')' && c != '\u0000'
305                 && !Character.isWhitespace( c ) )
306             {
307                 sb.append( c );
308                 c = nextChar();
309             }
310             prevChar();
311
312             if ( sb.length() > 0 )
313             {
314                 this.lastTokenType = LdapFilterToken.ATTRIBUTE;
315                 return new LdapFilterToken( this.lastTokenType, sb.toString(), pos - sb.length() + 1 );
316             }
317         }
318
319         // check value
320
if ( lastTokenType == LdapFilterToken.EQUAL || lastTokenType == LdapFilterToken.GREATER
321             || lastTokenType == LdapFilterToken.LESS || lastTokenType == LdapFilterToken.APROX )
322         {
323
324             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
325             c = nextNonLinebreakChar();
326             while ( c != '(' && c != ')' && c != '\u0000' )
327             {
328                 sb.append( c );
329                 c = nextNonLinebreakChar();
330             }
331             prevNonLinebreakChar();
332
333             if ( sb.length() > 0 )
334             {
335                 this.lastTokenType = LdapFilterToken.VALUE;
336                 return new LdapFilterToken( this.lastTokenType, sb.toString(), pos - sb.length() + 1 );
337             }
338         }
339
340         // no match
341
StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
342         c = nextChar();
343         while ( c != '(' && c != ')' && c != '\u0000' )
344         {
345             sb.append( c );
346             c = nextChar();
347         }
348         prevChar();
349         // this.lastTokenType = LdapFilterToken.UNKNOWN;
350
// return new LdapFilterToken(this.lastTokenType, sb.toString(),
351
// pos-sb.length());
352
return new LdapFilterToken( LdapFilterToken.UNKNOWN, sb.toString(), pos - sb.length() + 1 );
353     }
354
355 }
356
Popular Tags