Updates for LDAPJDK 4.1

This commit is contained in:
miodrag%netscape.com 2000-05-06 19:36:18 +00:00
parent 320e46ba60
commit 870ce16988
58 changed files with 2918 additions and 460 deletions

View File

@ -33,6 +33,7 @@
# classes
# LDAPCLASSES
# MAIN
# FACTORY
# CLIENT
# OPERS
# UTIL
@ -90,7 +91,8 @@ else
endif
endif
JAASLIB=$(BASEDIR)/ldapjdk/lib/jaas.jar
JAVACLASSPATH:=$(BASEDIR)/ldapjdk$(SEP)$(JAASLIB)$(SEP)$(BASEDIR)/ldapbeans$(SEP)$(JDK)/lib/classes.zip$(SEP)$(CLASSPATH)
JSSELIB=$(BASEDIR)/ldapjdk/lib/jnet.jar$(SEP)$(BASEDIR)/ldapjdk/lib/jsse.jar
JAVACLASSPATH:=$(BASEDIR)/ldapjdk$(SEP)$(JAASLIB)$(SEP)$(JSSELIB)$(SEP)$(BASEDIR)/ldapbeans$(SEP)$(JDK)/lib/classes.zip$(SEP)$(CLASSPATH)
SRCDIR=netscape/ldap
BEANDIR=$(BASEDIR)/ldapbeans/netscape/ldap/beans
@ -137,7 +139,8 @@ BERDOCCLASSES=netscape.ldap.ber.stream
SASLDOCCLASSES=com.netscape.sasl com.netscape.sasl.mechanisms
DOCCLASSES=netscape.ldap netscape.ldap.beans netscape.ldap.controls \
netscape.ldap.util $(SASLDOCCLASSES) $(TOOLSDIR)/*.java $(BERDOCCLASSES)
netscape.ldap.util netscape.ldap.factory \
$(SASLDOCCLASSES) $(TOOLSDIR)/*.java $(BERDOCCLASSES)
all: classes
@ -157,7 +160,7 @@ tests: $(CLASSDIR)
package: basepackage filterpackage beanpackage docpackage
basepackage: $(CLASSPACKAGEDIR)
cd $(DISTDIR)/classes; rm -f ../packages/$(BASEPACKAGENAME); $(JAR) cvf ../packages/$(BASEPACKAGENAME) netscape/ldap/*.class netscape/ldap/client/*.class netscape/ldap/client/opers/*.class netscape/ldap/ber/stream/*.class netscape/ldap/controls/*.class netscape/ldap/util/*.class netscape/ldap/errors/*.props com/netscape/sasl/*.class com/netscape/sasl/mechanisms/*.class *.class
cd $(DISTDIR)/classes; rm -f ../packages/$(BASEPACKAGENAME); $(JAR) cvf ../packages/$(BASEPACKAGENAME) netscape/ldap/*.class netscape/ldap/client/*.class netscape/ldap/client/opers/*.class netscape/ldap/ber/stream/*.class netscape/ldap/controls/*.class netscape/ldap/factory/*.class netscape/ldap/util/*.class netscape/ldap/errors/*.props com/netscape/sasl/*.class com/netscape/sasl/mechanisms/*.class *.class
beanpackage: $(CLASSPACKAGEDIR)
cd $(DISTDIR)/classes; rm -f ../packages/$(BEANPACKAGENAME); $(JAR) cvf ../packages/$(BEANPACKAGENAME) netscape/ldap/beans
@ -168,6 +171,9 @@ docpackage: $(DOCDIR) $(CLASSPACKAGEDIR)
MAIN: basics
cd ldapjdk/$(SRCDIR); $(JAVAC) -d "$(CLASS_DEST)" *.java
FACTORY: basics
cd ldapjdk/$(SRCDIR)/factory; $(JAVAC) -d "$(CLASS_DEST)" *.java
CLIENT: basics
cd ldapjdk/$(SRCDIR)/client; $(JAVAC) -d "$(CLASS_DEST)" *.java
@ -192,7 +198,7 @@ ERRORS: basics $(ERRORSDIR)
CONTROLS: basics
cd ldapjdk/$(SRCDIR)/controls; $(JAVAC) -d "$(CLASS_DEST)" *.java
LDAPCLASSES: BER OPERS CLIENT MAIN UTIL CONTROLS ERRORS SASL SASLMECHANISM TOOLS
LDAPCLASSES: BER OPERS CLIENT MAIN FACTORY UTIL CONTROLS ERRORS SASL SASLMECHANISM TOOLS
BEANS: OTHERBEANS

View File

@ -0,0 +1,8 @@
Jar files in this directory are used only for compilation and are
not to be distributed.
jaas.jar
required for SASL code compilation
jnet.jar and jsse.jar
required for JSSESocketFactory.java compilation

Binary file not shown.

Binary file not shown.

View File

@ -31,8 +31,9 @@ import netscape.ldap.ber.stream.*;
* @version 1.0
* @see netscape.ldap.LDAPAttributeSet
*/
public class LDAPAttribute {
public class LDAPAttribute implements java.io.Serializable {
static final long serialVersionUID = -4594745735452202600L;
private String name = null;
private byte[] nameBuf = null;
/**

View File

@ -113,6 +113,9 @@ import java.util.*;
**/
public class LDAPAttributeSchema extends LDAPSchemaElement {
static final long serialVersionUID = 2482595821879862595L;
/**
* Constructs a blank element.
*/
@ -185,7 +188,7 @@ public class LDAPAttributeSchema extends LDAPSchemaElement {
public LDAPAttributeSchema( String name, String oid, String description,
String syntaxString, boolean single,
String superior, String[] aliases ) {
super( name, oid, description );
super( name, oid, description, aliases );
attrName = "attributetypes";
syntaxElement.syntax = syntaxElement.syntaxCheck( syntaxString );
syntaxElement.syntaxString = syntaxString;
@ -196,9 +199,6 @@ public class LDAPAttributeSchema extends LDAPSchemaElement {
if ( (superior != null) && (superior.length() > 0) ) {
setQualifier( SUPERIOR, superior );
}
if ( (aliases != null) && (aliases.length > 0) ) {
this.aliases = aliases;
}
}
/**

View File

@ -32,8 +32,8 @@ import netscape.ldap.client.opers.*;
* @version 1.0
* @see netscape.ldap.LDAPAttribute
*/
public class LDAPAttributeSet implements Cloneable
{
public class LDAPAttributeSet implements Cloneable, java.io.Serializable {
static final long serialVersionUID = 5018474561697778100L;
Hashtable attrHash = null;
LDAPAttribute[] attrs = new LDAPAttribute[0];
/* If there are less attributes than this in the set, it's not worth
@ -334,6 +334,9 @@ public class LDAPAttributeSet implements Cloneable
vals[j++] = attrs[i];
}
}
if (attrHash != null) {
attrHash.remove(attrs[index].getName().toLowerCase());
}
attrs = vals;
}
}

View File

@ -86,8 +86,16 @@ import java.util.zip.CRC32;
* All clones of an <CODE>LDAPConnection</CODE> object share
* the same <CODE>LDAPCache</CODE> object.
* <P>
*
* Note that <CODE>LDAPCache</CODE> does not maintain consistency
* with the directory, so that cached search results may no longer be
* valid after a directory update. If the same application is performing
* both cached searches and directory updates, then the
* application should flush the corresponding cache entries after an update.
* To do this use the <CODE>flushEntries</CODE> method.
* <P>
*
* Note that search requests that return referrals are not cached.
* Also, note that search requests that return referrals are not cached.
* <P>
*
* The <CODE>LDAPCache</CODE> class includes methods for
@ -98,13 +106,18 @@ import java.util.zip.CRC32;
* @see netscape.ldap.LDAPConnection#setCache(netscape.ldap.LDAPCache)
* @see netscape.ldap.LDAPConnection#getCache
*/
public class LDAPCache {
public class LDAPCache implements Serializable {
static final long serialVersionUID = 6275167993337814294L;
private Hashtable m_cache;
private long m_timeToLive;
private long m_maxSize;
private String[] m_dns;
private Vector m_orderedStruct;
private long m_remainingSize = 0;
// Count of LDAPConnections that share this cache
private int m_refCnt = 0;
/**
* Delimiter used internally when creating keys
* for the cache.
@ -605,13 +618,51 @@ public class LDAPCache {
return m_cache.size();
}
/**
* Get number of LDAPConnections that share this cache
* @return Reference Count
*/
int getRefCount() {
return m_refCnt;
}
/**
* Add a new reference to this cache.
*
*/
synchronized void addReference() {
m_refCnt++;
if (m_debug) {
System.err.println("Cache refCnt="+ m_refCnt);
}
}
/**
* Remove a reference to this cache.
* If the reference count is 0, cleaup the cache.
*
*/
synchronized void removeReference() {
if (m_refCnt > 0) {
m_refCnt--;
if (m_debug) {
System.err.println("Cache refCnt="+ m_refCnt);
}
if (m_refCnt == 0 ) {
cleanup();
}
}
}
/**
* Cleans up
*/
void cleanup() {
synchronized void cleanup() {
flushEntries(null, 0);
m_timer.stop();
m_timer = null;
if (m_timer != null) {
m_timer.stop();
m_timer = null;
}
}
/**
@ -761,4 +812,4 @@ class TTLTimer implements Runnable{
m_cache.scheduleTTLTimer();
}
}
}

View File

@ -23,7 +23,6 @@ package netscape.ldap;
import java.util.*;
import java.text.*;
import netscape.ldap.client.*;
/**
* Compares LDAP entries based on one or more attribute values.
@ -39,12 +38,15 @@ import netscape.ldap.client.*;
* @see LDAPSearchResults#sort
*/
public class LDAPCompareAttrNames implements LDAPEntryComparator {
public class LDAPCompareAttrNames
implements LDAPEntryComparator, java.io.Serializable {
String m_attrs[];
boolean m_ascending[];
Locale m_locale = null;
Collator m_collator = null;
static final long serialVersionUID = -2567450425231175944L;
private String m_attrs[];
private boolean m_ascending[];
private Locale m_locale = null;
private Collator m_collator = null;
private boolean m_sensitive = true;
/**
* Constructs a comparator that compares the string values of
@ -168,19 +170,64 @@ public class LDAPCompareAttrNames implements LDAPEntryComparator {
/**
* Set the locale, if any, used for collation. If the locale is null,
* an ordinary string comparison is used for sorting.
* an ordinary string comparison is used for sorting. If sorting
* has been set to case-insensitive, the collation strength is set
* to Collator.PRIMARY, otherwise to Collator.IDENTICAL. If a
* different collation strength setting is required, use the signature
* that takes a collation strength parameter.
*
* @param locale the locale used for collation, or null.
*/
public void setLocale( Locale locale ) {
if ( m_sensitive ) {
setLocale( locale, Collator.IDENTICAL );
} else {
setLocale( locale, Collator.PRIMARY );
}
}
/**
* Sets the locale, if any, used for collation. If the locale is null,
* an ordinary string comparison is used for sorting.
*
* @param locale the locale used for collation, or null.
* @param strength collation strength: Collator.PRIMARY,
* Collator.SECONDARY, Collator.TERTIARY, or Collator.IDENTICAL
*/
public void setLocale( Locale locale, int strength ) {
m_locale = locale;
if ( m_locale == null ) {
m_collator = null;
} else {
m_collator = Collator.getInstance( m_locale );
m_collator.setStrength(strength);
}
}
/**
* Gets the state of the case-sensitivity flag. This only applies to
* Unicode sort order; for locale-specific sorting, case-sensitivity
* is controlled by the collation strength.
*
* @return <code>true</code> for case-sensitive sorting; this is
* the default
*/
public boolean getCaseSensitive() {
return m_sensitive;
}
/**
* Sets the state of the case-sensitivity flag. This only applies to
* Unicode sort order; for locale-specific sorting, case-sensitivity
* is controlled by the collation strength.
*
* @param sensitive <code>true</code> for case-sensitive sorting;
* this is the default
*/
public void setCaseSensitive( boolean sensitive ) {
m_sensitive = sensitive;
}
/**
* Returns <CODE>true</CODE> if the value of the attribute in the first entry is greater
* than the value of the attribute in the second entry.
@ -258,24 +305,41 @@ public class LDAPCompareAttrNames implements LDAPEntryComparator {
if ((lessValue == null) ^ (greaterValue == null))
return greaterValue != null;
if (lessValue == null ||
lessValue.equalsIgnoreCase (greaterValue))
if (attrPos == m_attrs.length - 1)
return false;
else
return attrGreater (greater, less, attrPos+1);
// Check for equality
if ( (lessValue == null) ||
((m_collator != null) &&
(m_collator.compare( greaterValue, lessValue ) == 0) ) ||
((m_collator == null) && m_sensitive &&
lessValue.equals(greaterValue)) ||
((m_collator == null) && !m_sensitive &&
lessValue.equalsIgnoreCase(greaterValue)) ) {
if ( m_collator != null ) {
if ( ascending )
if (attrPos == m_attrs.length - 1) {
return false;
} else {
return attrGreater (greater, less, attrPos+1);
}
}
// Not equal, check for order
if ( ascending ) {
if ( m_collator != null ) {
return ( m_collator.compare( greaterValue, lessValue ) > 0 );
else
return ( m_collator.compare( greaterValue, lessValue ) < 0 );
} else {
if ( ascending )
} else if ( m_sensitive ) {
return (greaterValue.compareTo (lessValue) > 0);
else
} else {
return (greaterValue.toLowerCase().compareTo (
lessValue.toLowerCase()) > 0);
}
} else {
if ( m_collator != null ) {
return ( m_collator.compare( greaterValue, lessValue ) < 0 );
} else if ( m_sensitive ) {
return (greaterValue.compareTo (lessValue) < 0);
} else {
return (greaterValue.toLowerCase().compareTo (
lessValue.toLowerCase()) < 0);
}
}
}
}

View File

@ -31,14 +31,19 @@ import java.net.*;
* in parallel by creating a separate thread after the specified delay.
* Connection setup status is preserved for later attempts, so that servers
* that are more likely to be available will be tried first.
* <P>
* The total time spent opening a connection can be limited with the
* <CODE>ConnectTimeout</CODE> property.
* <P>
* When a connection is successfully created, a socket is opened. The socket
* is passed to the LDAPConnThread. The LDAPConnThread must call
* invalidateConnection() if the connection is lost due to a network or
* server error, or disconnect() if the connection is deliberately terminated
* by the user.
*/
class LDAPConnSetupMgr implements Cloneable{
class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
static final long serialVersionUID = 1519402748245755306L;
/**
* Policy for opening a connection when multiple servers are used
*/
@ -53,7 +58,8 @@ class LDAPConnSetupMgr implements Cloneable{
private static final int CONNECTED = 0;
private static final int DISCONNECTED = 1;
private static final int NEVER_USED = 2;
private static final int FAILED = 3;
private static final int INTERRUPTED = 3;
private static final int FAILED = 4;
/**
* Representation for a server in the server list.
@ -104,65 +110,135 @@ class LDAPConnSetupMgr implements Cloneable{
/**
* Connection setup policy (PARALLEL or SERIAL)
*/
int m_policy;
int m_policy = SERIAL;
/**
* Delay in ms before another connection setup thread is started.
*/
int m_connSetupDelay;
int m_connSetupDelay = -1;
/**
* The maximum time to wait to established the connection
*/
int m_connectTimeout = 0;
/**
* During connection setup, the current count of servers to which
* connection attmpt has been made
*/
private transient int m_attemptCnt = 0;
/**
* Constructor
* @param host list of host names to which to connect
* @param port list of port numbers corresponding to the host list
* @param factory socket factory for SSL connections
* @param delay delay in seconds for the parallel connection setup policy.
* Possible values are: <br>(delay=-1) use serial policy,<br>
* (delay=0) start immediately concurrent threads to each specified server
* <br>(delay>0) create a new connection setup thread after delay seconds
* @param factory socket factory for SSL connections
*/
LDAPConnSetupMgr(String[] hosts, int[] ports, LDAPSocketFactory factory, int delay) {
LDAPConnSetupMgr(String[] hosts, int[] ports, LDAPSocketFactory factory) {
m_dsList = new ServerEntry[hosts.length];
for (int i=0; i < hosts.length; i++) {
m_dsList[i] = new ServerEntry(hosts[i], ports[i], NEVER_USED);
}
m_factory = factory;
m_policy = (delay < 0) ? SERIAL : PARALLEL;
m_connSetupDelay = delay*1000;
}
/**
* Constructor used by clone()
*/
private LDAPConnSetupMgr() {}
/**
* Try to open the connection to any of the servers in the list.
* Try to open the connection to any of the servers in the list, limiting
* the time waiting for the connection to be established
* @return connection socket
*/
Socket openConnection() throws LDAPException{
m_socket = null;
m_connException = null;
synchronized Socket openConnection() throws LDAPException{
long tcur=0, tmax = Long.MAX_VALUE;
Thread th = null;
reset();
// If reconnecting, sort dsList so that servers more likly to
// be available are tried first
sortDsList();
if (m_connectTimeout == 0) {
// No need for a separate thread, connect time not limited
connect();
}
else {
// Wait for connection at most m_connectTimeout milliseconds
// Run connection setup in a separate thread to monitor the time
tmax = System.currentTimeMillis() + m_connectTimeout;
th = new Thread (new Runnable() {
public void run() {
connect();
}
}, "ConnSetupMgr");
th.setDaemon(true);
th.start();
while (m_socket==null && (m_attemptCnt < m_dsList.length) &&
(tcur = System.currentTimeMillis()) < tmax) {
try {
wait(tmax - tcur);
}
catch (InterruptedException e) {
th.interrupt();
cleanup();
throw new LDAPInterruptedException("Interrupted connect operation");
}
}
}
if (m_socket != null) {
return m_socket;
}
if ( th != null && (tcur = System.currentTimeMillis()) >= tmax) {
// We have timed out
th.interrupt();
cleanup();
throw new LDAPException(
"connect timeout, " + getServerList() + " might be unreachable",
LDAPException.CONNECT_ERROR);
}
if (m_connException != null && m_dsList.length == 1) {
throw m_connException;
}
throw new LDAPException(
"failed to connect to server " + getServerList(),
LDAPException.CONNECT_ERROR);
}
private void reset() {
m_socket = null;
m_connException = null;
m_attemptCnt = 0;
for (int i=0; i < m_dsList.length; i++) {
m_dsList[i].connSetupThread = null;
}
}
private String getServerList() {
StringBuffer sb = new StringBuffer();
for (int i=0; i < m_dsList.length; i++) {
sb.append(i==0 ? "" : " ");
sb.append(m_dsList[i].host);
sb.append(":");
sb.append(m_dsList[i].port);
}
return sb.toString();
}
private void connect() {
if (m_policy == SERIAL || m_dsList.length == 1) {
openSerial();
}
else {
openParallel();
}
if (m_socket != null) {
return m_socket;
}
if (m_connException != null) {
throw m_connException;
}
return null;
}
}
/**
@ -170,7 +246,7 @@ class LDAPConnSetupMgr implements Cloneable{
* Put the connected server at the end of the server list for
* the next connect attempt.
*/
void invalidateConnection() {
synchronized void invalidateConnection() {
if (m_socket != null) {
m_dsList[m_dsIdx].connSetupStatus = FAILED;
@ -221,6 +297,35 @@ class LDAPConnSetupMgr implements Cloneable{
return m_dsList[0].port;
}
int getConnSetupDelay() {
return m_connSetupDelay/1000;
}
/**
* Selects the connection failover policy
* @param delay in seconds for the parallel connection setup policy.
* Possible values are: <br>(delay=-1) use serial policy,<br>
* (delay=0) start immediately concurrent threads to each specified server
* <br>(delay>0) create a new connection setup thread after delay seconds
*/
void setConnSetupDelay(int delay) {
m_policy = (delay < 0) ? SERIAL : PARALLEL;
m_connSetupDelay = delay*1000;
}
int getConnectTimeout() {
return m_connectTimeout/1000;
}
/**
* Sets the maximum time to spend in the openConnection() call
* @param timeout in seconds to wait for the connection to be established
*/
void setConnectTimeout(int timeout) {
m_connectTimeout = timeout*1000;
}
/**
* Check if the user has voluntarily closed the connection
*/
@ -268,24 +373,16 @@ class LDAPConnSetupMgr implements Cloneable{
try {
wait(m_connSetupDelay);
}
catch (InterruptedException e) {}
catch (InterruptedException e) {
return;
}
}
}
// At this point all threads are started. Wait until first thread
// succeeds to connect or all threads terminate
while (m_socket == null) {
// Check whether there are still running threads
boolean threadsRunning = false;
for (int i=0; i < m_dsList.length; i++) {
if (m_dsList[i].connSetupThread != null) {
threadsRunning = true;
break;
}
}
if (!threadsRunning) { return; }
while (m_socket == null && (m_attemptCnt < m_dsList.length)) {
// Wait for a thread to terminate
try {
@ -339,6 +436,7 @@ class LDAPConnSetupMgr implements Cloneable{
entry.connSetupStatus = FAILED;
m_connException = conex;
}
m_attemptCnt++;
notifyAll();
}
}
@ -353,7 +451,7 @@ class LDAPConnSetupMgr implements Cloneable{
ServerEntry entry = m_dsList[i];
if (entry.connSetupThread != null && entry.connSetupThread != currThread) {
entry.connSetupStatus = FAILED;
entry.connSetupStatus = INTERRUPTED;
//Thread.stop() is considered to be dangerous, use Thread.interrupt().
//interrupt() will however not work if the thread is blocked in the
//socket library native connect() call, but the connect() will
@ -371,7 +469,8 @@ class LDAPConnSetupMgr implements Cloneable{
* are tried first. The likelihood of making a successful connection
* is determined by the connSetupStatus. Lower values have higher
* likelihood. Thus, the order of server access is (1) disconnected by
* the user (2) never used (3) connection setup failed/connection lost
* the user (2) never used (3) interrupted connection attempt
* (4) connection setup failed/connection lost
*/
private void sortDsList() {
int srvCnt = m_dsList.length;
@ -411,17 +510,17 @@ class LDAPConnSetupMgr implements Cloneable{
}
public Object clone() {
LDAPConnSetupMgr cloneMgr = new LDAPConnSetupMgr();
cloneMgr.m_factory = m_factory;
cloneMgr.m_policy = m_policy;
cloneMgr.m_connSetupDelay = m_connSetupDelay;
cloneMgr.m_dsIdx = m_dsIdx;
cloneMgr.m_dsList = new ServerEntry[m_dsList.length];
cloneMgr.m_socket = m_socket;
for (int i=0; i<m_dsList.length; i++) {
ServerEntry e = m_dsList[i];
cloneMgr.m_dsList[i] = new ServerEntry(e.host, e.port, e.connSetupStatus);
try {
LDAPConnSetupMgr cloneMgr = (LDAPConnSetupMgr) super.clone();
cloneMgr.m_dsList = new ServerEntry[m_dsList.length];
for (int i=0; i<m_dsList.length; i++) {
ServerEntry e = m_dsList[i];
cloneMgr.m_dsList[i] = new ServerEntry(e.host, e.port, e.connSetupStatus);
}
return cloneMgr;
}
catch (CloneNotSupportedException ex) {
return null;
}
return cloneMgr;
}
}

View File

@ -71,7 +71,7 @@ class LDAPConnThread extends Thread {
transient private Thread m_thread = null;
transient Object m_sendRequestLock = new Object();
transient LDAPConnSetupMgr m_connMgr = null;
transient PrintWriter m_traceOutput = null;
transient Object m_traceOutput = null;
/**
* Constructs a connection thread that maintains connection to the
@ -80,7 +80,7 @@ class LDAPConnThread extends Thread {
* @param port LDAP port number
* @param factory LDAP socket factory
*/
public LDAPConnThread(LDAPConnSetupMgr connMgr, LDAPCache cache, OutputStream traceOutput)
public LDAPConnThread(LDAPConnSetupMgr connMgr, LDAPCache cache, Object traceOutput)
throws LDAPException {
super("LDAPConnThread " + connMgr.getHost() +":"+ connMgr.getPort());
m_requests = new Hashtable ();
@ -88,7 +88,7 @@ class LDAPConnThread extends Thread {
m_connMgr = connMgr;
m_socket = connMgr.getSocket();
setCache( cache );
setTraceOutputStream(traceOutput);
setTraceOutput(traceOutput);
setDaemon(true);
@ -128,12 +128,33 @@ class LDAPConnThread extends Thread {
m_serverOutput = os;
}
void setTraceOutputStream(OutputStream os) {
void setTraceOutput(Object traceOutput) {
synchronized (m_sendRequestLock) {
m_traceOutput = (os == null) ? null : new PrintWriter(os);
if (traceOutput == null) {
m_traceOutput = null;
}
else if (traceOutput instanceof OutputStream) {
m_traceOutput = new PrintWriter((OutputStream)traceOutput);
}
else if (traceOutput instanceof LDAPTraceWriter) {
m_traceOutput = traceOutput;
}
}
}
void logLDAPMessage(LDAPMessage msg) {
synchronized( m_sendRequestLock ) {
if (m_traceOutput instanceof PrintWriter) {
PrintWriter traceOutput = (PrintWriter)m_traceOutput;
traceOutput.println(msg.toTraceString());
traceOutput.flush();
}
else if (m_traceOutput instanceof LDAPTraceWriter) {
((LDAPTraceWriter)m_traceOutput).write(msg.toTraceString());
}
}
}
/**
* Set the cache to use for searches.
@ -187,8 +208,7 @@ class LDAPConnThread extends Thread {
synchronized( m_sendRequestLock ) {
try {
if (m_traceOutput != null) {
m_traceOutput.println(msg.toTraceString());
m_traceOutput.flush();
logLDAPMessage(msg);
}
msg.write (m_serverOutput);
m_serverOutput.flush ();
@ -317,6 +337,7 @@ class LDAPConnThread extends Thread {
m_registered = null;
m_messages = null;
m_requests.clear();
m_cache = null;
}
}
@ -402,10 +423,7 @@ class LDAPConnThread extends Thread {
msg = LDAPMessage.parseMessage(element);
if (m_traceOutput != null) {
synchronized( m_sendRequestLock ) {
m_traceOutput.println(msg.toTraceString());
m_traceOutput.flush();
}
logLDAPMessage(msg);
}
// passed in the ber element size to approximate the size of the cache

View File

@ -28,7 +28,6 @@ import netscape.ldap.ber.stream.*;
import netscape.ldap.util.*;
import java.io.*;
import java.net.*;
//import javax.security.auth.callback.CallbackHandler;
/**
* Represents a connection to an LDAP server. <P>
@ -93,7 +92,9 @@ import java.net.*;
* @see netscape.ldap.LDAPException
*/
public class LDAPConnection
implements LDAPv3, LDAPAsynchronousConnection, Cloneable {
implements LDAPv3, LDAPAsynchronousConnection, Cloneable, Serializable {
static final long serialVersionUID = -8698420087475771144L;
/**
* Version of the LDAP protocol used by default.
@ -170,7 +171,7 @@ public class LDAPConnection
* Name of the property to enable/disable LDAP message trace. <P>
*
* The property can be specified either as a system property
* (java -D command line option), or programmatically with
* (java -D command line option), or programmatically with the
* <CODE>setProperty</CODE> method.
* <P>
* When -D command line option is used, defining the property with
@ -179,10 +180,10 @@ public class LDAPConnection
* If the file name is prefixed with a '+' character, the file is
* opened in append mode.
* <P>
* When the property is set with <CODE>getProperty</CODE> method,
* When the property is set with the <CODE>getProperty</CODE> method,
* the property value must be either a String (represents a file name)
* or an OutputStream. To stop tracing, <CODE>null</CODE> should be
* passed as the property value.
* an OutputStream or an instance of LDAPTraceWriter. To stop tracing,
* <CODE>null</CODE> should be passed as the property value.
*
* @see netscape.ldap.LDAPConnection#setProperty(java.lang.String, java.lang.Object)
*/
@ -230,9 +231,10 @@ public class LDAPConnection
private int m_protocolVersion = LDAP_VERSION;
private LDAPConnSetupMgr m_connMgr;
private int m_connSetupDelay = -1;
private int m_connectTimeout = 0;
private LDAPSocketFactory m_factory;
/* m_thread does all socket i/o for the object and any clones */
private LDAPConnThread m_thread = null;
private transient LDAPConnThread m_thread = null;
/* To manage received server controls on a per-thread basis,
we keep a table of active threads and a table of controls,
indexed by thread */
@ -258,11 +260,11 @@ public class LDAPConnection
/**
* Properties
*/
private final static Float SdkVersion = new Float(4.07f);
private final static Float SdkVersion = new Float(4.1f);
private final static Float ProtocolVersion = new Float(3.0f);
private final static String SecurityVersion = new String("none,simple,sasl");
private final static Float MajorVersion = new Float(4.0f);
private final static Float MinorVersion = new Float(0.07f);
private final static Float MinorVersion = new Float(0.1f);
private final static String DELIM = "#";
private final static String PersistSearchPackageName =
"netscape.ldap.controls.LDAPPersistSearchControl";
@ -347,6 +349,12 @@ public class LDAPConnection
* @see netscape.ldap.LDAPConnection#getCache
*/
public void setCache(LDAPCache cache) {
if (m_cache != null) {
m_cache.removeReference();
}
if (cache != null) {
cache.addReference();
}
m_cache = cache;
if ( m_thread != null ) {
m_thread.setCache( cache );
@ -441,19 +449,19 @@ public class LDAPConnection
} else if ( name.equalsIgnoreCase( TRACE_PROPERTY ) ) {
OutputStream os = null;
Object traceOutput = null;
if (val == null) {
m_properties.remove(TRACE_PROPERTY);
}
else {
if (m_thread != null) {
os = createTraceOutputStream(val);
traceOutput = createTraceOutput(val);
}
m_properties.put( TRACE_PROPERTY, val );
}
if (m_thread != null) {
m_thread.setTraceOutputStream(os);
m_thread.setTraceOutput(traceOutput);
}
// This is used only by the ldapjdk test cases to simulate a
@ -467,17 +475,20 @@ public class LDAPConnection
}
/**
* Create output stream from the TRACE_PROPERTY value.
* The value can be either of type String or OutputStream. The
* String value represents output file name. If the name is an empty
* Evaluate the TRACE_PROPERTY value and create output stream.
* The value can be of type String, OutputStream or LDAPTraceWriter.
* The String value represents output file name. If the name is an empty
* string, the output is sent to System.err. If the file name is
* prefixed with a '+' character, the file is opened in append mode.
* @param out Trace output specifier
*
* @param out Trace output specifier. A file name, an output stream
* or an instance of LDAPTraceWriter
* @return An output stream or an LDAPTraceWriter instance
*/
OutputStream createTraceOutputStream(Object out) throws LDAPException {
OutputStream os = null;
Object createTraceOutput(Object out) throws LDAPException {
if (out instanceof String) { // trace file name
OutputStream os = null;
String file = (String)out;
if (file.length() == 0) {
os = System.err;
@ -496,15 +507,18 @@ public class LDAPConnection
"Can not open output trace file " + file + " " + e);
}
}
return os;
}
else if (out instanceof OutputStream) {
os = (OutputStream) out;
return out;
}
else if (out instanceof LDAPTraceWriter) {
return out;
}
else {
throw new LDAPException(TRACE_PROPERTY + " must be OutputStream or String" );
throw new LDAPException(TRACE_PROPERTY + " must be an OutputStream, a file name or an instance of LDAPTraceWriter" );
}
return os;
}
/**
@ -557,6 +571,30 @@ public class LDAPConnection
return m_boundPasswd;
}
/**
* Returns the maximum time to wait for the connection to be established.
* @return the maximum connect time in seconds or 0 (unlimited)
* @see netscape.ldap.LDAPConnection#setConnectTimeout
*/
public int getConnectTimeout () {
return m_connectTimeout;
}
/**
* Specifies the maximum time to wait for the connection to be established.
* If the value is 0, the time is not limited.
* @param timeout the maximum connect time in seconds or 0 (unlimited)
*/
public void setConnectTimeout (int timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("Timeout value can not be negative");
}
m_connectTimeout = timeout;
if (m_connMgr != null) {
m_connMgr.setConnectTimeout(m_connectTimeout);
}
}
/**
* Returns the delay in seconds when making concurrent connection attempts to
* multiple servers.
@ -577,9 +615,9 @@ public class LDAPConnection
* Specifies the delay in seconds when making concurrent connection attempts to
* multiple servers.
* <P>Effectively, selects the connection setup policy when a list of hosts is passed
* to the <CODE>connect</CODE>method.
* to the <CODE>connect</CODE> method.
*
* <br>If the serial policy, the default one, is selected, an attempt is made to
* <br>If the serial policy is selected, the default one, an attempt is made to
* connect to the first host in the list. The next entry in
* the list is tried only if the attempt to connect to the current host fails.
* This might cause your application to block for unacceptably long time if a host is down.
@ -602,6 +640,9 @@ public class LDAPConnection
*/
public void setConnSetupDelay (int delay) {
m_connSetupDelay = delay;
if (m_connMgr != null) {
m_connMgr.setConnSetupDelay(delay);
}
}
/**
@ -689,24 +730,30 @@ public class LDAPConnection
* }
* System.out.println( "Connected to " + ldapHost + " at port " + ldapPort )
* </PRE>
*
*<P>
* You can limit the time spent waiting for the connection to be established
* by calling <CODE>setConnectTimeout</CODE> before <CODE>connect</CODE>.
* <P>
* @param host host name of the LDAP server to which you want to connect.
* This value can also be a space-delimited list of hostnames or
* hostnames and port numbers (using the syntax
* <I>hostname:portnumber</I>). The connection setup policy specified with
* the <CODE>ConnSetupDelay</CODE> property controls whether connection
* attempts are made serially or concurrently. For example, you can specify
* <I>hostname:portnumber</I>). For example, you can specify
* the following values for the <CODE>host</CODE> argument:<BR>
*<PRE>
* myhost
* myhost hishost:389 herhost:5000 whathost
* myhost:686 myhost:389 hishost:5000 whathost:1024
*</PRE>
* If multiple servers are specified in the <CODE>host</CODE> list, the connection
* setup policy specified with the <CODE>ConnSetupDelay</CODE> property controls
* whether connection attempts are made serially or concurrently.
* <P>
* @param port port number of the LDAP server to which you want to connect.
* This parameter is ignored for any host in the <CODE>host</CODE>
* parameter which includes a colon and port number.
* @exception LDAPException The connection failed.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay
* @see netscape.ldap.LDAPConnection#setConnectTimeout
*/
public void connect(String host, int port) throws LDAPException {
connect( host, port, null, null, m_defaultConstraints, false );
@ -749,19 +796,24 @@ public class LDAPConnection
* }
* System.out.println( "Connected to " + ldapHost + " at port " + ldapPort );
* </PRE>
*
*<P>
* You can limit the time spent waiting for the connection to be established
* by calling <CODE>setConnectTimeout</CODE> before <CODE>connect</CODE>.
* <P>
* @param host host name of the LDAP server to which you want to connect.
* This value can also be a space-delimited list of hostnames or
* hostnames and port numbers (using the syntax
* <I>hostname:portnumber</I>). The connection setup policy specified with
* the <CODE>ConnSetupDelay</CODE> property controls whether connection
* attempts are made serially or concurrently. For example, you can specify
* <I>hostname:portnumber</I>). For example, you can specify
* the following values for the <CODE>host</CODE> argument:<BR>
*<PRE>
* myhost
* myhost hishost:389 herhost:5000 whathost
* myhost:686 myhost:389 hishost:5000 whathost:1024
*</PRE>
* If multiple servers are specified in the <CODE>host</CODE> list, the connection
* setup policy specified with the <CODE>ConnSetupDelay</CODE> property controls
* whether connection attempts are made serially or concurrently.
* <P>
* @param port port number of the LDAP server to which you want to connect.
* This parameter is ignored for any host in the <CODE>host</CODE>
* parameter which includes a colon and port number.
@ -769,6 +821,7 @@ public class LDAPConnection
* @param passwd password used for authentication
* @exception LDAPException The connection or authentication failed.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay
* @see netscape.ldap.LDAPConnection#setConnectTimeout
*/
public void connect(String host, int port, String dn, String passwd)
throws LDAPException {
@ -781,19 +834,24 @@ public class LDAPConnection
* represents an open connection, the connection is closed first
* before the new connection is opened. This method allows the user to
* specify the preferences for the bind operation.
*
*<P>
* You can limit the time spent waiting for the connection to be established
* by calling <CODE>setConnectTimeout</CODE> before <CODE>connect</CODE>.
* <P>
* @param host host name of the LDAP server to which you want to connect.
* This value can also be a space-delimited list of hostnames or
* hostnames and port numbers (using the syntax
* <I>hostname:portnumber</I>). The connection setup policy specified with
* the <CODE>ConnSetupDelay</CODE> property controls whether connection
* attempts are made serially or concurrently. For example, you can specify
* <I>hostname:portnumber</I>). For example, you can specify
* the following values for the <CODE>host</CODE> argument:<BR>
*<PRE>
* myhost
* myhost hishost:389 herhost:5000 whathost
* myhost:686 myhost:389 hishost:5000 whathost:1024
*</PRE>
* If multiple servers are specified in the <CODE>host</CODE> list, the connection
* setup policy specified with the <CODE>ConnSetupDelay</CODE> property controls
* whether connection attempts are made serially or concurrently.
* <P>
* @param port port number of the LDAP server to which you want to connect.
* This parameter is ignored for any host in the <CODE>host</CODE>
* parameter which includes a colon and port number.
@ -802,6 +860,7 @@ public class LDAPConnection
* @param cons preferences for the bind operation
* @exception LDAPException The connection or authentication failed.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay
* @see netscape.ldap.LDAPConnection#setConnectTimeout
*/
public void connect(String host, int port, String dn, String passwd,
LDAPConstraints cons) throws LDAPException {
@ -849,8 +908,9 @@ public class LDAPConnection
}
/* Create the Connection Setup Manager */
m_connMgr = new LDAPConnSetupMgr(hostList, portList, m_factory,
m_connSetupDelay);
m_connMgr = new LDAPConnSetupMgr(hostList, portList, m_factory);
m_connMgr.setConnSetupDelay(m_connSetupDelay);
m_connMgr.setConnectTimeout(m_connectTimeout);
connect();
@ -970,20 +1030,20 @@ public class LDAPConnection
LDAPException.PARAM_ERROR );
}
m_connMgr.openConnection();
m_connMgr.openConnection();
m_thread = getNewThread(m_connMgr, m_cache);
authenticateSSLConnection();
}
/**
* Returns the trace output stream if set by the user
* Returns the trace output object if set by the user
*/
OutputStream getTraceOutputStream() throws LDAPException {
Object getTraceOutput() throws LDAPException {
// Check first if trace output has been set using setProperty()
Object traceOut = m_properties.get(TRACE_PROPERTY);
if (traceOut != null) {
return createTraceOutputStream(traceOut);
return createTraceOutput(traceOut);
}
// Check if the property has been set with java -Dcom.netscape.ldap.trace
@ -992,7 +1052,7 @@ public class LDAPConnection
try {
traceOut = System.getProperty(TRACE_PROPERTY);
if (traceOut != null) {
return createTraceOutputStream(traceOut);
return createTraceOutput(traceOut);
}
}
catch (Exception e) {
@ -1033,7 +1093,7 @@ public class LDAPConnection
// to the new thread
try {
newThread = new LDAPConnThread(connMgr, cache,
getTraceOutputStream());
getTraceOutput());
v = (Vector)m_threadConnTable.remove(connThread);
break;
} catch (Exception e) {
@ -1055,7 +1115,7 @@ public class LDAPConnection
if (!connExists) {
try {
newThread = new LDAPConnThread(connMgr, cache,
getTraceOutputStream());
getTraceOutput());
v = new Vector();
v.addElement(this);
} catch (Exception e) {
@ -1296,7 +1356,7 @@ public class LDAPConnection
* obtain additional required information
* @exception LDAPException Failed to authenticate to the LDAP server.
* @see netscape.ldap.LDAPConnection#authenticate(java.lang.String,
* java.util.Hashtable, javax.security.auth.callback.CallbackHandler)
* java.util.Hashtable, java.lang.Object)
*/
public void authenticate(String dn, String[] mechanisms,
Hashtable props, /*CallbackHandler*/ Object cbh)
@ -1613,7 +1673,7 @@ public class LDAPConnection
* obtain additional required information
* @exception LDAPException Failed to authenticate to the LDAP server.
* @see netscape.ldap.LDAPConnection#bind(java.lang.String,
* java.util.Hashtable, javax.security.auth.callback.CallbackHandler)
* java.util.Hashtable, java.lang.Object)
*/
public void bind(String dn, String[] mechanisms,
Hashtable props, /*CallbackHandler*/ Object cbh)
@ -1709,14 +1769,16 @@ public class LDAPConnection
* Mark this connection as bound in the thread connection table
*/
void markConnAsBound() {
if (m_threadConnTable.containsKey(m_thread)) {
Vector v = (Vector)m_threadConnTable.get(m_thread);
for (int i=0, n=v.size(); i<n; i++) {
LDAPConnection conn = (LDAPConnection)v.elementAt(i);
conn.m_bound = true;
synchronized (m_threadConnTable) {
if (m_threadConnTable.containsKey(m_thread)) {
Vector v = (Vector)m_threadConnTable.get(m_thread);
for (int i=0, n=v.size(); i<n; i++) {
LDAPConnection conn = (LDAPConnection)v.elementAt(i);
conn.m_bound = true;
}
} else {
printDebug("Thread table does not contain the thread of this object");
}
} else {
printDebug("Thread table does not contain the thread of this object");
}
}
@ -1731,18 +1793,26 @@ public class LDAPConnection
// Before sendRequest gets invoked, it is possible that the LDAPConnThread
// encountered a network error and called deregisterConnection which
// set the thread reference to null.
for (int i=0; i<3; i++) {
boolean requestSent=false;
for (int i=0; !requestSent && i<3; i++) {
try {
m_thread.sendRequest(this, oper, myListener, cons);
break;
requestSent=true;
} catch(NullPointerException ne) {
// do nothing
}catch (IllegalArgumentException e) {
throw new LDAPException(e.getMessage(), LDAPException.PARAM_ERROR);
}
}
if (!isConnected()) {
throw new LDAPException("The connection is not available",
LDAPException.OTHER);
}
if (!requestSent) {
throw new LDAPException("Failed to send request",
LDAPException.OTHER);
}
}
/**
@ -1829,7 +1899,7 @@ public class LDAPConnection
}
if (m_cache != null) {
m_cache.cleanup();
m_cache.removeReference();
m_cache = null;
}
deleteThreadConnEntry();
@ -1840,17 +1910,19 @@ public class LDAPConnection
* Remove this connection from the thread connection table
*/
private void deleteThreadConnEntry() {
Enumeration keys = m_threadConnTable.keys();
while (keys.hasMoreElements()) {
LDAPConnThread connThread = (LDAPConnThread)keys.nextElement();
Vector connVector = (Vector)m_threadConnTable.get(connThread);
synchronized (m_threadConnTable) {
Vector connVector = (Vector)m_threadConnTable.get(m_thread);
if (connVector == null) {
printDebug("Thread table does not contain the thread of this object");
return;
}
Enumeration enumv = connVector.elements();
while (enumv.hasMoreElements()) {
LDAPConnection c = (LDAPConnection)enumv.nextElement();
if (c.equals(this)) {
connVector.removeElement(c);
if (connVector.size() == 0) {
m_threadConnTable.remove(connThread);
m_threadConnTable.remove(m_thread);
}
return;
}
@ -2028,8 +2100,10 @@ public class LDAPConnection
public LDAPEntry read (String DN, String attrs[],
LDAPSearchConstraints cons) throws LDAPException {
LDAPSearchResults results = search (DN, SCOPE_BASE,
defaultFilter, attrs, false, cons);
LDAPSearchResults results =
search (DN, SCOPE_BASE,
"(|(objectclass=*)(objectclass=ldapsubentry))",
attrs, false, cons);
if (results == null) {
return null;
}
@ -5147,16 +5221,18 @@ public class LDAPConnection
c.m_prevBoundDN = this.m_prevBoundDN;
c.m_prevBoundPasswd = this.m_prevBoundPasswd;
c.m_anonymousBound = this.m_anonymousBound;
c.m_cache = this.m_cache;
c.setCache(this.m_cache); // increments cache reference cnt
c.m_factory = this.m_factory;
c.m_thread = this.m_thread; /* share current connection thread */
Vector v = (Vector)m_threadConnTable.get(this.m_thread);
if (v != null) {
v.addElement(c);
} else {
printDebug("Failed to clone");
return null;
synchronized (m_threadConnTable) {
Vector v = (Vector)m_threadConnTable.get(this.m_thread);
if (v != null) {
v.addElement(c);
} else {
printDebug("Failed to clone");
return null;
}
}
c.m_thread.register(c);

View File

@ -31,8 +31,9 @@ package netscape.ldap;
*
* @version 1.0
*/
public class LDAPConstraints implements Cloneable {
public class LDAPConstraints implements Cloneable, java.io.Serializable {
static final long serialVersionUID = 6506767263918312029L;
private int m_hop_limit;
private LDAPBind m_bind_proc;
private LDAPRebind m_rebind_proc;

View File

@ -161,7 +161,8 @@ import netscape.ldap.controls.*;
* @see netscape.ldap.LDAPConstraints#setClientControls
* @see netscape.ldap.LDAPConstraints#setServerControls
*/
public class LDAPControl implements Cloneable {
public class LDAPControl implements Cloneable, java.io.Serializable {
static final long serialVersionUID = 5149887553272603753L;
public final static String MANAGEDSAIT = "2.16.840.1.113730.3.4.2";
/* Password information sent back to client */
public final static String PWEXPIRED = "2.16.840.1.113730.3.4.4";

View File

@ -0,0 +1,395 @@
/* -*- 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) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
package netscape.ldap;
import java.util.*;
/**
* The definition of a DIT content rule in the schema.
* <A HREF="http://www.ietf.org/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol (v3):
* DIT Content Rule Description</A> covers the types of information
* to specify when defining a DIT content rule. According to the RFC,
* the description of a DIT content rule can include the following:
* <P>
*
* <UL>
* <LI>an OID identifying the attribute type
* <LI>a name identifying the attribute type
* <LI>a description of the attribute type
* <LI>the name of the parent attribute type
* <LI>the syntax used by the attribute (for example,
* <CODE>cis</CODE> or <CODE>int</CODE>)
* <LI>an indication of whether the attribute type is single-valued
* or multi-valued
* </UL>
* <P>
*
* When you construct an <CODE>LDAPDITContentRuleSchema</CODE> object, you can
* specify these types of information as arguments to the constructor or
* in the AttributeTypeDescription format specified in RFC 2252.
* When an LDAP client searches an LDAP server for the schema, the server
* returns schema information as an object with attribute values in this
* format.
* <P>
*
* There are a number of additional optional description fields which
* are not explicitly accessible through LDAPDITContentRuleSchema, but which
* can be managed with setQualifier, getQualifier, and getQualifierNames:
* <P>
*
* <UL>
* <LI>OBSOLETE
* </UL>
* <P>
*
* To get the name, OID, and description of this DIT content rule
* , use the <CODE>getName</CODE>, <CODE>getOID</CODE>, and
* <CODE>getDescription</CODE> methods inherited from the abstract class
* <CODE>LDAPSchemaElement</CODE>. Optional and custom qualifiers are
* accessed with <CODE>getQualifier</CODE> and <CODE>getQualifierNames</CODE>
* from <CODE>LDAPSchemaElement</CODE>.
* <P>
*
* To add or remove this attribute type definition from the
* schema, use the <CODE>add</CODE> and <CODE>remove</CODE>
* methods, which this class inherits from the <CODE>LDAPSchemaElement</CODE>
* abstract class.
* <P>
* RFC 2252 defines DITContentRuleDescription as follows:
* <P>
* <PRE>
* DITContentRuleDescription = "("
* numericoid ; Structural ObjectClass identifier
* [ "NAME" qdescrs ]
* [ "DESC" qdstring ]
* [ "OBSOLETE" ]
* [ "AUX" oids ] ; Auxiliary ObjectClasses
* [ "MUST" oids ] ; AttributeType identifiers
* [ "MAY" oids ] ; AttributeType identifiers
* [ "NOT" oids ] ; AttributeType identifiers
* ")"
* </PRE>
*
* @version 1.0
* @see netscape.ldap.LDAPSchemaElement
**/
public class LDAPDITContentRuleSchema extends LDAPSchemaElement {
static final long serialVersionUID = -8588488481097270056L;
/**
* Constructs a blank element.
*/
protected LDAPDITContentRuleSchema() {
super();
}
/**
* Constructs a DIT content rule definition, using the specified
* information.
* @param name name of the attribute type
* @param oid object identifier (OID) of the attribute type
* in dotted-string format (for example, "1.2.3.4")
* @param description description of attribute type
* @param obsolete <code>true</code> if the rule is obsolete
* @param auxiliary a list of auxiliary object classes
* allowed for an entry to which this content rule applies.
* These may either be specified by name or numeric oid.
* @param required a list of user attribute types that an entry
* to which this content rule applies must contain in addition to
* its normal set of mandatory attributes. These may either be
* specified by name or numeric oid.
* @param optional a list of user attribute types that an entry
* to which this content rule applies may contain in addition to
* its normal set of optional attributes. These may either be
* specified by name or numeric oid.
* @param precluded a list consisting of a subset of the optional
* user attribute types of the structural and auxiliary object
* classes which are precluded from an entry to which this content rule
* applies. These may either be specified by name or numeric oid.
*/
public LDAPDITContentRuleSchema( String name, String oid,
String description, boolean obsolete,
String[] auxiliary,
String[] required,
String[] optional,
String[] precluded ) {
super( name, oid, description, null );
if ( required != null ) {
for( int i = 0; i < required.length; i++ ) {
must.addElement( required[i] );
}
}
if ( optional != null ) {
for( int i = 0; i < optional.length; i++ ) {
may.addElement( optional[i] );
}
}
if ( auxiliary != null ) {
for( int i = 0; i < auxiliary.length; i++ ) {
aux.addElement( auxiliary[i] );
}
}
if ( precluded != null ) {
for( int i = 0; i < precluded.length; i++ ) {
not.addElement( precluded[i] );
}
}
if ( obsolete ) {
setQualifier( OBSOLETE, "" );
}
}
/**
* Constructs a DIT content rule definition based on a description in
* the DITContentRuleDescription format. For information on this format,
* (see <A HREF="http://www.ietf.org/rfc/rfc2252.txt"
* >RFC 2252, Lightweight Directory Access Protocol (v3):
* DIT Content Rule Description</A>. This is the format that LDAP servers
* and clients use to exchange schema information. (For example, when
* you search an LDAP server for its schema, the server returns an entry
* with the attributes "objectclasses" and "attributetypes". The
* values of "attributetypes" are attribute type descriptions
* in this format.)
* <P>
*
* @param raw definition of the DIT content rule in the
* DITContentRuleDescription format
*/
public LDAPDITContentRuleSchema( String raw ) {
attrName = "ditContentRules";
parseValue( raw );
Object o = properties.get( MAY );
if ( o != null ) {
if ( o instanceof Vector ) {
may = (Vector)o;
} else {
may.addElement( o );
}
}
o = properties.get( MUST );
if ( o != null ) {
if ( o instanceof Vector ) {
must = (Vector)o;
} else {
must.addElement( o );
}
}
o = properties.get( NOT );
if ( o != null ) {
if ( o instanceof Vector ) {
not = (Vector)o;
} else {
not.addElement( o );
}
}
o = properties.get( AUX );
if ( o != null ) {
if ( o instanceof Vector ) {
aux = (Vector)o;
} else {
aux.addElement( o );
}
}
}
/**
* Gets the names of the required attributes for
* this content rule.
* @return the names of the required attributes
* for this content rule.
*/
public String[] getRequiredAttributes() {
String[] vals = new String[must.size()];
must.copyInto( vals );
return vals;
}
/**
* Gets the names of optional attributes allowed
* in this content rule.
* @return the names of optional attributes
* allowed in this content rule.
*/
public String[] getOptionalAttributes() {
String[] vals = new String[may.size()];
may.copyInto( vals );
return vals;
}
/**
* Gets the names of the precluded attributes for
* this content rule.
* @return the names of the precluded attributes
* for this content rule.
*/
public String[] getPrecludedAttributes() {
String[] vals = new String[not.size()];
not.copyInto( vals );
return vals;
}
/**
* Gets the names of the auxiliary object classes allowed
* in this content rule.
* @return the names of auxiliary object classes
* allowed in this content rule.
*/
public String[] getAuxiliaryClasses() {
String[] vals = new String[aux.size()];
aux.copyInto( vals );
return vals;
}
/**
* Prepares a value in RFC 2252 format for submission to a server
*
* @return a String ready for submission to an LDAP server.
*/
public String getValue() {
String s = getValuePrefix();
String val;
val = getOptionalValues( NOVALS );
if ( val.length() > 0 ) {
s += val + ' ';
}
if ( aux.size() > 0 ) {
s += AUX + " " + vectorToList( aux );
s += ' ';
}
if ( must.size() > 0 ) {
s += MUST + " " + vectorToList( must );
s += ' ';
}
if ( may.size() > 0 ) {
s += MAY + " " + vectorToList( may );
s += ' ';
}
if ( not.size() > 0 ) {
s += NOT + " " + vectorToList( not );
s += ' ';
}
val = getCustomValues();
if ( val.length() > 0 ) {
s += val + ' ';
}
s += ')';
return s;
}
/**
* Creates a list within parentheses, with $ as delimiter
*
* @param vals values for list
* @return a String with a list of values.
*/
protected String vectorToList( Vector vals ) {
String val = "( ";
for( int i = 0; i < vals.size(); i++ ) {
val += (String)vals.elementAt(i) + ' ';
if ( i < (vals.size() - 1) ) {
val += "$ ";
}
}
val += ')';
return val;
}
/**
* Gets the definition of the rule in a user friendly format.
* This is the format that the rule definition uses when
* printing the attribute type or the schema.
* @return definition of the rule in a user friendly format.
*/
public String toString() {
String s = "Name: " + name + "; OID: " + oid;
s += "; Description: " + description + "; Required: ";
int i = 0;
Enumeration e = must.elements();
while( e.hasMoreElements() ) {
if ( i > 0 )
s += ", ";
i++;
s += (String)e.nextElement();
}
s += "; Optional: ";
e = may.elements();
i = 0;
while( e.hasMoreElements() ) {
if ( i > 0 )
s += ", ";
i++;
s += (String)e.nextElement();
}
s += "; Auxiliary: ";
e = aux.elements();
i = 0;
while( e.hasMoreElements() ) {
if ( i > 0 )
s += ", ";
i++;
s += (String)e.nextElement();
}
s += "; Precluded: ";
e = not.elements();
i = 0;
while( e.hasMoreElements() ) {
if ( i > 0 )
s += ", ";
i++;
s += (String)e.nextElement();
}
if ( isObsolete() ) {
s += "; OBSOLETE";
}
s += getQualifierString( IGNOREVALS );
return s;
}
public final static String AUX = "AUX";
public final static String MUST = "MUST";
public final static String MAY = "MAY";
public final static String NOT = "NOT";
// Qualifiers known to not have values; prepare a Hashtable
static final String[] NOVALS = { "OBSOLETE" };
static {
for( int i = 0; i < NOVALS.length; i++ ) {
novalsTable.put( NOVALS[i], NOVALS[i] );
}
}
// Qualifiers which we output explicitly in toString()
static final String[] IGNOREVALS = { OBSOLETE,
AUX,
MUST,
MAY,
NOT
};
private Vector must = new Vector();
private Vector may = new Vector();
private Vector aux = new Vector();
private Vector not = new Vector();
}

View File

@ -0,0 +1,276 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The structures 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) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
package netscape.ldap;
import java.util.*;
/**
* The definition of a DIT structure rule in the schema.
* <A HREF="http://www.ietf.org/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol (v3):
* DIT Structure Rule Description</A> covers the types of information
* to specify when defining a DIT structure rule. According to the RFC,
* the description of a DIT structure rule can include the following:
* <P>
*
* <UL>
* <LI>an OID identifying the attribute type
* <LI>a name identifying the attribute type
* <LI>a description of the attribute type
* <LI>the name of the parent attribute type
* <LI>the syntax used by the attribute (for example,
* <CODE>cis</CODE> or <CODE>int</CODE>)
* <LI>an indication of whether the attribute type is single-valued
* or multi-valued
* </UL>
* <P>
*
* When you construct an <CODE>LDAPDITStructureRuleSchema</CODE> object, you can
* specify these types of information as arguments to the constructor or
* in the AttributeTypeDescription format specified in RFC 2252.
* When an LDAP client searches an LDAP server for the schema, the server
* returns schema information as an object with attribute values in this
* format.
* <P>
*
* There are a number of additional optional description fields which
* are not explicitly accessible through LDAPDITStructureRuleSchema, but which
* can be managed with setQualifier, getQualifier, and getQualifierNames:
* <P>
*
* <UL>
* <LI>OBSOLETE
* </UL>
* <P>
*
* To get the name, OID, and description of this DIT structure rule
* , use the <CODE>getName</CODE>, <CODE>getOID</CODE>, and
* <CODE>getDescription</CODE> methods inherited from the abstract class
* <CODE>LDAPSchemaElement</CODE>. Optional and custom qualifiers are
* accessed with <CODE>getQualifier</CODE> and <CODE>getQualifierNames</CODE>
* from <CODE>LDAPSchemaElement</CODE>.
* <P>
*
* To add or remove this attribute type definition from the
* schema, use the <CODE>add</CODE> and <CODE>remove</CODE>
* methods, which this class inherits from the <CODE>LDAPSchemaElement</CODE>
* abstract class.
* <P>
* RFC 2252 defines DITStructureRuleDescription as follows:
* <P>
* <PRE>
* DITStructureRuleDescription = "(" whsp
* ruleidentifier whsp ; DITStructureRule identifier
* [ "NAME" qdescrs ]
* [ "DESC" qdstring ]
* [ "OBSOLETE" whsp ]
* "FORM" woid whsp ; NameForm
* [ "SUP" ruleidentifiers whsp ] ; superior DITStructureRules
* ")"
* </PRE>
*
* @version 1.0
* @see netscape.ldap.LDAPSchemaElement
**/
public class LDAPDITStructureRuleSchema extends LDAPSchemaElement {
static final long serialVersionUID = -2823317246039655811L;
/**
* Constructs a blank element.
*/
protected LDAPDITStructureRuleSchema() {
super();
}
/**
* Constructs a DIT structure rule definition, using the specified
* information.
* @param name name of the attribute type
* @param ruleID unique identifier of the structure rule.<BR>
* NOTE: this is an integer, not a dotted numerical identifier.
* Structure rules aren't identified by OID.
* @param description description of attribute type
* @param obsolete <code>true</code> if the rule is obsolete
* @param nameForm either the identifier or name of a name form.
* This is used to indirectly refer to the object class that this
* structure rule applies to.
* @param superiors list of superior structure rules - specified
* by their integer ID. The object class specified by this structure
* rule (via the nameForm parameter) may only be subordinate in
* the DIT to object classes of those represented by the structure
* rules here.
*/
public LDAPDITStructureRuleSchema( String name, int ruleID,
String description, boolean obsolete,
String nameForm,
String[] superiors ) {
super( name, "", description, null );
this.nameForm = nameForm;
this.ruleID = ruleID;
if ( obsolete ) {
setQualifier( OBSOLETE, "" );
}
if ( (superiors != null) && (superiors.length > 0) ) {
setQualifier( SUPERIOR, superiors );
}
}
/**
* Constructs a DIT structure rule definition based on a description in
* the DITStructureRuleDescription format. For information on this format,
* (see <A HREF="http://www.ietf.org/rfc/rfc2252.txt"
* >RFC 2252, Lightweight Directory Access Protocol (v3):
* DIT Structure Rule Description</A>. This is the format that
* LDAP servers
* and clients use to exchange schema information. (For example, when
* you search an LDAP server for its schema, the server returns an entry
* with the attributes "objectclasses" and "attributetypes". The
* values of "attributetypes" are attribute type descriptions
* in this format.)
* <P>
*
* @param raw definition of the DIT structure rule in the
* DITStructureRuleDescription format
*/
public LDAPDITStructureRuleSchema( String raw ) {
attrName = "ditStructureRules";
parseValue( raw );
Object o = properties.get( FORM );
if ( o != null ) {
nameForm = (String)o;
}
try {
ruleID = Integer.parseInt( oid );
} catch ( Exception e ) {
}
}
/**
* Returns a list of all structure rules that are superior to this
* structure rule. To resolve to an object class, you need to first
* resolve the superior id to another structure rule, then call
* getNameForm().getObjectClass() on that structure rule.
* @return the structure rules that are superior to this
* structure rule.
*/
public String[] getSuperiors() {
return getQualifier( SUPERIOR );
}
/**
* Returns the rule ID for this structure rule. Note that this returns
* an integer rather than a dotted decimal OID. Objects of this class do
* not have an OID, thus getID will return null.
*
* @return the rule ID for this structure rule.
*/
public int getRuleID() {
return ruleID;
}
/**
* Returns the NameForm that this structure rule controls. You can get
* the actual object class that this structure rule controls by calling
* getNameForm().getObjectClass().
*
* @return the NameForm that this structure rule controls.
*/
public String getNameForm() {
return nameForm;
}
/**
* Prepares a value in RFC 2252 format for submission to a server
*
* @return a String ready for submission to an LDAP server.
*/
public String getValue() {
String s = "( " + ruleID + ' ';
if ( name != null ) {
s += "NAME " + '\'' + name + "\' ";
}
if ( description != null ) {
s += "DESC \'" + description + "\' ";
}
if ( isObsolete() ) {
s += OBSOLETE + ' ';
}
s += FORM + " " + nameForm + ' ';
String val = getValue( SUPERIOR, false );
if ( (val != null) && (val.length() > 1) ) {
s += val + ' ';
}
val = getCustomValues();
if ( val.length() > 0 ) {
s += val + ' ';
}
s += ')';
return s;
}
/**
* Gets the definition of the rule in a user friendly format.
* This is the format that the rule definition uses when
* printing the attribute type or the schema.
* @return definition of the rule in a user friendly format.
*/
public String toString() {
String s = "Name: " + name + "; ruleID: " + ruleID + "; ";
s += "Description: " + description;
if ( isObsolete() ) {
s += "; OBSOLETE";
}
String[] superiors = getSuperiors();
if ( superiors != null ) {
for( int i = 0; i < superiors.length; i++ ) {
s += superiors[i];
if ( i < (superiors.length-1) ) {
s += ", ";
}
}
}
s += "Name form: " + nameForm + "; ";
s += getQualifierString( IGNOREVALS );
return s;
}
public final static String FORM = "FORM";
// Qualifiers known to not have values; prepare a Hashtable
static final String[] NOVALS = { "OBSOLETE" };
static {
for( int i = 0; i < NOVALS.length; i++ ) {
novalsTable.put( NOVALS[i], NOVALS[i] );
}
}
// Qualifiers which we output explicitly in toString()
static final String[] IGNOREVALS = { OBSOLETE,
FORM,
"SUP"
};
private String nameForm = null;
private int ruleID = 0;
}

View File

@ -132,11 +132,15 @@ public class LDAPDN {
StringBuffer copy = new StringBuffer();
int i=0;
while (i<buffer.length()) {
char c = buffer.charAt(i);
if (c != '\\')
char c = buffer.charAt(i++);
if (c != '\\') {
copy.append(c);
i++;
}
else { // copy the escaped char following the back slash
if (i<buffer.length()) {
copy.append(buffer.charAt(i++));
}
}
}
return name.getTypes()[0]+"="+(new String(copy));

View File

@ -28,8 +28,9 @@ import java.util.*;
*
* @version 1.0
*/
public class LDAPEntry {
public class LDAPEntry implements java.io.Serializable {
static final long serialVersionUID = -5563306228920012807L;
private String dn = null;
private LDAPAttributeSet attrSet = null;
@ -38,7 +39,7 @@ public class LDAPEntry {
*/
public LDAPEntry() {
dn = null;
attrSet = null;
attrSet = new LDAPAttributeSet();
}
/**
@ -48,7 +49,7 @@ public class LDAPEntry {
*/
public LDAPEntry( String distinguishedName ) {
dn = distinguishedName;
attrSet = null;
attrSet = new LDAPAttributeSet();
}
/**

View File

@ -129,7 +129,10 @@ import java.io.*;
* @version 1.0
* @see netscape.ldap.LDAPReferralException
*/
public class LDAPException extends java.lang.Exception {
public class LDAPException extends java.lang.Exception
implements java.io.Serializable {
static final long serialVersionUID = -9215007872184847924L;
/**
* (0) The operation completed successfully.

View File

@ -123,7 +123,9 @@ package netscape.ldap;
* @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String, java.lang.String[], boolean)
*
*/
public class LDAPExtendedOperation {
public class LDAPExtendedOperation implements java.io.Serializable {
static final long serialVersionUID = 4010382829133611945L;
/**
* Construct an object

View File

@ -28,7 +28,10 @@ import netscape.ldap.client.opers.JDAPExtendedResponse;
*
* @version 1.0
*/
public class LDAPExtendedResponse extends LDAPResponse {
public class LDAPExtendedResponse extends LDAPResponse
implements java.io.Serializable {
static final long serialVersionUID = -3813049515964705320L;
/**
* Constructor

View File

@ -30,6 +30,8 @@ package netscape.ldap;
*/
public class LDAPInterruptedException extends LDAPException {
static final long serialVersionUID = 5267455101797397456L;
/**
* Constructs a default exception with a specified string of
* additional information. This string appears if you call
@ -54,4 +56,4 @@ public class LDAPInterruptedException extends LDAPException {
}
return str;
}
}
}

View File

@ -100,6 +100,9 @@ import java.util.*;
**/
public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
static final long serialVersionUID = 6466155218986944131L;
/**
* Constructs a matching rule definition, using the specified
* information.

View File

@ -0,0 +1,212 @@
/* -*- 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) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
package netscape.ldap;
import java.util.*;
/**
* The definition of a matching rule use in the schema.
* <A HREF="http://ds.internic.net/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol (v3):
* Attribute Syntax Definitions</A> covers the types of information
* that need to be specified in the definition of a matching rule use.
* According to the RFC, the description of a matching rule use can
* include the following information:
* <P>
*
* <UL>
* <LI>an OID identifying the matching rule
* <LI>a name identifying the matching rule use
* <LI>a description of the matching rule use
* <LI>a list of attributes the matching rule applies to
* </UL>
* <P>
*
* When you construct an <CODE>LDAPMatchingRuleUseSchema</CODE> object, you can
* specify these types of information as arguments to the constructor or
* in the MatchingRuleUseDescription format specified in RFC 2252.
* When an LDAP client searches an LDAP server for the schema, the server
* returns schema information as an object with values in this
* format.
* <P>
*
* You can get the name, OID, and description of this matching rule use
* definition by using the <CODE>getName</CODE>, <CODE>getOID</CODE>, and
* <CODE>getDescription</CODE> methods inherited from the abstract class
* <CODE>LDAPSchemaElement</CODE>. Custom qualifiers are
* accessed with <CODE>getQualifier</CODE> and <CODE>getQualifierNames</CODE>
* from <CODE>LDAPSchemaElement</CODE>.
* <P>
*
* To add or remove this matching rule definition from the
* schema, use the <CODE>add</CODE> and <CODE>remove</CODE>
* methods, which this class inherits from the <CODE>LDAPSchemaElement</CODE>
* abstract class.
* <P>
* RFC 2252 defines MatchingRuleUseDescription follows:
* <P>
* <PRE>
* Values of the matchingRuleUse list the attributes which are suitable
* for use with an extensible matching rule.
*
* MatchingRuleUseDescription = "(" whsp
* numericoid whsp ; MatchingRule identifier
* [ "NAME" qdescrs ]
* [ "DESC" qdstring ]
* [ "OBSOLETE" ]
* "APPLIES" oids ; AttributeType identifiers
* whsp ")"
* </PRE>
* <P>
*
* @version 1.0
* @see netscape.ldap.LDAPSchemaElement
* @see netscape.ldap.LDAPMatchingRuleSchema
**/
public class LDAPMatchingRuleUseSchema extends LDAPAttributeSchema {
/**
* Constructs a matching rule use definition, using the specified
* information.
* @param name name of the matching rule
* @param oid object identifier (OID) of the matching rule
* in dotted-decimal format (for example, "1.2.3.4")
* @param description description of the matching rule
* @param attributes array of the OIDs of the attributes for which
* the matching rule is applicable
*/
public LDAPMatchingRuleUseSchema( String name, String oid,
String description,
String[] attributes ) {
if ( (oid == null) || (oid.trim().length() < 1) ) {
throw new IllegalArgumentException( "OID required" );
}
this.name = name;
this.oid = oid;
this.description = description;
attrName = "matchingruleuse";
this.attributes = new String[attributes.length];
for( int i = 0; i < attributes.length; i++ ) {
this.attributes[i] = attributes[i];
}
}
/**
* Constructs a matching rule use definition based on descriptions in
* the MatchingRuleUseDescription format. For information on this format,
* (see <A HREF="http://ds.internic.net/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol (v3):
* Attribute Syntax Definitions</A>. This is the format that LDAP servers
* and clients use to exchange schema information. For example, when
* you search an LDAP server for its schema, the server returns an entry
* with attributes that include "matchingrule" and "matchingruleuse".
* The values of these attributes are matching rule descriptions
* in this format.
* <P>
*
* @param use definition of the use of the matching rule in the
* MatchingRuleUseDescription format
*/
public LDAPMatchingRuleUseSchema( String use ) {
attrName = "matchingruleuse";
parseValue( use );
Vector v = (Vector)properties.get( "APPLIES" );
if ( v != null ) {
attributes = new String[v.size()];
v.copyInto( attributes );
v.removeAllElements();
}
}
/**
* Gets the list of the OIDs of the attribute types which can be used
* with the matching rule.
* @return array of the OIDs of the attribute types which can be used
* with the matching rule.
*/
public String[] getApplicableAttributes() {
return attributes;
}
/**
* Gets the matching rule use definition in the string representation
* of the MatchingRuleUseDescription data type defined in X.501 (see
* <A HREF="http://ds.internic.net/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol
* (v3): Attribute Syntax Definitions</A>
* for a description of these formats).
* This is the format that LDAP servers and clients use to exchange
* schema information. (For example, when
* you search an LDAP server for its schema, the server returns an entry
* with the attributes "matchingrules" and "matchingruleuse". The
* values of these attributes are matching rule description and
* matching rule use description in these formats.)
* <P>
*
* @return a string in a format that can be used as the value of
* the <CODE>matchingruleuse</CODE> attribute (which describes the use of
* a matching rule in the schema) of a <CODE>subschema</CODE> object
*/
public String getValue() {
String s = getValuePrefix();
if ( (attributes != null) && (attributes.length > 0) ) {
s += "APPLIES ( ";
for( int i = 0; i < attributes.length; i++ ) {
if ( i > 0 )
s += " $ ";
s += attributes[i];
}
s += " ) ";
}
s += ')';
return s;
}
/**
* Gets the definition of the matching rule use in a user friendly format.
* This is the format that the matching rule use definition uses when
* you print the matching rule or the schema.
* @return definition of the matching rule in a user friendly format.
*/
public String toString() {
String s = "Name: " + name + "; OID: " + oid;
s += "; Description: " + description;
if ( attributes != null ) {
s += "; Applies to: ";
for( int i = 0; i < attributes.length; i++ ) {
if ( i > 0 )
s += ", ";
s += attributes[i];
}
}
s += getQualifierString( EXPLICIT );
return s;
}
// Qualifiers tracked explicitly
static final String[] EXPLICIT = { OBSOLETE };
private String[] attributes = null;
}

View File

@ -49,7 +49,9 @@ import java.text.SimpleDateFormat;
*
* @version 1.0
*/
public class LDAPMessage {
public class LDAPMessage implements java.io.Serializable {
static final long serialVersionUID = -1364094245850026720L;
public final static int BIND_REQUEST = 0;
public final static int BIND_RESPONSE = 1;

View File

@ -33,7 +33,9 @@ import java.util.Vector;
* Superclass for LDAResponseListener and LDAPSearchListener
*
*/
class LDAPMessageQueue {
class LDAPMessageQueue implements java.io.Serializable {
static final long serialVersionUID = -7163312406176592277L;
/**
* Request entry encapsulates request parameters

View File

@ -44,7 +44,9 @@ import netscape.ldap.ber.stream.*;
* @version 1.0
* @see netscape.ldap.LDAPConnection#modify(java.lang.String, netscape.ldap.LDAPModification)
*/
public class LDAPModification {
public class LDAPModification implements java.io.Serializable {
static final long serialVersionUID = 4836472112866826595L;
/**
* Specifies that a value should be added to an attribute.

View File

@ -37,8 +37,9 @@ import java.util.*;
* @see netscape.ldap.LDAPModification
* @see netscape.ldap.LDAPConnection#modify(java.lang.String, netscape.ldap.LDAPModificationSet)
*/
public class LDAPModificationSet {
public class LDAPModificationSet implements java.io.Serializable {
static final long serialVersionUID = 4650238666753391214L;
private int current = 0;
private Vector modifications;

View File

@ -0,0 +1,295 @@
/* -*- 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) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
package netscape.ldap;
import java.util.*;
/**
* The definition of a name form in the schema.
* <A HREF="http://ds.internic.net/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol (v3):
* Attribute Syntax Definitions</A> covers the types of information
* that need to be specified in the definition of a name form.
* According to the RFC, the description of a name form can
* include the following information:
* <P>
*
* <UL>
* <LI>an OID identifying the name form
* <LI>a name identifying the name form
* <LI>a description of the name form
* <LI>the structural object class of this name form
* <LI>the list of attribute types that are required in this name form
* <LI>the list of attribute types that are allowed (optional) in this
* name form
* </UL>
* <P>
*
* When you construct an <CODE>LDAPNameFormSchema</CODE> object,
* you can specify
* these types of information as arguments to the constructor or in the
* NameFormDescription format specified in RFC 2252.
* When an LDAP client searches an LDAP server for the schema, the server
* returns schema information as an object with attribute values in this
* format.
* <P>
*
* You can get the name, OID, and description of this name form
* definition by using the <CODE>getName</CODE>, <CODE>getOID</CODE>, and
* <CODE>getDescription</CODE> methods inherited from the abstract class
* <CODE>LDAPSchemaElement</CODE>. Optional and custom qualifiers are
* accessed with <CODE>getQualifier</CODE> and <CODE>getQualifierNames</CODE>
* from <CODE>LDAPSchemaElement</CODE>.
* <P>
*
* To add or remove this name form definition from the
* schema, use the <CODE>add</CODE> and <CODE>remove</CODE>
* methods, which this class inherits from the <CODE>LDAPSchemaElement</CODE>
* abstract class.
* <P>
* RFC 2252 defines NameFormDescription as follows:
* <P>
* <PRE>
* NameFormDescription = "(" whsp
* numericoid whsp ; NameForm identifier
* [ "NAME" qdescrs ]
* [ "DESC" qdstring ]
* [ "OBSOLETE" whsp ]
* "OC" woid ; Structural ObjectClass
* [ "MUST" oids ] ; AttributeTypes
* [ "MAY" oids ] ; AttributeTypes
* whsp ")"
* </PRE>
*
* @version 1.0
* @see netscape.ldap.LDAPSchemaElement
**/
public class LDAPNameFormSchema extends LDAPSchemaElement {
static final long serialVersionUID = 1665316286199590403L;
/**
* Constructs a name form definition, using the specified
* information.
* @param name name of the name form
* @param oid object identifier (OID) of the name form
* in dotted-string format (for example, "1.2.3.4")
* @param description description of the name form
* @param obsolete <code>true</code> if the rule is obsolete
* @param objectClass the object to which this name form applies.
* This may either be specified by name or numeric oid.
* @param required array of names of attributes required
* in this name form
* @param optional array of names of optional attributes
* allowed in this name form
*/
public LDAPNameFormSchema( String name, String oid,
String description, boolean obsolete,
String objectClass,
String[] required, String[] optional ) {
super( name, oid, description, null );
attrName = "nameforms";
if ( obsolete ) {
setQualifier( OBSOLETE, "" );
}
this.objectClass = objectClass;
if ( required != null ) {
for( int i = 0; i < required.length; i++ ) {
must.addElement( required[i] );
}
}
if ( optional != null ) {
for( int i = 0; i < optional.length; i++ ) {
may.addElement( optional[i] );
}
}
}
/**
* Constructs a name form definition based on a description in
* the NameFormDescription format. For information on this format,
* (see <A HREF="http://ds.internic.net/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol (v3):
* Attribute Syntax Definitions</A>. This is the format that LDAP servers
* and clients use to exchange schema information. (For example, when
* you search an LDAP server for its schema, the server returns an entry
* with the attributes "objectclasses" and "attributetypes". The
* values of the "objectclasses" attribute are name form descriptions
* in this format.)
* <P>
*
* @param raw definition of the object in the NameFormDescription
* format
*/
public LDAPNameFormSchema( String raw ) {
attrName = "objectclasses";
parseValue( raw );
Object o = properties.get( "MAY" );
if ( o != null ) {
if ( o instanceof Vector ) {
may = (Vector)o;
} else {
may.addElement( o );
}
}
o = properties.get( "MUST" );
if ( o != null ) {
if ( o instanceof Vector ) {
must = (Vector)o;
} else {
must.addElement( o );
}
}
o = properties.get( "OC" );
if ( o != null ) {
objectClass = (String)o;
}
}
/**
* Gets the names of the required attributes for
* this name form.
* @return the names of the required attributes
* for this name form.
*/
public String[] getRequiredNamingAttributes() {
String[] vals = new String[must.size()];
must.copyInto( vals );
return vals;
}
/**
* Gets the names of optional attributes allowed
* in this name form.
* @return the names of optional attributes
* allowed in this name form.
*/
public String[] getOptionalNamingAttributes() {
String[] vals = new String[may.size()];
may.copyInto( vals );
return vals;
}
/**
* Returns the name of the object class that this name form applies to.
*
* @return the name of the object class that this name form applies to.
*/
public String getObjectClass() {
return objectClass;
}
/**
* Prepares a value in RFC 2252 format for submitting to a server.
*
* @param quotingBug <CODE>true</CODE> if SUP and SYNTAX values are to
* be quoted. That is to satisfy bugs in certain LDAP servers.
* @return a String ready for submission to an LDAP server.
*/
String getValue( boolean quotingBug ) {
String s = getValuePrefix();
String val = getOptionalValues( NOVALS );
if ( val.length() > 0 ) {
s += val + ' ';
}
s += "OC " + objectClass + ' ';
if ( must.size() > 0 ) {
s += "MUST " + vectorToList( must );
s += ' ';
}
if ( may.size() > 0 ) {
s += "MAY " + vectorToList( may );
s += ' ';
}
val = getCustomValues();
if ( val.length() > 0 ) {
s += val + ' ';
}
s += ')';
return s;
}
/**
* Gets the definition of the name form in a user friendly format.
* This is the format that the name form definition uses when
* you print the name form or the schema.
* @return definition of the name form in a user friendly format.
*/
public String toString() {
String s = "Name: " + name + "; OID: " + oid;
s += "; Description: " + description + "; Required: ";
String[] vals = getRequiredNamingAttributes();
for( int i = 0; i < vals.length; i++ ) {
if ( i > 0 )
s += ", ";
s += vals[i];
}
s += "; Optional: ";
vals = getOptionalNamingAttributes();
for( int i = 0; i < vals.length; i++ ) {
if ( i > 0 )
s += ", ";
s += vals[i];
}
if ( isObsolete() ) {
s += "; OBSOLETE";
}
s += getQualifierString( IGNOREVALS );
return s;
}
/**
* Creates a list within parentheses, with $ as delimiter
*
* @param vals values for list
* @return a String with a list of values.
*/
protected String vectorToList( Vector vals ) {
String val = "( ";
for( int i = 0; i < vals.size(); i++ ) {
val += (String)vals.elementAt(i) + ' ';
if ( i < (vals.size() - 1) ) {
val += "$ ";
}
}
val += ')';
return val;
}
private Vector must = new Vector();
private Vector may = new Vector();
private String objectClass = null;
// Qualifiers known to not have values; prepare a Hashtable
static final String[] NOVALS = { "OBSOLETE" };
static {
for( int i = 0; i < NOVALS.length; i++ ) {
novalsTable.put( NOVALS[i], NOVALS[i] );
}
}
// Qualifiers which we output explicitly in toString()
static final String[] IGNOREVALS = { "MUST", "MAY",
"OBJECTCLASS", "OBSOLETE"};
}

View File

@ -104,6 +104,9 @@ import java.util.*;
* @see netscape.ldap.LDAPSchemaElement
**/
public class LDAPObjectClassSchema extends LDAPSchemaElement {
static final long serialVersionUID = -1732784695071118656L;
/**
* Constructs an object class definition, using the specified
* information. The type of the object class will be STRUCTURAL.
@ -121,19 +124,7 @@ public class LDAPObjectClassSchema extends LDAPSchemaElement {
public LDAPObjectClassSchema( String name, String oid, String superior,
String description,
String[] required, String[] optional ) {
super( name, oid, description );
attrName = "objectclasses";
setQualifier( SUPERIOR, superior );
if ( required != null ) {
for( int i = 0; i < required.length; i++ ) {
must.addElement( required[i] );
}
}
if ( optional != null ) {
for( int i = 0; i < optional.length; i++ ) {
may.addElement( optional[i] );
}
}
this( name, oid, superior, description, required, optional, null );
}
/**
@ -161,13 +152,43 @@ public class LDAPObjectClassSchema extends LDAPSchemaElement {
this( name, oid,
((superiors != null) && (superiors.length > 0)) ?
superiors[0] : null,
description, required, optional );
description, required, optional, aliases );
if ( (superiors != null) && (superiors.length > 1) ) {
setQualifier( SUPERIOR, superiors );
}
setQualifier( TYPE, typeToString( type ) );
if ( (aliases != null) && (aliases.length > 0) ) {
this.aliases = aliases;
}
/**
* Constructs an object class definition, using the specified
* information. The type of the object class will be STRUCTURAL.
* @param name name of the object class
* @param oid object identifier (OID) of the object class
* in dotted-string format (for example, "1.2.3.4")
* @param description description of the object class
* @param superior name of the parent object class
* (the object class that the new object class inherits from)
* @param required array of names of attributes required
* in this object class
* @param optional array of names of optional attributes
* allowed in this object class
*/
protected LDAPObjectClassSchema( String name, String oid, String superior,
String description,
String[] required, String[] optional,
String[] aliases ) {
super( name, oid, description, aliases );
attrName = "objectclasses";
setQualifier( SUPERIOR, superior );
if ( required != null ) {
for( int i = 0; i < required.length; i++ ) {
must.addElement( required[i] );
}
}
if ( optional != null ) {
for( int i = 0; i < optional.length; i++ ) {
may.addElement( optional[i] );
}
}
}

View File

@ -53,8 +53,9 @@ import java.io.*;
* @version 1.0
* @see netscape.ldap.LDAPRebind
*/
public class LDAPRebindAuth {
public class LDAPRebindAuth implements java.io.Serializable {
static final long serialVersionUID = 7161655313564756294L;
private String m_dn;
private String m_password;

View File

@ -37,6 +37,7 @@ import java.io.*;
*/
public class LDAPReferralException extends LDAPException {
static final long serialVersionUID = 1771536577344289897L;
private String m_referrals[] = null; /* modified for LDAPv3 */
/**

View File

@ -42,8 +42,9 @@ import java.io.*;
* </pre>
* @see java.util.Locale
*/
class LDAPResourceBundle {
class LDAPResourceBundle implements java.io.Serializable {
static final long serialVersionUID = -5903986665461157980L;
private static final boolean m_debug = false;
private static final String m_suffix = ".props";
private static final String m_locale_separator = "_";

View File

@ -31,6 +31,8 @@ import netscape.ldap.client.opers.JDAPResult;
*/
public class LDAPResponse extends LDAPMessage {
static final long serialVersionUID = 5822205242593427418L;
/**
* Constructor
*

View File

@ -26,7 +26,8 @@ package netscape.ldap;
* It stores the response controls and its corresponding LDAPConnection and
* the message ID for its corresponding LDAPMessage.
*/
class LDAPResponseControl {
class LDAPResponseControl implements java.io.Serializable {
static final long serialVersionUID = 389472019686058593L;
private LDAPConnection m_connection;
private int m_messageID;
private LDAPControl[] m_controls;
@ -52,4 +53,4 @@ class LDAPResponseControl {
public LDAPConnection getConnection() {
return m_connection;
}
}
}

View File

@ -29,6 +29,8 @@ package netscape.ldap;
*/
public class LDAPResponseListener extends LDAPMessageQueue{
static final long serialVersionUID = 901897097111294329L;
/**
* Constructor
* @param asynchOp a boolean flag that is true if the object is used for

View File

@ -45,7 +45,10 @@ import java.net.*;
* @see LDAPSSLSocketFactoryExt
* @see LDAPConnection#LDAPConnection(netscape.ldap.LDAPSocketFactory)
*/
public class LDAPSSLSocketFactory implements LDAPSSLSocketFactoryExt {
public class LDAPSSLSocketFactory
implements LDAPSSLSocketFactoryExt, java.io.Serializable {
static final long serialVersionUID = -3331456736649381427L;
/**
* Indicates if client authentication is on.

View File

@ -40,7 +40,10 @@ import java.util.Hashtable;
* @see LDAPSocketFactory
* @see LDAPConnection#LDAPConnection(netscape.ldap.LDAPSocketFactory)
*/
public class LDAPSSLSocketWrapFactory implements LDAPSSLSocketFactoryExt {
public class LDAPSSLSocketWrapFactory
implements LDAPSSLSocketFactoryExt, java.io.Serializable {
static final long serialVersionUID = -4171548771815037740L;
/**
* The constructor with the specified package for security

View File

@ -158,7 +158,10 @@ import java.util.*;
* @version 1.0
* @author Rob Weltman
**/
public class LDAPSchema {
public class LDAPSchema implements java.io.Serializable {
static final long serialVersionUID = -3911737419783579398L;
/**
* Constructs a new <CODE>LDAPSchema</CODE> object.
* Once you construct the object, you can get
@ -275,6 +278,130 @@ public class LDAPSchema {
matchingRules.put( matchSchema.getName().toLowerCase(), matchSchema );
}
/**
* Add a syntax schema definition to the current schema.
* You can also add syntax schema definitions by calling the
* <CODE>add</CODE> method of your newly constructed
* <CODE>LDAPSyntaxSchema</CODE> object.
* <P>
*
* To remove a syntax schema definition that you have added,
* call the <CODE>getSyntax</CODE> method to get the
* <CODE>LDAPSyntaxSchema</CODE> object representing your
* syntax type and call the <CODE>remove</CODE> method.
* <P>
*
* <B>NOTE: </B>For information on the <CODE>add</CODE> and
* <CODE>remove</CODE> methods of <CODE>LDAPSyntaxSchema</CODE>,
* see the documentation for <CODE>LDAPSchemaElement</CODE>.
* (These methods are inherited from <CODE>LDAPSchemaElement</CODE>.)
* <P>
*
* @param syntaxSchema <CODE>LDAPSyntaxSchema</CODE> object
* representing the syntax schema definition to add
* @see netscape.ldap.LDAPSyntaxSchema
* @see netscape.ldap.LDAPSchemaElement#add
* @see netscape.ldap.LDAPSchemaElement#remove
*/
public void addSyntax( LDAPSyntaxSchema syntaxSchema ) {
String name = syntaxSchema.getName().toLowerCase();
if ( name.length() < 1 ) {
name = syntaxSchema.getOID();
}
syntaxes.put( name, syntaxSchema );
}
/**
* Add a structure rule definition to the current schema.
* You can also add structure rule definitions by calling the
* <CODE>add</CODE> method of your newly constructed
* <CODE>LDAPDITStructureRuleSchema</CODE> object.
* <P>
*
* To remove a structure rule definition that you have added,
* call the <CODE>getDITStructureRule</CODE> method to get the
* <CODE>LDAPDITStructureRuleSchema</CODE> object representing your
* rule and call the <CODE>remove</CODE> method.
* <P>
*
* <B>NOTE: </B>For information on the <CODE>add</CODE> and
* <CODE>remove</CODE> methods of <CODE>LDAPSyntaxSchema</CODE>,
* see the documentation for <CODE>LDAPSchemaElement</CODE>.
* (These methods are inherited from <CODE>LDAPSchemaElement</CODE>.)
* <P>
*
* @param rule <CODE>LDAPDITStructureRuleSchema</CODE> object
* representing the structure rule definition to add
* @see netscape.ldap.LDAPDITStructureRuleSchema
* @see netscape.ldap.LDAPSchemaElement#add
* @see netscape.ldap.LDAPSchemaElement#remove
*/
public void addDITStructureRule( LDAPDITStructureRuleSchema rule ) {
String name = rule.getName().toLowerCase();
structureRulesByName.put( name, rule );
structureRulesById.put( new Integer( rule.getRuleID() ), rule );
}
/**
* Add a content rule definition to the current schema.
* You can also add content rule definitions by calling the
* <CODE>add</CODE> method of your newly constructed
* <CODE>LDAPDITContentRuleSchema</CODE> object.
* <P>
*
* To remove a content rule definition that you have added,
* call the <CODE>getDITContentRule</CODE> method to get the
* <CODE>LDAPDITContentRuleSchema</CODE> object representing your
* rule and call the <CODE>remove</CODE> method.
* <P>
*
* <B>NOTE: </B>For information on the <CODE>add</CODE> and
* <CODE>remove</CODE> methods of <CODE>LDAPSyntaxSchema</CODE>,
* see the documentation for <CODE>LDAPSchemaElement</CODE>.
* (These methods are inherited from <CODE>LDAPSchemaElement</CODE>.)
* <P>
*
* @param rule <CODE>LDAPDITContentRuleSchema</CODE> object
* representing the content rule definition to add
* @see netscape.ldap.LDAPDITContentRuleSchema
* @see netscape.ldap.LDAPSchemaElement#add
* @see netscape.ldap.LDAPSchemaElement#remove
*/
public void addDITContentRule( LDAPDITContentRuleSchema rule ) {
String name = rule.getName().toLowerCase();
contentRules.put( name, rule );
}
/**
* Add a name form definition to the current schema.
* You can also add name form definitions by calling the
* <CODE>add</CODE> method of your newly constructed
* <CODE>LDAPNameFormSchema</CODE> object.
* <P>
*
* To remove a name form definition that you have added,
* call the <CODE>getNameForm</CODE> method to get the
* <CODE>LDAPNameFormSchema</CODE> object representing your
* nameForm type and call the <CODE>remove</CODE> method.
* <P>
*
* <B>NOTE: </B>For information on the <CODE>add</CODE> and
* <CODE>remove</CODE> methods of <CODE>LDAPNameFormSchema</CODE>,
* see the documentation for <CODE>LDAPSchemaElement</CODE>.
* (These methods are inherited from <CODE>LDAPSchemaElement</CODE>.)
* <P>
*
* @param nameForm <CODE>LDAPNameFormSchema</CODE> object
* representing the name form definition to add
* @see netscape.ldap.LDAPNameFormSchema
* @see netscape.ldap.LDAPSchemaElement#add
* @see netscape.ldap.LDAPSchemaElement#remove
*/
public void addNameForm( LDAPNameFormSchema nameForm ) {
String name = nameForm.getName().toLowerCase();
nameForms.put( name, nameForm );
}
/**
* Gets an enumeration ofthe object class definitions in this schema.
* @return an enumeration of object class definitions.
@ -299,6 +426,38 @@ public class LDAPSchema {
return matchingRules.elements();
}
/**
* Get an enumeration of the syntaxes in this schema.
* @return an enumeration of syntax objects
*/
public Enumeration getSyntaxes() {
return syntaxes.elements();
}
/**
* Get an enumeration of the structure rules in this schema.
* @return an enumeration of structure rule objects
*/
public Enumeration getDITStructureRules() {
return structureRulesByName.elements();
}
/**
* Get an enumeration of the content rules in this schema.
* @return an enumeration of content rule objects
*/
public Enumeration getDITContentRules() {
return contentRules.elements();
}
/**
* Get an enumeration of the name forms in this schema.
* @return an enumeration of name form objects
*/
public Enumeration getNameForms() {
return nameForms.elements();
}
/**
* Gets the definition of the object class with the specified name.
* @param name name of the object class to find
@ -329,6 +488,59 @@ public class LDAPSchema {
return (LDAPMatchingRuleSchema)matchingRules.get( name.toLowerCase() );
}
/**
* Gets the definition of a syntax with the specified name.
* @param name name of the syntax to find
* @return an <CODE>LDAPSyntaxSchema</CODE> object representing
* the syntax definition, or <CODE>null</CODE> if not found.
*/
public LDAPSyntaxSchema getSyntax( String name ) {
return (LDAPSyntaxSchema)syntaxes.get( name.toLowerCase() );
}
/**
* Gets the definition of a structure rule with the specified name.
* @param name name of the rule to find
* @return an <CODE>LDAPDITStructureRuleSchema</CODE> object representing
* the rule, or <CODE>null</CODE> if not found.
*/
public LDAPDITStructureRuleSchema getDITStructureRule( String name ) {
return (LDAPDITStructureRuleSchema)structureRulesByName.get(
name.toLowerCase() );
}
/**
* Gets the definition of a structure rule with the specified name.
* @param ID ID of the rule to find
* @return an <CODE>LDAPDITStructureRuleSchema</CODE> object representing
* the rule, or <CODE>null</CODE> if not found.
*/
public LDAPDITStructureRuleSchema getDITStructureRule( int ID ) {
return (LDAPDITStructureRuleSchema)structureRulesById.get(
new Integer( ID ) );
}
/**
* Gets the definition of a content rule with the specified name.
* @param name name of the rule to find
* @return an <CODE>LDAPDITContentRuleSchema</CODE> object representing
* the rule, or <CODE>null</CODE> if not found.
*/
public LDAPDITContentRuleSchema getDITContentRule( String name ) {
return (LDAPDITContentRuleSchema)contentRules.get(
name.toLowerCase() );
}
/**
* Gets the definition of a name form with the specified name.
* @param name name of the name form to find
* @return an <CODE>LDAPNameFormSchema</CODE> object representing
* the syntax definition, or <CODE>null</CODE> if not found.
*/
public LDAPNameFormSchema getNameForm( String name ) {
return (LDAPNameFormSchema)nameForms.get( name.toLowerCase() );
}
/**
* Get an enumeration of the names of the object classes in this schema.
* @return an enumeration of object class names (all lower-case).
@ -353,6 +565,38 @@ public class LDAPSchema {
return matchingRules.keys();
}
/**
* Get an enumeration of the names of the syntaxes in this schema.
* @return an enumeration of syntax names (all lower-case).
*/
public Enumeration getSyntaxNames() {
return syntaxes.keys();
}
/**
* Get an enumeration of the names of the structure rules in this schema.
* @return an enumeration of names of the structure rule objects
*/
public Enumeration getDITStructureRuleNames() {
return structureRulesByName.keys();
}
/**
* Get an enumeration of the names of the content rules in this schema.
* @return an enumeration of names of the content rule objects
*/
public Enumeration getDITContentRuleNames() {
return contentRules.keys();
}
/**
* Get an enumeration of the names of the name forms in this schema.
* @return an enumeration of names of name form objects
*/
public Enumeration getNameFormNames() {
return nameForms.keys();
}
/**
* Retrieve the schema for a specific entry.
* @param ld an active connection to a Directory Server
@ -399,6 +643,53 @@ public class LDAPSchema {
}
}
/* Get all syntax definitions */
attr = entry.getAttribute( "ldapsyntaxes" );
if ( attr != null ) {
en = attr.getStringValues();
while( en.hasMoreElements() ) {
LDAPSyntaxSchema sch =
new LDAPSyntaxSchema( (String)en.nextElement() );
addSyntax( sch );
}
}
/* Get all structure rule definitions */
attr = entry.getAttribute( "ldapditstructurerules" );
if ( attr != null ) {
en = attr.getStringValues();
while( en.hasMoreElements() ) {
LDAPDITStructureRuleSchema sch =
new LDAPDITStructureRuleSchema(
(String)en.nextElement() );
addDITStructureRule( sch );
}
}
/* Get all content rule definitions */
attr = entry.getAttribute( "ldapditcontentrules" );
if ( attr != null ) {
en = attr.getStringValues();
while( en.hasMoreElements() ) {
LDAPDITContentRuleSchema sch =
new LDAPDITContentRuleSchema(
(String)en.nextElement() );
addDITContentRule( sch );
}
}
/* Get all name form definitions */
attr = entry.getAttribute( "nameforms" );
if ( attr != null ) {
en = attr.getStringValues();
while( en.hasMoreElements() ) {
LDAPNameFormSchema sch =
new LDAPNameFormSchema(
(String)en.nextElement() );
addNameForm( sch );
}
}
/* Matching rules are tricky, because we have to match up a
rule with its use. First get all the uses. */
Hashtable h = new Hashtable();
@ -527,6 +818,12 @@ public class LDAPSchema {
s += en.nextElement().toString();
s += '\n';
}
s += "Syntaxes:\n";
en = getSyntaxes();
while( en.hasMoreElements() ) {
s += en.nextElement().toString();
s += '\n';
}
return s;
}
@ -572,7 +869,7 @@ public class LDAPSchema {
private static LDAPEntry readSchema( LDAPConnection ld, String dn )
throws LDAPException {
return readSchema( ld, dn, null );
return readSchema( ld, dn, new String[] { "*", "ldapsyntaxes" } );
}
/**
@ -620,6 +917,8 @@ public class LDAPSchema {
printEnum( schema.getAttributes() );
System.out.println( "\nMatching rules: " );
printEnum( schema.getMatchingRules() );
System.out.println( "\nSyntaxes: " );
printEnum( schema.getSyntaxes() );
System.exit( 0 );
} catch ( LDAPException e ) {
System.err.println( e );
@ -629,4 +928,9 @@ public class LDAPSchema {
private Hashtable objectClasses = new Hashtable();
private Hashtable attributes = new Hashtable();
private Hashtable matchingRules = new Hashtable();
private Hashtable syntaxes = new Hashtable();
private Hashtable structureRulesByName = new Hashtable();
private Hashtable structureRulesById = new Hashtable();
private Hashtable contentRules = new Hashtable();
private Hashtable nameForms = new Hashtable();
}

View File

@ -77,7 +77,10 @@ import java.util.*;
* @version 1.0
**/
public abstract class LDAPSchemaElement {
public abstract class LDAPSchemaElement implements java.io.Serializable {
static final long serialVersionUID = -3972153461950418863L;
/**
* Constructs a blank element.
*/
@ -92,12 +95,28 @@ public abstract class LDAPSchemaElement {
*/
protected LDAPSchemaElement( String name, String oid,
String description ) {
if ( (oid == null) || (oid.trim().length() < 1) ) {
this( name, oid, description, null );
}
/**
* Constructs a definition explicitly.
* @param name name of element
* @param oid dotted-string object identifier
* @param description description of element
* @param aliases names which are to be considered aliases for this
* element; <CODE>null</CODE> if there are no aliases
*/
protected LDAPSchemaElement( String name, String oid,
String description, String[] aliases ) {
if ( oid == null ) {
throw new IllegalArgumentException( "OID required" );
}
this.name = name;
this.oid = oid;
this.description = description;
if ( (aliases != null) && (aliases.length > 0) ) {
this.aliases = aliases;
}
}
/**
@ -300,7 +319,8 @@ public abstract class LDAPSchemaElement {
* @return <CODE>true<CODE> if the element is defined as obsolete.
*/
public boolean isObsolete() {
return properties.containsKey(OBSOLETE);
return (properties == null) ? false :
properties.containsKey(OBSOLETE);
}
/**
@ -476,7 +496,7 @@ public abstract class LDAPSchemaElement {
*/
String getValuePrefix() {
String s = "( " + oid + ' ';
if ( name != null ) {
if ( (name != null) && (name.length() > 0) ) {
s += "NAME ";
if ( aliases != null ) {
s += "( " + '\'' + name + "\' ";

View File

@ -38,7 +38,7 @@ public class LDAPSearchConstraints extends LDAPConstraints
private int maxRes;
private int batch;
private int serverTimeLimit;
transient private int m_maxBacklog = 100;
private int m_maxBacklog = 100;
/**
* Constructs an <CODE>LDAPSearchConstraints</CODE> object that specifies

View File

@ -31,6 +31,7 @@ import netscape.ldap.client.*;
*/
public class LDAPSearchListener extends LDAPMessageQueue {
static final long serialVersionUID = -7163312406176592277L;
// this instance variable is only for cache purpose
private Long m_key = null;
private LDAPSearchConstraints m_constraints;

View File

@ -30,6 +30,8 @@ import netscape.ldap.client.opers.JDAPSearchResponse;
*/
public class LDAPSearchResult extends LDAPMessage {
static final long serialVersionUID = 36890821518462301L;
/**
* LDAPEntry
*/

View File

@ -30,6 +30,8 @@ import netscape.ldap.client.opers.JDAPSearchResultReference;
*/
public class LDAPSearchResultReference extends LDAPMessage {
static final long serialVersionUID = -7816778029315223117L;
/**
* A list of LDAP URLs that are referred to.
*/

View File

@ -41,8 +41,9 @@ import java.io.*;
* @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String, java.lang.String[], boolean)
* @see netscape.ldap.LDAPConnection#abandon(netscape.ldap.LDAPSearchResults)
*/
public class LDAPSearchResults implements Enumeration {
public class LDAPSearchResults implements Enumeration, java.io.Serializable {
static final long serialVersionUID = -501692208613904825L;
private Vector entries = null;
private LDAPSearchListener resultSource;
private boolean searchComplete = false;
@ -73,6 +74,7 @@ public class LDAPSearchResults implements Enumeration {
entries = new Vector();
connectionToClose = null;
searchComplete = true;
currCons = new LDAPSearchConstraints();
}
LDAPSearchResults(LDAPConnection conn, LDAPSearchConstraints cons,
@ -105,8 +107,10 @@ public class LDAPSearchResults implements Enumeration {
}
}
LDAPSearchResults(Vector v, LDAPConnection conn, LDAPSearchConstraints cons,
String base, int scope, String filter, String[] attrs, boolean attrsOnly) {
LDAPSearchResults(Vector v, LDAPConnection conn,
LDAPSearchConstraints cons,
String base, int scope, String filter,
String[] attrs, boolean attrsOnly) {
this(v);
currConn = conn;
currCons = cons;
@ -124,8 +128,7 @@ public class LDAPSearchResults implements Enumeration {
void add( LDAPMessage msg ) {
if (msg instanceof LDAPSearchResult) {
entries.addElement( ((LDAPSearchResult)msg).getEntry());
}
else if (msg instanceof LDAPSearchResultReference) {
} else if (msg instanceof LDAPSearchResultReference) {
/* convert to LDAPReferralException */
String urls[] = ((LDAPSearchResultReference)msg).getUrls();
if (urls != null) {
@ -190,22 +193,24 @@ public class LDAPSearchResults implements Enumeration {
*/
void quicksort (LDAPEntry[] toSort, LDAPEntryComparator compare,
int low, int high) {
if (low >= high)
if (low >= high) {
return;
}
LDAPEntry pivot = toSort[low];
int slow = low-1, shigh = high+1;
while (true) {
do
do {
shigh--;
while (compare.isGreater (toSort[shigh], pivot));
do
} while (compare.isGreater (toSort[shigh], pivot));
do {
slow++;
while (compare.isGreater (pivot, toSort[slow]));
} while (compare.isGreater (pivot, toSort[slow]));
if (slow >= shigh)
if (slow >= shigh) {
break;
}
LDAPEntry temp = toSort[slow];
toSort[slow] = toSort[shigh];
@ -277,26 +282,31 @@ public class LDAPSearchResults implements Enumeration {
// if automatic referral, then add to the entries, otherwise, dont do it
// since the elements in referralResults are LDAPReferralException.
if (currCons.getReferrals())
if (currCons.getReferrals()) {
while (referralResults.size() > 0) {
Object obj = null;
if ((obj=nextReferralElement()) != null)
if ((obj=nextReferralElement()) != null) {
entries.addElement(obj);
}
}
}
int numEntries = entries.size();
if (numEntries <= 0)
if (numEntries <= 0) {
return;
}
LDAPEntry[] toSort = new LDAPEntry[numEntries];
entries.copyInto (toSort);
if (toSort.length > 1)
if (toSort.length > 1) {
quicksort (toSort, compare, 0, numEntries-1);
}
entries.removeAllElements();
for (int i = 0; i < numEntries; i++)
for (int i = 0; i < numEntries; i++) {
entries.addElement (toSort[i]);
}
}
/**
@ -338,10 +348,12 @@ public class LDAPSearchResults implements Enumeration {
public LDAPEntry next() throws LDAPException {
Object o = nextElement();
if ((o instanceof LDAPReferralException) ||
(o instanceof LDAPException))
(o instanceof LDAPException)) {
throw (LDAPException)o;
if (o instanceof LDAPEntry)
}
if (o instanceof LDAPEntry) {
return (LDAPEntry)o;
}
return null;
}
@ -405,11 +417,12 @@ public class LDAPSearchResults implements Enumeration {
return obj;
}
if ((obj == null) || (!res.hasMoreElements()))
if ((obj == null) || (!res.hasMoreElements())) {
referralResults.removeElementAt(0);
}
else
}
} else {
referralResults.removeElementAt(0);
}
return null;
}
@ -434,8 +447,9 @@ public class LDAPSearchResults implements Enumeration {
*/
public boolean hasMoreElements() {
while ((entries.size() == 0) && (!searchComplete))
while ((entries.size() == 0) && (!searchComplete)) {
fetchResult();
}
if ((entries.size() == 0) &&
((exceptions == null) || (exceptions.size() == 0))) {
@ -454,25 +468,31 @@ public class LDAPSearchResults implements Enumeration {
}
/**
* Returns a count of the entries in the search results.
* @return count of entries found by the search.
* Returns a count of queued search results immediately available for
* processing.
* A search result is either a search entry or an exception. If the
* search is asynchronous (batch size not 0), this reports the number
* of results received so far.
* @return count of search results immediatly available for processing
*/
public int getCount() {
int totalReferralEntries = 0;
int count = 0;
for (int i=0; i<referralResults.size(); i++) {
int count = entries.size();
for ( int i = 0; i < referralResults.size(); i++ ) {
LDAPSearchResults res =
(LDAPSearchResults)referralResults.elementAt(i);
totalReferralEntries = totalReferralEntries+res.getCount();
(LDAPSearchResults)referralResults.elementAt(i);
count += res.getCount();
}
if ( resultSource != null ) {
count += resultSource.getMessageCount();
}
if (resultSource != null) {
count = resultSource.getMessageCount();
} else {
count = entries.size();
}
if (exceptions != null)
return (count + exceptions.size() + totalReferralEntries);
return (count + totalReferralEntries);
if ( exceptions != null ) {
count += exceptions.size();
}
return count;
}
/**
@ -480,8 +500,9 @@ public class LDAPSearchResults implements Enumeration {
* @return Message ID.
*/
int getMessageID() {
if ( resultSource == null )
if ( resultSource == null ) {
return -1;
}
return resultSource.getMessageID();
}
@ -493,8 +514,7 @@ public class LDAPSearchResults implements Enumeration {
/* Asynchronous case */
if ( resultSource != null ) {
synchronized( this ) {
if (searchComplete || firstResult)
{
if (searchComplete || firstResult) {
firstResult = false;
return;
}

View File

@ -26,7 +26,8 @@ package netscape.ldap;
*
* @version 1.0
*/
public class LDAPSortKey {
public class LDAPSortKey implements java.io.Serializable {
static final long serialVersionUID = -7044232342344864405L;
public final static int REVERSE = 0x81;
/**

View File

@ -0,0 +1,177 @@
/* -*- 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) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
package netscape.ldap;
import java.util.*;
/**
* The definition of a syntax type in the schema.
* <A HREF="http://www.ietf.org/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol (v3):
* LDAP Subschema Attribute</A> covers the types of information
* to specify when defining a syntax.
* The description of a syntax can include the following:
* <P>
*
* <UL>
* <LI>an OID identifying the syntax
* <LI>a description of the attribute type
* </UL>
* <P>
*
* When you construct an <CODE>LDAPSyntaxSchema</CODE> object, you can
* specify these types of information as arguments to the constructor or
* in the ldapSyntaxes format specified in RFC 2252.
* When an LDAP client searches an LDAP server for the schema, the server
* returns schema information as an object with attribute values in this
* format.
* <P>
* RFC 2252 defines SyntaxDescription as follows:
* <P>
* <PRE>
* SyntaxDescription = "(" whsp
* numericoid whsp
* [ "DESC" qdstring ]
* whsp ")"
* </PRE>
*<P>
* Syntax definitions do not have a name, so the <CODE>getName</CODE>
* method inherited from <CODE>LDAPSchemaElement</CODE> returns "".
* To get the OID and description of this syntax type
* definition, use the <CODE>getOID</CODE> and
* <CODE>getDescription</CODE> methods inherited from the abstract class
* <CODE>LDAPSchemaElement</CODE>.
* <P>
*
* To add or remove this syntax type definition from the
* schema, use the <CODE>add</CODE> and <CODE>remove</CODE>
* methods, which this class inherits from the <CODE>LDAPSchemaElement</CODE>
* abstract class.
*
* @version 1.0
* @see netscape.ldap.LDAPSchemaElement
**/
public class LDAPSyntaxSchema extends LDAPSchemaElement {
static final long serialVersionUID = 3590667117475688132L;
/**
* Constructs a blank element.
*/
protected LDAPSyntaxSchema() {
super();
}
/**
* Constructs a syntax type definition, using the specified
* information.
* @param oid object identifier (OID) of the syntax type
* in dotted-string format (for example, "1.2.3.4")
* @param description description of syntax type
*/
public LDAPSyntaxSchema( String oid, String description ) {
super( "", oid, description );
attrName = "ldapSyntaxes";
syntaxElement.syntax = syntaxElement.syntaxCheck( oid );
syntaxElement.syntaxString = oid;
}
/**
* Constructs a syntax type definition based on a description in
* the ldapSyntaxes format. For information on this format,
* (see <A HREF="http://www.ietf.org/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol (v3):
* LDAP Subschema Attribute</A>. This is the format that LDAP servers
* and clients use to exchange schema information. (For example, when
* you search an LDAP server for its schema, the server returns an entry
* with the syntaxs "objectclasses" and "ldapSyntaxes". The
* values of "ldapSyntaxes" are syntax type descriptions
* in this format.)
* <P>
*
* @param raw definition of the syntax type in the
* ldapSyntaxes format
*/
public LDAPSyntaxSchema( String raw ) {
attrName = "ldapSyntaxes";
parseValue( raw );
}
/**
* Gets the syntax of the schema element
* @return one of the following values:
* <UL>
* <LI><CODE>cis</CODE> (case-insensitive string)
* <LI><CODE>ces</CODE> (case-exact string)
* <LI><CODE>binary</CODE> (binary data)
* <LI><CODE>int</CODE> (integer)
* <LI><CODE>telephone</CODE> (telephone number -- identical to cis,
* but blanks and dashes are ignored during comparisons)
* <LI><CODE>dn</CODE> (distinguished name)
* <LI><CODE>unknown</CODE> (not a known syntax)
* </UL>
*/
public int getSyntax() {
return syntaxElement.syntax;
}
/**
* Gets the syntax of the syntax type in dotted-decimal format,
* for example "1.2.3.4.5"
* @return The syntax syntax in dotted-decimal format.
*/
public String getSyntaxString() {
return syntaxElement.syntaxString;
}
/**
* Prepares a value in RFC 2252 format for submission to a server
*
* @return a String ready for submission to an LDAP server.
*/
public String getValue() {
String s = getValuePrefix();
String val = getCustomValues();
if ( val.length() > 0 ) {
s += val + ' ';
}
s += ')';
return s;
}
/**
* Gets the definition of the syntax type in a user friendly format.
* This is the format that the syntax type definition uses when
* printing the syntax type or the schema.
* @return definition of the syntax type in a user friendly format.
*/
public String toString() {
String s = "OID: " + oid;
s += "; Description: " + description;
s += getQualifierString( null );
return s;
}
protected LDAPSyntaxSchemaElement syntaxElement =
new LDAPSyntaxSchemaElement();
}

View File

@ -33,6 +33,9 @@ import java.util.*;
**/
class LDAPSyntaxSchemaElement extends LDAPSchemaElement {
static final long serialVersionUID = 6086340702503710702L;
/**
* Construct a blank element.
*/

View File

@ -0,0 +1,59 @@
/* -*- 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) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
package netscape.ldap;
/**
* The <CODE>LDAPTraceWriter</CODE> interface enables logging of LDAP
* trace messages in environments where an OutputStream can not be used.
* <P>
* The interface is primarily meant for integrating LDAP tracing with the
* servlet log facility:
* <P>
* <PRE>
* servletCtx = config.getServletContext();
* ...
* LDAPConnection ld = new LDAPConnection();
* ld.setProperty(ld.TRACE_PROPERTY,
* new LDAPTraceWriter() {
* public void write (String msg) {
* servletCtx.log(msg);
* }
* });
* <PRE>
* <P>
*
* @version 1.0
* @see netscape.ldap.LDAPConnection#setProperty(java.lang.String, java.lang.Object)
*/
public interface LDAPTraceWriter {
/**
* Writes an LDAP trace message.
*
* @param msg An incoming or outgoing LDAP message
*
* @version 1.0
* @see netscape.ldap.LDAPConnection#setProperty(java.lang.String, java.lang.Object)
*/
public void write (String msg);
}

View File

@ -31,7 +31,7 @@ import java.net.MalformedURLException;
* TARGET="_blank">RFC 1959</A>. LDAP URLs have the following format:
*
* <PRE>
* "ldap://" [ <I>hostName</I> [":" <I>portNumber</I>] ] "//"
* "ldap://" [ <I>hostName</I> [":" <I>portNumber</I>] ] "/"
* <I>distinguishedName</I>
* ["?" <I>attributeList</I> ["?" <I>scope</I>
* "?" <I>filterString</I> ] ]
@ -77,8 +77,9 @@ import java.net.MalformedURLException;
*
* @version 1.0
*/
public class LDAPUrl {
public class LDAPUrl implements java.io.Serializable {
static final long serialVersionUID = -3245440798565713640L;
public static String defaultFilter = "(objectClass=*)";
private String hostName;
@ -95,106 +96,144 @@ public class LDAPUrl {
* @exception MalformedURLException failed to parse URL
*/
public LDAPUrl (String url) throws java.net.MalformedURLException {
StringTokenizer urlParser = new StringTokenizer (url, ":/?", true);
String currentToken;
String attributeList = null;
attributes = null;
scope = LDAPv2.SCOPE_BASE;
filter = defaultFilter;
URL = url;
try {
currentToken = urlParser.nextToken();
if (!currentToken.equalsIgnoreCase ("LDAP"))
throw new MalformedURLException ();
parseUrl(url);
}
urlParser.nextToken(); // ":"
urlParser.nextToken(); // "/"
urlParser.nextToken(); // "/"
/**
* Parse URL as defined in RFC 1959
*/
private void parseUrl(String url) throws MalformedURLException {
StringTokenizer urlParser = new StringTokenizer (url, ":/?", true);
String currentToken;
String str = null;
currentToken = urlParser.nextToken();
currentToken = urlParser.nextToken();
if (!currentToken.equalsIgnoreCase ("LDAP"))
throw new MalformedURLException ();
if (currentToken.equals ("/")) {
hostName = null;
portNumber = LDAPv2.DEFAULT_PORT;
} else {
hostName = currentToken;
if (urlParser.countTokens() == 0) {
portNumber = LDAPv2.DEFAULT_PORT;
return;
}
currentToken = urlParser.nextToken (); // either ":" or "/"
if (currentToken.equals (":")) {
portNumber = Integer.parseInt (urlParser.nextToken());
if (urlParser.countTokens() == 0) {
return;
}
urlParser.nextToken (); // "/"
} else
portNumber = LDAPv2.DEFAULT_PORT;
}
if (urlParser.countTokens() == 0)
return;
DN = decode (urlParser.nextToken ());
// it retrieves the ? token, meaning no DN is supplied
if (DN.equals("?"))
DN = "";
else if (DN.equals("/"))
throw new MalformedURLException ();
if (urlParser.hasMoreTokens ()) {
// we have a "?attributeList" portion
String str = null;
str = readNextConstruct(urlParser);
// if attribute
if ((str != null) && (isAttribute(str))) {
// it retrieves the ? token, meaning no attribute is supplied
if (str.equals("?")) {
attributeList = null;
str = urlParser.nextToken();
}
else {
attributeList = decode(str);
str = readNextConstruct(urlParser);
}
}
// if scope
if ((str != null) && ((scope = getScope(str)) != -1))
str = readNextConstruct(urlParser);
// no scope is supplied
else if ((str != null) && (str.equals("?"))) {
scope = LDAPv2.SCOPE_BASE;
str = urlParser.nextToken();
} else {
scope = LDAPv2.SCOPE_BASE;
}
// if filter
if ((str != null) && (isFilter(str))) {
filter = decode(str);
str = readNextConstruct(urlParser);
}
}
} catch (NumberFormatException nf) {
currentToken = urlParser.nextToken();
if (!currentToken.equals(":")) {
throw new MalformedURLException ();
}
currentToken = urlParser.nextToken();
if (!currentToken.equals("/")) {
throw new MalformedURLException ();
}
currentToken = urlParser.nextToken();
if (!currentToken.equals("/")) {
throw new MalformedURLException ();
}
if (attributeList != null) {
currentToken = urlParser.nextToken();
if (currentToken.equals ("/")) {
hostName = null;
portNumber = LDAPv2.DEFAULT_PORT;
} else {
hostName = currentToken;
if (urlParser.countTokens() == 0) {
portNumber = LDAPv2.DEFAULT_PORT;
return;
}
currentToken = urlParser.nextToken (); // either ":" or "/"
if (currentToken.equals (":")) {
try {
portNumber = Integer.parseInt (urlParser.nextToken());
} catch (NumberFormatException nf) {
throw new MalformedURLException ();
}
if (urlParser.countTokens() == 0) {
return;
}
urlParser.nextToken (); // "/"
} else
portNumber = LDAPv2.DEFAULT_PORT;
}
// DN
if (!urlParser.hasMoreTokens ()) {
return;
}
DN = decode(readNextConstruct(urlParser));
if (DN.equals("?")) {
DN = "";
}
else if (DN.equals("/")) {
throw new MalformedURLException ();
}
// attribute
if (!urlParser.hasMoreTokens ()) {
return;
}
str = readNextConstruct(urlParser);
if (!str.equals("?")) {
StringTokenizer attributeParser = new
StringTokenizer (attributeList, ", ");
StringTokenizer (decode(str), ", ");
attributes = new Vector ();
while (attributeParser.hasMoreTokens())
while (attributeParser.hasMoreTokens()) {
attributes.addElement (attributeParser.nextToken());
}
}
// scope
if (!urlParser.hasMoreTokens ()) {
return;
}
str = readNextConstruct(urlParser);
if (!str.equals("?")) {
scope = getScope(str);
if (scope < 0) {
throw new MalformedURLException("Bad scope:" + str);
}
}
// filter
if (!urlParser.hasMoreTokens ()) {
return;
}
str = readNextConstruct(urlParser);
filter = decode(str);
checkBalancedParentheses(filter);
if (!filter.startsWith("(") && !filter.endsWith(")")) {
filter = "(" + filter + ")";
}
// Nothing after the filter is allowed
if (urlParser.hasMoreTokens()) {
throw new MalformedURLException();
}
}
private void checkBalancedParentheses(String filter) throws MalformedURLException {
int parenCnt =0;
StringTokenizer filterParser = new StringTokenizer (filter, "()", true);
while (filterParser.hasMoreElements()) {
String token = filterParser.nextToken();
if (token.equals("(")) {
parenCnt++;
}
else if (token.equals(")")) {
if (--parenCnt < 0) {
throw new MalformedURLException("Unbalanced filter parentheses");
}
}
}
if (parenCnt != 0) {
throw new MalformedURLException("Unbalanced filter parentheses");
}
}
/**
* Constructs with the specified host, port, and DN. This form is used to
* create URL references to a particular object in the directory.
@ -441,34 +480,6 @@ public class LDAPUrl {
return URL;
}
/**
* Checks if the given string is a filter expression.
* @param the string which is checked
* @return <code>true</code> if the given string is a filter expression; otherwise,
* <code>false</code>.
*/
private boolean isFilter(String str) {
if (str.startsWith("("))
return true;
else
return false;
}
/**
* Checks if the given string is an attribute expression.
* @param the string which is checked
* @return <code>true</code> if the given string is an attribute expression; otherwise,
* <code>false</code>.
*/
private boolean isAttribute(String str) {
if ((!str.startsWith("(")) && (!str.equalsIgnoreCase("base")) &&
(!str.equalsIgnoreCase("one")) && (!str.equalsIgnoreCase("sub")))
return true;
else
return false;
}
/**
* Reads next construct from the given string parser.
* @param parser the string parser
@ -481,8 +492,19 @@ public class LDAPUrl {
try {
if (parser.hasMoreTokens()) {
parser.nextToken(); // "?"
return parser.nextToken();
String tkn = parser.nextToken();
if (tkn.equals("?")) { // empty construct
return tkn;
}
else if (parser.hasMoreTokens()){
// Remove '?' delimiter
String delim = parser.nextToken();
if (!delim.equals("?")) {
throw new MalformedURLException();
}
}
return tkn;
}
} catch (NoSuchElementException e) {
throw new MalformedURLException();

View File

@ -95,6 +95,9 @@ public abstract class JDAPFilter {
f.trim();
if (f.startsWith("&")) { /* and */
JDAPFilter filters[] = getFilterList(f.substring(1, f.length()));
if (filters == null) {
throw new IllegalArgumentException("Bad search filter");
}
JDAPFilterAnd and = new JDAPFilterAnd();
for (int i = 0; i < filters.length; i++) {
and.addElement(filters[i]);
@ -102,13 +105,20 @@ public abstract class JDAPFilter {
return and;
} else if (f.startsWith("|")) { /* or */
JDAPFilter filters[] = getFilterList(f.substring(1, f.length()));
if (filters == null) {
throw new IllegalArgumentException("Bad search filter");
}
JDAPFilterOr or = new JDAPFilterOr();
for (int i = 0; i < filters.length; i++) {
or.addElement(filters[i]);
}
return or;
} else if (f.startsWith("!")) { /* not */
return new JDAPFilterNot(getFilter(f.substring(1, f.length())));
JDAPFilter filter = getFilter(f.substring(1, f.length()));
if (filter == null) {
throw new IllegalArgumentException("Bad search filter");
}
return new JDAPFilterNot(filter);
} else { /* item */
return getFilterItem(f.substring(0, f.length()));
}

View File

@ -74,17 +74,19 @@ class JDAPFilterOpers {
return null;
}
String hex = "0x"+val.substring(pos+1, pos+3);
Integer num = null;
// decode this number to integer, exception thrown when this is not the
// hex
try {
String hex = "0x"+val.substring(pos+1, pos+3);
num = Integer.decode(hex);
} catch (IndexOutOfBoundsException e) {
printDebug(e.toString());
throw new IllegalArgumentException("Bad search filter");
} catch (NumberFormatException e) {
printDebug(e.toString());
return null;
throw new IllegalArgumentException("Bad search filter");
}
byte[] b = {(byte)num.intValue()};

View File

@ -0,0 +1,94 @@
/* -*- 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) 2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
package netscape.ldap.factory;
import java.net.*;
import java.io.*;
import javax.net.ssl.*;
import netscape.ldap.*;
import com.sun.net.ssl.*;
/**
* Creates an SSL socket connection to a server, using the JSSE package
* from Sun. This class implements the <CODE>LDAPSocketFactory</CODE>
* interface.
* <P>
*
* @version 1.0
* @see LDAPSocketFactory
* @see LDAPConnection#LDAPConnection(netscape.ldap.LDAPSocketFactory)
*/
public class JSSESocketFactory
implements LDAPSocketFactory, java.io.Serializable {
static final long serialVersionUID = 6834205777733266609L;
// Optional explicit cipher suites to use
private String[] suites;
/**
* Factory constructor
*
* @param suites Cipher suites to attempt to use with the server;
* if <code>null</code>, use any cipher suites available in the
* JSSE package
*/
public JSSESocketFactory( String[] suites ) {
this.suites = suites;
}
/**
* Creates an SSL socket
*
* @param host Host name or IP address of SSL server
* @param port Port numbers of SSL server
* @return A socket for an encrypted session
* @exception LDAPException on error creating socket
*/
public Socket makeSocket(String host, int port)
throws LDAPException {
SSLSocket sock = null;
try {
SSLSocketFactory factory =
(SSLSocketFactory)SSLSocketFactory.getDefault();
sock = (SSLSocket)factory.createSocket(host, port);
if (suites != null) {
sock.setEnabledCipherSuites(suites);
sock.startHandshake();
}
} catch (UnknownHostException e) {
throw new LDAPException("SSL connection to " + host +
":" + port,
LDAPException.CONNECT_ERROR);
} catch (IOException f) {
throw new LDAPException("SSL connection to " + host +
":" + port,
LDAPException.CONNECT_ERROR);
}
return sock;
}
}

View File

@ -213,6 +213,9 @@ public class DSMLWriter extends LDAPWriter {
* @param dn the DN of the entry
*/
protected void printEntryStart( String dn ) {
if ( dn == null ) {
dn = "";
}
printString( " <dsml:entry dn=\"" + dn + "\">" );
}

View File

@ -133,6 +133,18 @@ public class LDIFWriter extends LDAPWriter {
* @param dn the DN of the entry
*/
protected void printEntryStart( String dn ) {
if ( dn == null ) {
dn = "";
} else {
byte[] b = null;
try {
b = dn.getBytes( "UTF8" );
} catch ( UnsupportedEncodingException ex ) {
}
if ( !LDIF.isPrintable(b) ) {
dn = getPrintableValue( b );
}
}
printString( "dn" + m_sep + " " + dn );
}

View File

@ -229,9 +229,8 @@ public final class RDN implements java.io.Serializable {
* @param rdn the DN component to compare against the
* current DN component.
* @return <code>true</code> if the two DN components are equal.
* @see netscape.ldap.util.RDN#registerCesAttribute
* @see netscape.ldap.util.RDN#cesAttributeIsRegistered
* @see netscape.ldap.util.RDN#getRegisteredCesAttributes
* @see netscape.ldap.util.RDN#registerAttributeSyntax
* @see netscape.ldap.util.RDN#getAttributeSyntax
*/
public boolean equals(RDN rdn) {
String[] this_types = (String[])getTypes().clone();

View File

@ -2,54 +2,212 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.7 [en] (WinNT; I) [Netscape]">
<meta name="GENERATOR" content="Mozilla/4.72 [en] (WinNT; I) [Netscape]">
<meta name="Author" content="Jacob Rosenschein">
<meta name="Description" content="Release Notes for version 4.0 of the Netscape Directory SDK 4.0 for Java">
<meta name="Description" content="Release Notes for version 4.1 of the Directory SDK for Java">
<meta name="KeyWords" content="Java SDK, Directory SDK, LDAP SDK, SDK, LDAP, Directory, Netscape Directory, Netscape SDK, Java LDAP SDK">
<title>Directory SDK 4.0 for Java Source Code Release Notes</title>
<title>Directory SDK 4.1 for Java Source Code Release Notes</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
<center>
<h2>
<font face="Arial,Helvetica">Netscape Directory SDK 4.0 for Java Source
Code Release Notes</font></h2></center>
<font face="Arial,Helvetica">Directory SDK 4.1 for Java Source Code Release
Notes</font></h2></center>
<center>Last Updated September 13, 1999</center>
<center>Last Updated May 06, 2000</center>
<p>These release notes contain information about:
<ul>
<li>
<a href="#new41">What's New in Version 4.1</a></li>
<li>
<a href="#fixed40">Bugs Fixed Since Version 4.0</a></li>
<li>
<a href="#new">What's New in Version 4.0</a></li>
<li>
<a href="#fixed305">Bugs Fixed Since Version 3.05</a></li>
<li>
<a href="#install">Downloading and Building the Source</a></li>
<li>
<a href="#update">Updating Java Classes in Netscape Communicator</a></li>
<li>
<a href="#fixed">Bugs Fixed Since Version 3.05</a></li>
<li>
<a href="#report">Reporting Problems</a></li>
<li>
<a href="#newsgroup">Accessing the Directory Developers Newsgroup</a></li>
</ul>
For the latest documentation, see the <i><a href="http://developer.netscape.com/docs/manuals/dirsdk/jsdk40/contents.htm" TARGET="_top">Netscape
For the latest documentation, see the <i><a href="http://developer.iplanet.com/docs/manuals/dirsdk/jsdk40/contents.htm" TARGET="_top">Netscape
Directory SDK 4.0 for Java Programmer's Guide</a></i>, which is available
on Netscape DevEdge Online.
<p>Reference materials for the Directory SDK 4.0 for Java are produced
on the iPlanet Developer Documentation site.
<p>Reference materials for the Directory SDK 4.x for Java are produced
using the Javadoc utility. They are available in the <tt>/dist/doc/</tt>
directory where you installed the SDK or online at: <tt><a href="http://developer.netscape.com/docs/manuals/dirsdk/jsdk40/Reference/index.html">http://developer.netscape.com/docs/manuals/dirsdk/jsdk40/Reference/index.html</a></tt>.
<p>If you only want the Netscape Directory SDK 4.0 for Java (not the source
code), you can dowload it from Netscape <a href="http://developer.netscape.com/tech/directory/downloads.html">DevEdge</a>.
directory where you installed the SDK or online at:
<br><tt><a href="http://developer.iplanet.com/docs/manuals/dirsdk/jsdk40/Reference/index.html">http://developer.iplanet.com/docs/manuals/dirsdk/jsdk40/Reference/index.html</a>.</tt>
<p>If you only want the Directory SDK 4.x for Java (not the source code),
you can download it from the <a href="http://www.iplanet.com/downloads/developer/index.html">iPlanet
Developer Downloads</a> site.
<p>
<hr SIZE=1 NOSHADE WIDTH="100%"><a NAME="new"></a><b><font face="Arial,Helvetica"><font size=+1>What's
<hr SIZE=1 NOSHADE WIDTH="100%">
<br><a NAME="new41"></a><b><font face="Arial,Helvetica"><font size=+1>What's
New in Version 4.1</font></font></b>
<p>The Directory SDK 4.1 for Java is a bug fix relase. Please check the
list of <a href="#fixed40">Bugs Fixed Since Version 4.0</a>. The following
new features have been added in this release:
<ul>
<li>
A new class, <tt>netscape.ldap.factory.JSSESocketFactory</tt>. It implements
the <tt>LDAPSocketFactory</tt> interface using the Java Secure Socket Extension
(JSSE)&nbsp; intefaces as the SSL provider. A JSSE implementation is not
packaged with the Directory SDK classes; you will need to have one in your
CLASSPATH to be able to use <tt>JSSESocketFactory</tt>.&nbsp; A reference
implementation of JSSE interfaces is available at <a href="http://java.sun.com/products/jsse/">http://java.sun.com/products/jsse/</a>.</li>
<li>
A new interface,&nbsp; <tt>netscape.ldap.LDAPTraceWriter,</tt> enables
logging of LDAP trace messages in environments where an <tt>OutputStream</tt>
cannot be used. The interface is meant primarily for integrating LDAP tracing
with the servlet log facility.</li>
<li>
A new method <tt>setConnectTimeout() </tt>has been added to <tt>LDAPConnection.
</tt>This
method allows you to limit&nbsp; the amount of time that application code
waits for <tt>LDAPConnection.connnect() </tt>to establish a connection.
By setting the connect timeout, an application can avoid blocking for a
long period of time when a Directory Server host is down or unreachable.</li>
<li>
All base classes in the <tt>netscape.ldap</tt> and <tt>netscape.ldap.util</tt>
package are now serializable.</li>
</ul>
<hr SIZE=1 NOSHADE WIDTH="100%">
<br><a NAME="fixed40"></a><b><font face="Arial,Helvetica"><font size=+1>Bugs
Fixed Since Version 4.0</font></font></b>
<p>The following bugs have been fixed since the release of the Directory
SDK 4.0 for Java. iPlanet bug numbers are shown in parentheses.
<ul>
<li>
Bugzilla <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=28001">28001</a>:
Parsing in <tt>LDAPUrl(String url)</tt> ignores attributes if DN is empty.</li>
<li>
Bugzilla <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=28005">28005</a>:
Exceptions thrown in <tt>connect()</tt> and <tt>disconnect()</tt>.</li>
<li>
Bugzilla <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=13546">13546</a>:
<tt>JDAPFilterOpers</tt>
throws StringIndexOutOfBoundsException.</li>
<li>
Bugzilla <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=16514">16514</a>:
<tt>LDAPAttributeSet.removeElementAt()</tt>
doesn't remove the attribute completely.</li>
<li>
Bugzilla <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=34326">34326:</a><tt>
LDAPDN.unEscapeRDN()</tt> removes all /'s - not just the escape characters.</li>
<li>
Bugzilla <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=29262">29262:</a><tt>
LDAPSearch</tt> doesn't apply base64-encoding to to nonprintable DNs.</li>
<li>
Wrong user DN supplied for referral on bind operation. (364869)</li>
<li>
4.0 LDAPMatchingRuleSchema not binary compatible with 3.x.&nbsp; (365423)</li>
<li>
LDAP JDK does not properly abandon operation. (341439)</li>
<li>
<tt>RDN.equals()</tt> assumes case-insensitivity, ignores multiple values.
(365574)</li>
<li>
<tt>authenticate()</tt> with bad password does not throw exception. (366578)</li>
<li>
Should provide DSML option for LDAPSearch. (368416)</li>
<li>
Incorrect signature for <tt>LDAPResponseListener.merge()</tt>. (364775)</li>
<li>
MS JVM throws <tt>LDAPSortControl</tt> runtime exception. (365574)</li>
<li>
Need new method <tt>LDAPDN.equals( String dn1, String dn2)</tt>. (365575)</li>
<li>
Some 3.x <tt>LDAPSchema</tt> public methods are protected in 4.x. (381574)</li>
<li>
Server using VLV for non-search operations - 'Critical extension unavailable'
error in log. (382605)</li>
<li>
<tt>LDAPSearchResults.getCount()</tt> returns wrong count. (355336)</li>
<li>
<tt>LDAPCache.cleanup()</tt> throws NullPointerException. (388736)</li>
<li>
<tt>LDAPConnection.read()</tt> doesn't return subentries (387722)</li>
<li>
LDAP SDK 4.0 causes NAS crash. (390128)</li>
<li>
NullPointerException in <tt>deleteThreadConnEntry()</tt>. (389228)</li>
<li>
<tt>LDAPSchema.getSyntaxes()</tt> missing (I-D conformance). (388463)</li>
<li>
SASL bugs found at CMU. (391585)</li>
<li>
<tt>LDAPCompareAttrNames</tt> not consistently case-sensitive. (390382)</li>
<li>
<tt>LDAPEntry</tt> throws a null exception when reading non existing attribute
(388577)</li>
<li>
NullPointerException with Malformed Filter. (390249)</li>
<li>
LDAP objects not really serializable. (356821)</li>
<li>
<tt>LDAPSearch -l</tt> option does not work correctly (393676)</li>
<li>
NullPointerException in <tt>LDAPSearch</tt> (387453)</li>
<li>
<tt>java-object-schema.conf</tt> is not packaged with SDK. (390154)</li>
<li>
JNDI SP: <tt>LdapContextImpl.reconnect(null)</tt> throw null pointer exceptions
(383788)</li>
</ul>
<hr SIZE=1 NOSHADE WIDTH="100%">
<p><a NAME="new"></a><b><font face="Arial,Helvetica"><font size=+1>What's
New in Version 4.0</font></font></b>
<p>The Netscape Directory SDK 4.0 for Java provides programmers with the
tools to develop directory-enabled software.&nbsp; This release includes:
<p>The Directory SDK 4.0 for Java provides programmers with the tools to
develop directory-enabled software.&nbsp; This release includes:
<ul>
<li>
Application Program Interface (API) updates to match the newest LDAP (Lightweight
@ -62,15 +220,13 @@ an asynchronous interface to LDAP</li>
a new SASL (Simple Authentication and Security Layer) API</li>
<li>
the Netscape LDAP Service Provider for JNDI (Java Naming and Directory
Interface).</li>
the Netscape LDAP Service Provider for LDAP.</li>
</ul>
Additional improvements and changes to the Directory SDK are listed under
<a href="#fixed">Bugs
<a href="#fixed305">Bugs
Fixed Since Version 3.05</a>.
<p><b><font face="Arial,Helvetica">API updates</font></b>
<p>The Netscape Directory SDK 4.0 for Java supports these changes to the
LDAP API:
<p>The Directory SDK 4.0 for Java supports these changes to the LDAP API:
<ul>
<li>
Sophisticated client-side management of referral authentication using the
@ -129,7 +285,7 @@ using different credentials, without rebinding.</li>
to call <tt>System.exit</tt> when terminating your program.</li>
</ul>
<b><font face="Arial,Helvetica">Asynchronous API</font></b>
<p>The Netscape Directory SDK 4.0 for Java provides an interface called
<p>The Directory SDK 4.0 for Java provides an interface called
<tt>LDAPAsynchronousConnection</tt>.
This interface contains methods for performing LDAP operations asynchronously.
Instead of blocking while waiting for a response, methods in <tt>LDAPAsynchronousConnection</tt>
@ -170,46 +326,8 @@ For more information see "<a href="http://developer.netscape.com/docs/manuals/di
the JNDI Service Provider</a>" in the <i><a href="http://developer.netscape.com/docs/manuals/dirsdk/jsdk40/contents.htm">Netscape
Directory SDK 4.0 for Java Programmer's Guide</a></i>.
<p>
<hr SIZE=1 NOSHADE WIDTH="100%"><a NAME="install"></a><b><font face="Arial,Helvetica"><font size=+1>Downloading
and Building the Source</font></font></b>
<p>The Directory SDK source code is available on the Mozilla website. You
can download it at <a href="http://www.mozilla.org/directory/javasdk.html">http://www.mozilla.org/directory/javasdk.html</a>.
<p>Follow the instructions at <a href="http://www.mozilla.org/directory/buildjsdk-4.0.txt">http://www.mozilla.org/directory/buildjsdk-4.0.txt</a>
to build the Netscape Directory SDK.
<p>
<hr SIZE=1 NOSHADE WIDTH="100%"><a NAME="update"></a><b><font face="Arial,Helvetica"><font size=+1>Updating
Java Classes in Netscape Communicator</font></font></b>
<p>The LDAP Java classes contained in Netscape Communicator 4.7 and earlier
are outdated. You can upgrade these class files to the latest versions
using Communicator's SmartUpdate feature.
<p>The SmartUpdate page for the LDAP Java classes is at: <a href="http://developer.netscape.com/software/ldap/ldap.html">http://developer.netscape.com/software/ldap/ldap.html</a>
<p><b>Note: </b>This page uses Communicator's SmartUpdate feature to update
the classes. Before visiting this page, you must enable SmartUpdate, Java,
JavaScript, and cookies in Communicator.
<p><b><font face="Arial,Helvetica">To enable SmartUpdate, Java, JavaScript,
and cookies:</font></b>
<ul>
<li>
Go to the Edit menu and choose Preferences.</li>
<li>
Select Advanced and make sure that Accept all cookies is active (it's radio
button is filled).</li>
<li>
Make sure that Enable Java and Enable JavaScript are checked.</li>
<li>
Choose Advanced | SmartUpdate from the left-hand panel.</li>
<li>
Make sure that Enable SmartUpdate is checked.</li>
<li>
Click OK.</li>
</ul>
<hr SIZE=1 NOSHADE WIDTH="100%"><a NAME="fixed"></a><b><font face="Arial,Helvetica"><font size=+1>Bugs
<hr SIZE=1 NOSHADE WIDTH="100%">
<p><a NAME="fixed305"></a><b><font face="Arial,Helvetica"><font size=+1>Bugs
Fixed Since Version 3.05</font></font></b>
<p>The following bugs have been fixed since the release of the Directory
SDK 3.05 for Java. Bug numbers are shown in parentheses.
@ -286,6 +404,46 @@ The SDK should treat a <tt>"null"</tt> filter as meaning <tt>"objectclass=*"</tt
(354997)</li>
</ul>
<hr SIZE=1 NOSHADE WIDTH="100%">
<br><a NAME="install"></a><b><font face="Arial,Helvetica"><font size=+1>Downloading
and Building the Source</font></font></b>
<p>The Directory SDK source code is available on the Mozilla website. You
can download it at <a href="http://www.mozilla.org/directory/javasdk.html">http://www.mozilla.org/directory/javasdk.html</a>.
<p>Follow the instructions at <a href="http://www.mozilla.org/directory/buildjsdk-4.0.txt">http://www.mozilla.org/directory/buildjsdk-4.0.txt</a>
to build the Netscape Directory SDK.
<p>
<hr SIZE=1 NOSHADE WIDTH="100%"><a NAME="update"></a><b><font face="Arial,Helvetica"><font size=+1>Updating
Java Classes in Netscape Communicator</font></font></b>
<p>The LDAP Java classes contained in Netscape Communicator 4.7 and earlier
are outdated. You can upgrade these class files to the latest versions
using Communicator's SmartUpdate feature.
<p>The SmartUpdate page for the LDAP Java classes is at: <a href="http://developer.netscape.com/software/ldap/ldap.html">http://developer.netscape.com/software/ldap/ldap.html</a>
<p><b>Note: </b>This page uses Communicator's SmartUpdate feature to update
the classes. Before visiting this page, you must enable SmartUpdate, Java,
JavaScript, and cookies in Communicator.
<p><b><font face="Arial,Helvetica">To enable SmartUpdate, Java, JavaScript,
and cookies:</font></b>
<ul>
<li>
Go to the Edit menu and choose Preferences.</li>
<li>
Select Advanced and make sure that Accept all cookies is active (it's radio
button is filled).</li>
<li>
Make sure that Enable Java and Enable JavaScript are checked.</li>
<li>
Choose Advanced | SmartUpdate from the left-hand panel.</li>
<li>
Make sure that Enable SmartUpdate is checked.</li>
<li>
Click OK.</li>
</ul>
<hr SIZE=1 NOSHADE WIDTH="100%"><a NAME="report"></a><b><font face="Arial,Helvetica"><font size=+1>Reporting
Problems</font></font></b>
<p>Please submit your problem via the the <a href="http://bugzilla.mozilla.org">Bugzilla</a>
@ -294,7 +452,7 @@ bugsystem . Use the "LDAP Java SDK" component.
<hr SIZE=1 NOSHADE WIDTH="100%"><a NAME="newsgroup"></a><b><font face="Arial,Helvetica"><font size=+1>Accessing
the Directory Developers Newsgroup</font></font></b>
<p>If you have additional questions or need more information about the
Netscape Directory SDK 4.0 for Java, please visit the Mozilla <a href="news://news.mozilla.org/netscape.public.mozilla.directory">Directory
Netscape Directory SDK 4.x for Java, please visit the Mozilla <a href="news://news.mozilla.org/netscape.public.mozilla.directory">Directory
newsgroup</a> and the DevEdge <a href="http://developer.netscape.com/support/newsgroups/" TARGET="_top">Directory
Server newsgroups</a>.
<center>
@ -312,4 +470,3 @@ TechSearch</a>.</font></center>
<hr SIZE=0 WIDTH="100%">
</body>
</html>
GIF89a¤Õÿ€ÿÿÿÿÿÌÿÌÿÿÌÌõõùììòââìâ¹ìÙÙåÏÏßÌÿÿÌÿÌÌÌÿÌÌÌÌ™ÿÌ™ÌÅÅÙ¼¼Ò²²Ì©©Æ  ¿™Ìÿ™ÌÌ™™ÿ™™Ì™™™™fÌ™f™¹ŒŒ³ƒƒ¬yy¦ppŸfÌÌf™Ìf™™ffÌff™fffff3f3™f3f3™Ì3™™3f™3ff33™33f3333€f3€3€™™€f™€ff€f3€3™€3f€33€€f€€3€€€€€€€€€€€€,€€€€¤@ÿÀpH,

View File

@ -407,7 +407,7 @@ public class LDAPSearch extends LDAPTool {
cons.setServerControls(controls);
cons.setDereference( m_deref );
cons.setMaxResults( m_sizelimit );
cons.setTimeLimit( m_timelimit );
cons.setServerTimeLimit( m_timelimit );
cons.setReferrals( m_referrals );
if ( m_referrals ) {
setDefaultReferralCredentials( cons );
@ -468,6 +468,7 @@ public class LDAPSearch extends LDAPTool {
System.err.println("\t"+urls[i].getUrl().toString());
continue;
} catch (Exception e) {
m_pw.flush();
System.err.println( e.toString() );
continue;
}
@ -483,6 +484,7 @@ public class LDAPSearch extends LDAPTool {
}
}
} catch (Exception e) {
m_pw.flush();
System.err.println( e.toString() );
System.exit(0);
}
@ -501,11 +503,13 @@ public class LDAPSearch extends LDAPTool {
protected static boolean isSchemaEntry( LDAPEntry entry ) {
LDAPAttribute attr = entry.getAttribute( "objectclass" );
String[] vals = attr.getStringValueArray();
for( int i = 0; i < vals.length; i++ ) {
if ( vals[i].equalsIgnoreCase( "subschema" ) ) {
return true;
}
if ( attr != null ) {
String[] vals = attr.getStringValueArray();
for( int i = 0; i < vals.length; i++ ) {
if ( vals[i].equalsIgnoreCase( "subschema" ) ) {
return true;
}
}
}
return false;
}