/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* A class for parsing LDAP search filters (defined in RFC 1960, 2254)
*
* @author Jon Ruiz
* @author Rosanna Lee
*/
}
// %%% "filter" and "pos" are not declared "private" due to bug 4064984.
int pos;
protected static final boolean debug = false;
pos = 0;
rootFilter = this.createNextFilter();
}
// Returns true if targetAttrs passes the filter
if (targetAttrs == null)
return false;
}
/*
* Utility routines used by member classes
*/
// does some pre-processing on the string to make it look exactly lik
// what the parser expects. This only needs to be called once.
protected void normalizeFilter() {
skipWhiteSpace(); // get rid of any leading whitespaces
// Sometimes, search filters don't have "(" and ")" - add them
if(getCurrentChar() != BEGIN_FILTER_TOKEN) {
}
// this would be a good place to strip whitespace if desired
filter);}
}
private void skipWhiteSpace() {
consumeChar();
}
}
throws InvalidSearchFilterException {
try {
// make sure every filter starts with "("
if(getCurrentChar() != BEGIN_FILTER_TOKEN) {
throw new InvalidSearchFilterException("expected \"" +
"\" at position " +
pos);
}
// skip past the "("
this.consumeChar();
// use the next character to determine the type of filter
switch(getCurrentChar()) {
case AND_TOKEN:
filter = new CompoundFilter(true);
break;
case OR_TOKEN:
filter = new CompoundFilter(false);
break;
case NOT_TOKEN:
break;
default:
filter = new AtomicFilter();
break;
}
// make sure every filter ends with ")"
if(getCurrentChar() != END_FILTER_TOKEN) {
throw new InvalidSearchFilterException("expected \"" +
"\" at position " +
pos);
}
// skip past the ")"
this.consumeChar();
} catch (InvalidSearchFilterException e) {
throw e; // just rethrow these
// catch all - any uncaught exception while parsing will end up here
} catch (Exception e) {
throw new InvalidSearchFilterException("Unable to parse " +
this.filter + "\"");
}
return filter;
}
protected char getCurrentChar() {
}
protected char relCharAt(int i) {
}
protected void consumeChar() {
pos++;
}
protected void consumeChars(int i) {
pos += i;
}
}
" " + endIndex);}
}
/**
* A class for dealing with compound filters ("and" & "or" filters).
*/
private boolean polarity;
subFilters = new Vector();
}
}
}
return !polarity;
}
}
return polarity;
}
} /* CompoundFilter */
/**
* A class for dealing with NOT filters
*/
}
}
} /* notFilter */
// note: declared here since member classes can't have static variables
/**
* A class for dealing wtih atomic filters
*/
private int matchType;
try {
// find the end
//determine the match type
switch(qualifier) {
case APPROX_TOKEN:
break;
case GREATER_TOKEN:
break;
case LESS_TOKEN:
break;
case EXTEND_TOKEN:
throw new OperationNotSupportedException("Extensible match not supported");
default:
break;
}
//update our position
} catch (Exception e) {
e.printStackTrace();}
new InvalidSearchFilterException("Unable to parse " +
sfe.setRootCause(e);
throw(sfe);
}
value);}
}
try {
return false;
}
} catch (NamingException ne) {
"here");}
return false;
}
while(candidates.hasMoreElements()) {
switch(matchType) {
case APPROX_MATCH:
case EQUAL_MATCH:
return true;
}
break;
case GREATER_MATCH:
return true;
}
break;
case LESS_MATCH:
return true;
}
break;
default:
"matchType");}
}
}
return false;
}
// used for substring comparisons (where proto has "*" wildcards
// simple case 1: "*" means attribute presence is being tested
return true;
}
// simple case 2: if there are no wildcards, call String.equals()
}
// do the work: make sure all the substrings are present
int currentPos = 0;
// do we need to begin with the first token?
return false;
}
while(subStrs.hasMoreTokens()) {
currentStr +"\"");}
if(currentPos == -1) {
return false;
}
}
// do we need to end with the last token?
return false;
}
return true;
}
} /* AtomicFilter */
// ----- static methods for producing string filters given attribute set
// ----- or object array
/**
* Creates an LDAP filter as a conjuction of the attributes supplied.
*/
return "objectClass=*";
}
answer = "(& ";
// only checking presence of attribute
} else {
) {
}
}
}
}
answer += ")";
//System.out.println("filter: " + answer);
return answer;
}
// Writes the hex representation of a byte to a StringBuffer.
char c;
c = (char) ((x >> 4) & 0xf);
if (c > 9)
c = (char) ((c-10) + 'A');
else
c = (char)(c + '0');
c = (char) (x & 0xf);
if (c > 9)
c = (char)((c-10) + 'A');
else
c = (char)(c + '0');
}
/**
* Returns the string representation of an object (such as an attr value).
* If obj is a byte array, encode each item as \xx, where xx is hex encoding
* of the byte value.
* Else, if obj is not a String, use its string representation (toString()).
* Special characters in obj (or its string representation) are then
* encoded appropriately according to RFC 2254.
* * \2a
* ( \28
* ) \29
* \ \5c
* NUL \00
*/
return null;
if (obj instanceof byte[]) {
// binary data must be encoded as \hh where hh is a hex char
}
}
} else {
}
char ch;
for (int i = 0; i < len; i++) {
case '*':
break;
case '(':
break;
case ')':
break;
case '\\':
break;
case 0:
break;
default:
}
}
}
/**
* Finds the first occurrence of <tt>ch</tt> in <tt>val</tt> starting
* from position <tt>start</tt>. It doesn't count if <tt>ch</tt>
* has been escaped by a backslash (\)
*/
// if at start of string, or not there at all, or if not escaped
return where;
// start search after escaped star
}
return -1;
}
/**
* Formats the expression <tt>expr</tt> using arguments from the array
* <tt>args</tt>.
*
* <code>{i}</code> specifies the <code>i</code>'th element from
* the array <code>args</code> is to be substituted for the
* string "<code>{i}</code>".
*
* To escape '{' or '}' (or any other character), use '\'.
*
* Uses getEncodedStringRep() to do encoding.
*/
throws NamingException {
int param;
if (pend < 0) {
}
// at this point, pend should be pointing at '}'
try {
} catch (NumberFormatException e) {
throw new InvalidSearchFilterException(
"integer expected inside {}: " + expr);
}
throw new InvalidSearchFilterException(
"number exceeds argument list: " + param);
}
}
}
/*
* returns an Attributes instance containing only attributeIDs given in
* "attributeIDs" whose values come from the given DSContext.
*/
return originals;
}
}
return result;
}
/* For testing filter
public static void main(String[] args) {
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
attrs.put("cn", "Rosanna Lee");
attrs.put("sn", "Lee");
attrs.put("fn", "Rosanna");
attrs.put("id", "10414");
attrs.put("machine", "jurassic");
try {
System.out.println(format(attrs));
String expr = "(&(Age = {0})(Account Balance <= {1}))";
Object[] fargs = new Object[2];
// fill in the parameters
fargs[0] = new Integer(65);
fargs[1] = new Float(5000);
System.out.println(format(expr, fargs));
System.out.println(format("bin={0}",
new Object[] {new byte[] {0, 1, 2, 3, 4, 5}}));
System.out.println(format("bin=\\{anything}", null));
} catch (NamingException e) {
e.printStackTrace();
}
}
*/
}