/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1999 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ package netscape.ldap.util; import netscape.ldap.*; import java.util.*; /** * Represents an LDAP search filter, which includes the string-based * representation of the filter and other information retrieved from the * LDAP filter configuration file (or from a buffer in memory or from a URL). *
* * Although this class provides methods to create and modify LDAP * filters, in most cases, you do not need to use these methods. * In most situations, these classes are used to access individual * filters from filter configuration files. *
* * For example, you might do the following: *
* *
LDAPFilterDescriptor
constructor to
* read the filter configuration file into memory.
* getFilters
method to get a list of
* filters that match the search criteria. This list of filters
* is represented by an LDAPFilterList
object.
* LDAPFilter
object), and apply the filter to
* a search.
* * * For an example of using an object of this class and for more information on * the filter configuration file syntax, see the documentation for LDAPFilterDescriptor. *
*
* @see LDAPFilterDescriptor
* @see LDAPFilterList
* @version 1.0
*/
public class LDAPFilter implements Cloneable {
private static final int DEFAULT_FILTER_LENGTH = 256;
private String m_strFilter = null;
private String m_strDescription; // token 4 from filter configuration file
private int m_nScope; // token 5 from filter configuration file
private boolean m_bIsExact;
private String m_strMatchPattern; // token 1 from filter configuration file
private String m_strDelimeter; // token 2 from filter configuration file
private String m_strFilterTemplate; // token 3 from filter configuration file
private int m_nLine;
private String m_strSuffix;
private String m_strPrefix;
/**
* Constructs an LDAPFilter
object. In most situations,
* you do not need to construct an LDAPFilter object. Instead, you
* work with LDAPFilter
objects created from the
* LDAPFilter
objects and LDAPFilterDescriptor
* objects.
*
*
* This constructor uses the integer value for a search scope in
* addition to other information to construct an LDAPFilter
* object. The integer value of the search scope can be one of the
* following:
*
LDAPConnection.SCOPE_BASE
* LDAPConnection.SCOPE_ONE
* LDAPConnection.SCOPE_SUB
* illegalArgumentException
.
*/
public LDAPFilter ( String strMatchPattern,
String strDelimeter,
String strFilterTemplate,
String strDescription,
int nScope ) throws IllegalArgumentException{
m_strMatchPattern = convertMatchPattern ( strMatchPattern );
m_strDelimeter = strDelimeter;
m_strFilterTemplate = strFilterTemplate;
m_strDescription = strDescription;
m_nScope = nScope;
}
/**
* Constructs an LDAPFilter
object. In most situations,
* you do not need to construct an LDAPFilter object. Instead, you
* work with LDAPFilter
objects created from the
* LDAPFilter
objects and LDAPFilterDescriptor
* objects.
*
*
* This constructor uses the string value for a search scope in
* addition to other information to construct an LDAPFilter
* object. The string value of the search scope can be one of the
* following:
*
"base"
* "onelevel"
* "subtree"
* illegalArgumentException
.
*/
public LDAPFilter ( String strMatchPattern,
String strDelimeter,
String strFilterTemplate,
String strDescription,
String strScope )
throws IllegalArgumentException {
if ( strScope.equals ( "base" ) ) {
m_nScope = LDAPConnection.SCOPE_BASE;
} else if ( strScope.equals ( "onelevel" ) ) {
m_nScope = LDAPConnection.SCOPE_ONE;
} else if ( strScope.equals ( "subtree" ) ) {
m_nScope = LDAPConnection.SCOPE_SUB;
}
m_strMatchPattern = strMatchPattern;
m_strDelimeter = strDelimeter;
m_strFilterTemplate = strFilterTemplate;
m_strDescription = strDescription;
}
/**
* Print out a string representation of the LDAPFilter.
* Basically, it prints out the appropriate fields.
* * * For example, suppose you called the method in this way: *
* *
System.out.println(filter.toString());* * The resulting output might look like this: *
* *
* matchPtn: "@" * delim: " " * filttmpl: "(mail=%v*)" * descript: "start of email address" * scope: "LDAPConnection.SCOPE_SUB" * line: "32" * FILTER: "(mail=babs@aceindustry.com*)" **/ public String toString() { StringBuffer strBuf = new StringBuffer ( 300 ); strBuf.append ( " matchPtn: \"" + m_strMatchPattern+"\"\n" ); strBuf.append ( " delim: \"" + m_strDelimeter+"\"\n" ); strBuf.append ( " filttmpl: \"" + m_strFilterTemplate+"\"\n" ); strBuf.append ( " descript: \"" + m_strDescription+"\"\n" ); switch ( m_nScope ) { case LDAPConnection.SCOPE_BASE: strBuf.append ( " scope: \"LDAPConnection.SCOPE_BASE\"\n" ); break; case LDAPConnection.SCOPE_ONE: strBuf.append ( " scope: \"LDAPConnection.SCOPE_ONE\"\n" ); break; case LDAPConnection.SCOPE_SUB: strBuf.append ( " scope: \"LDAPConnection.SCOPE_SUB\"\n" ); break; } strBuf.append ( " line: \"" + m_nLine+"\"\n" ); strBuf.append ( " FILTER: \"" + m_strFilter+"\"\n" ); return strBuf.toString(); } /** * Sets up the filter string, given the string
strValue
.
* If the strPrefix
and strSuffix
arguments
* are non-null strings, they are prepended and appended
* to the filter string (respectively).
*
*
* This string, which is available through the getFilter()
* method, should be suitable for use as search criteria when
* calling the LDAPConnection.search()
method.
*
* * Notes: *
* *
LDAPFilterDescriptor.setFilterAffixes
* method, so you
* need to explicitly define any filter prefixes or suffixes here.* *
*
*
* @see netscape.ldap.util.LDAPFilterDescriptor#setFilterAffixes
* @see #setFilterAffixes
*/
public void setupFilter ( String strValue, String strPrefix,
String strSuffix ) {
createFilterString ( strValue, strPrefix, strSuffix );
}
/**
* Sets up the filter string, given the string strValue
.
* This string, which is available through the getFilter()
* method, should be suitable for use as search criteria when
* calling the LDAPConnection.search()
method.
*
*
* Note: If you want to specify a filter prefix and suffix,
* you need to explicitly define them by calling the
* setFilterAffixes()
method.
*
* @see netscape.ldap.util.LDAPFilterDescriptor#setFilterAffixes
* @see #setFilterAffixes
*
*/
public void setupFilter ( String strValue ) {
createFilterString ( strValue, null, null );
}
/**
* Create the filter string which can be used in
* LDAPConnection.search() and others given the parameter
* strValue. If strPrefix and strSuffix are non-null strings,
* prepend strPrefix and append strSuffix.
*/
void createFilterString ( String strValue, String strPrefix,
String strSuffix ) {
StringTokenizer strTok =
new StringTokenizer ( strValue, m_strDelimeter );
// Initialize an array of broken up values so that we
// can reference them directly.
String[] aValues = new String[strTok.countTokens()];
int nTokens = strTok.countTokens();
for ( int i = 0; i < nTokens; i++ ) {
aValues[i] = strTok.nextToken();
}
StringBuffer sbFilter = new StringBuffer ( DEFAULT_FILTER_LENGTH);
if ( strPrefix != null ) {
sbFilter.append ( strPrefix );
}
char[] cFilterTemplate = m_strFilterTemplate.toCharArray();
int i = 0;
while ( i < cFilterTemplate.length ) {
if ( cFilterTemplate[i] == '%' ) {
i++;
if ( cFilterTemplate[i] == 'v' ) {
if ( i == (cFilterTemplate.length-1) ) {
sbFilter.append ( strValue );
break;
}
i++;
switch ( cFilterTemplate[i] ) {
case '$':
sbFilter.append ( aValues[aValues.length] );
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
int nValue = Integer.parseInt
( new Character
(cFilterTemplate[i]).toString() );
nValue--;
i++;
if ( cFilterTemplate[i] == '-' ) {
i++;
if ( Character.isDigit ( cFilterTemplate[i] )) {
int nValue2 = Integer.parseInt
( new Character
(cFilterTemplate[i]).toString() );
nValue2--;
for ( int j = nValue; j <= nValue2; j++ ) {
sbFilter.append ( aValues[j] );
sbFilter.append
( ( j == nValue2 ) ? "" : " " );
}
} else {
for ( int j = nValue; j < aValues.length;j++ ) {
sbFilter.append ( aValues[j] );
sbFilter.append
( ( j == aValues.length - 1 ) ? "" : " " );
}
sbFilter.append ( cFilterTemplate[i]);
}
} else {
sbFilter.append ( aValues[nValue] );
sbFilter.append ( cFilterTemplate[i] );
}
break;
// We just got a plain old %v, so insert the
// strValue
default:
sbFilter.append ( strValue );
sbFilter.append ( cFilterTemplate[i] );
break;
}
} else {
sbFilter.append ( "%" );
sbFilter.append ( cFilterTemplate[i] );
}
} else {
sbFilter.append ( cFilterTemplate[i] );
}
i++;
}
if ( strSuffix != null ) {
sbFilter.append ( strSuffix );
}
m_strFilter = sbFilter.toString();
}
/**
* Makes a copy of this LDAPFilter
object.
*/
public Object clone() {
try {
return super.clone();
} catch ( CloneNotSupportedException e ) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
/**
* Set the line number from which this filter was created. This
* is used only when the LDAPFilter is created when an
* LDAPFilterDescriptor is initialized from a file/URL/buffer.
*/
void setLine ( int nLine ) {
m_nLine = nLine;
}
/**
* The ldapfilter.conf specifies match patterns in a funny way.
* A "." means "any character" except when used inside of a set of
* square brackets "[]", in which case, the "." means just a
* plain old period (not a * special character).
*
* This function converts periods inside of a set of square
* brackets into a "\." as per normal regexp code.
*/
String convertMatchPattern ( String strMatchPattern ) {
StringBuffer sb = new StringBuffer ( strMatchPattern.length() + 1);
char[] a_cMatchPattern = strMatchPattern.toCharArray();
boolean bInBrackets = false;
for ( int i = 0; i < a_cMatchPattern.length; i++ ) {
if ( a_cMatchPattern[i] == '.' ) {
if ( bInBrackets ) {
sb.append ( "\\" );
}
} else if ( a_cMatchPattern[i] == '[' ) {
bInBrackets = true;
} else if ( a_cMatchPattern[i] == ']' ) {
bInBrackets = false;
}
sb.append ( a_cMatchPattern[i] );
}
return sb.toString();
}
/**
* Returns the filter string. This method will return null if the
* filter string has not been calculated by the setupFilter()
,
* getFilter (strValue)
, or getFilter (strValue,
* strPrefix, strSuffix )
methods.
*
* @see #setupFilter
* @see #getFilter
*/
public String getFilter () {
return m_strFilter;
}
/**
* Create a filter string given a string value. This method uses
* any Prefixes or Suffixes that have been set by the
* setFilterAffixes() method.
* * This is the same as doing: *
* setupFilter ( strValue ); * getFilter(); **/ public String getFilter ( String strValue ) { createFilterString ( strValue, m_strPrefix, m_strSuffix ); return m_strFilter; } /** * Create a filter string given a string value. If strPrefix * and/or strSuffix is non-null, these values are prepended and * appended to the returned string.
* * This is the same as doing: *
* setupFilter ( strValue, strPrefix, strSuffix ); * getFilter(); **/ public String getFilter ( String strValue, String strPrefix, String strSuffix ) { createFilterString ( strValue, strPrefix, strSuffix ); return m_strFilter; } /** * Return this filter's match pattern. The match pattern is * found as the first token in a filter configuration line in the * ldapfilter.conf file. */ public String getMatchPattern() { return m_strMatchPattern; } /** * Return this filter's delimeter. The delmimeter is * found as the second token in a filter configuration line in the * ldapfilter.conf file. */ public String getDelimeter() { return m_strDelimeter; } /** * Return this filter's filter template. The filter template is * found as the third token in a filter configuration line in the * ldapfilter.conf file. */ public String getFilterTemplate() { return m_strFilterTemplate; } /** * Return this filter's description. The description is * found as the fourth token in a filter configuration line in the * ldapfilter.conf file. */ public String getDescription() { return m_strDescription; } /** * Return this filter's scope. The scope is * found as the fifth (optional) token in a filter configuration * line in the ldapfilter.conf file. */ public String getScope() { switch ( m_nScope ) { case LDAPConnection.SCOPE_BASE: return "base"; case LDAPConnection.SCOPE_ONE: return "onelevel"; case LDAPConnection.SCOPE_SUB: return "subtree"; default: return "UNKNOWN!"; } } /** * Return this filter's line number. The line number is * mostly a debugging variable to let the developer know which * filter from the filter configuration file is being used. */ public String getLineNumber() { return Integer.toString ( m_nLine ); } public void setFilterAffixes ( String strPrefix, String strSuffix ) { m_strPrefix = strPrefix; m_strSuffix = strSuffix; } }