Synch up with the main dev tree

git-svn-id: svn://10.0.0.236/trunk@44846 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
miodrag%netscape.com
1999-08-27 15:58:58 +00:00
parent 16b0b18fb6
commit b4ad141bad
37 changed files with 1384 additions and 652 deletions

View File

@@ -111,7 +111,7 @@ import java.util.*;
public class LDAPAttributeSchema extends LDAPSchemaElement {
/**
* Construct a blank element.
* Constructs a blank element.
*/
protected LDAPAttributeSchema() {
super();
@@ -120,11 +120,11 @@ public class LDAPAttributeSchema extends LDAPSchemaElement {
/**
* Constructs an attribute type 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 syntax Syntax of this attribute type. The value of this
* @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 syntax syntax of this attribute type. The value of this
* argument can be one of the following:
* <UL>
* <LI><CODE>cis</CODE> (case-insensitive string)
@@ -135,38 +135,67 @@ public class LDAPAttributeSchema extends LDAPSchemaElement {
* but blanks and dashes are ignored during comparisons)
* <LI><CODE>dn</CODE> (distinguished name)
* </UL>
* @param single <CODE>true</CODE> if the attribute type is single-valued.
* @param single <CODE>true</CODE> if the attribute type is single-valued
*/
public LDAPAttributeSchema( String name, String oid, String description,
int syntax, boolean single ) {
int syntax, boolean single ) {
this( name, oid, description, cisString, single );
this.syntax = syntax;
this.syntaxString = internalSyntaxToString();
setQualifier( SYNTAX, this.syntaxString );
syntaxElement.syntax = syntax;
String syntaxType = syntaxElement.internalSyntaxToString( syntax );
if ( syntaxType != null ) {
syntaxElement.syntaxString = syntaxType;
}
setQualifier( SYNTAX, getSyntaxString() );
}
/**
* Constructs an attribute type 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 syntaxString Syntax of this attribute type in dotted-string
* format (for example, "1.2.3.4.5").
* @param single <CODE>true</CODE> if the attribute type is single-valued.
* @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 syntaxString syntax of this attribute type in dotted-string
* format (for example, "1.2.3.4.5")
* @param single <CODE>true</CODE> if the attribute type is single-valued
*/
public LDAPAttributeSchema( String name, String oid, String description,
String syntaxString, boolean single ) {
String syntaxString, boolean single ) {
this( name, oid, description, syntaxString, single, null, null );
}
/**
* Constructs an attribute type 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 syntaxString syntax of this attribute type in dotted-string
* format (for example, "1.2.3.4.5")
* @param single <CODE>true</CODE> if the attribute type is single-valued
* @param superior superior attribute as a name or OID; <CODE>null</CODE>
* if there is no superior
* @param aliases names which are to be considered aliases for this
* attribute; <CODE>null</CODE> if there are no aliases
*/
public LDAPAttributeSchema( String name, String oid, String description,
String syntaxString, boolean single,
String superior, String[] aliases ) {
super( name, oid, description );
attrName = "attributetypes";
this.syntax = syntaxCheck( syntaxString );
this.syntaxString = syntaxString;
setQualifier( SYNTAX, this.syntaxString );
this.single = single;
syntaxElement.syntax = syntaxElement.syntaxCheck( syntaxString );
syntaxElement.syntaxString = syntaxString;
setQualifier( SYNTAX, syntaxElement.syntaxString );
if ( single ) {
setQualifier( SINGLE, "" );
}
if ( (superior != null) && (superior.length() > 0) ) {
setQualifier( SUPERIOR, superior );
}
if ( (aliases != null) && (aliases.length > 0) ) {
this.aliases = aliases;
}
}
/**
@@ -182,22 +211,42 @@ public class LDAPAttributeSchema extends LDAPSchemaElement {
* in this format.)
* <P>
*
* @param raw Definition of the attribute type in the
* AttributeTypeDescription format.
* @param raw definition of the attribute type in the
* AttributeTypeDescription format
*/
public LDAPAttributeSchema( String raw ) {
attrName = "attributetypes";
parseValue( raw );
String val = (String)properties.get( SYNTAX );
if ( val != null ) {
syntaxString = val;
syntax = syntaxCheck( val );
syntaxElement.syntaxString = val;
syntaxElement.syntax = syntaxElement.syntaxCheck( val );
}
single = properties.containsKey( "SINGLE-VALUE" );
}
/**
* Gets the syntax of the attribute type.
* Determines if the attribute type is single-valued.
* @return <code>true</code> if single-valued,
* <code>false</code> if multi-valued
*/
public boolean isSingleValued() {
return (properties != null) ? properties.containsKey( SINGLE ) :
false;
}
/**
* Gets the name of the attribute that this attribute inherits from,
* if any.
* @return the name of the attribute that this attribute
* inherits from, or <CODE>null</CODE> if it does not have a superior
*/
public String getSuperior() {
String[] val = getQualifier( SUPERIOR );
return ((val != null) && (val.length > 0)) ? val[0] : null;
}
/**
* Gets the syntax of the schema element
* @return One of the following values:
* <UL>
* <LI><CODE>cis</CODE> (case-insensitive string)
@@ -211,83 +260,42 @@ public class LDAPAttributeSchema extends LDAPSchemaElement {
* </UL>
*/
public int getSyntax() {
return syntax;
return syntaxElement.syntax;
}
/**
* Gets the syntax of the attribute type in dotted-decimal format,
* for example "1.2.3.4.5"
* @return the attribute syntax in dotted-decimal format.
* @return The attribute syntax in dotted-decimal format.
*/
public String getSyntaxString() {
return syntaxString;
}
/**
* Determines if the attribute type is single-valued.
* @return <code>true</code> if single-valued,
* <code>false</code> if multi-valued.
*/
public boolean isSingleValued() {
return single;
}
protected String internalSyntaxToString() {
String s;
if ( syntax == cis ) {
s = cisString;
} else if ( syntax == binary ) {
s = binaryString;
} else if ( syntax == ces ) {
s = cesString;
} else if ( syntax == telephone ) {
s = telephoneString;
} else if ( syntax == dn ) {
s = dnString;
} else if ( syntax == integer ) {
s = intString;
} else {
s = syntaxString;
}
return s;
}
protected String syntaxToString() {
String s;
if ( syntax == cis ) {
s = "case-insensitive string";
} else if ( syntax == binary ) {
s = "binary";
} else if ( syntax == integer ) {
s = "integer";
} else if ( syntax == ces ) {
s = "case-exact string";
} else if ( syntax == telephone ) {
s = "telephone";
} else if ( syntax == dn ) {
s = "distinguished name";
} else {
s = syntaxString;
}
return s;
return syntaxElement.syntaxString;
}
/**
* Prepare 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 to be submitted to an LDAP server
* be quoted; that is to satisfy bugs in certain LDAP servers.
* @return a String ready to be submitted to an LDAP server
*/
String getValue( boolean quotingBug ) {
String getValue( boolean quotingBug ) {
String s = getValuePrefix();
s += getValue( SUPERIOR, false );
String val = getOptionalValues( MATCHING_RULES );
String val = getValue( SUPERIOR, false );
if ( val.length() > 0 ) {
s += val + ' ';
}
s += getValue( SYNTAX, quotingBug );
s += ' ';
val = getOptionalValues( MATCHING_RULES );
if ( val.length() > 0 ) {
s += val + ' ';
}
val = getValue( SYNTAX, quotingBug );
if ( val.length() > 0 ) {
s += val + ' ';
}
if ( isSingleValued() ) {
s += SINGLE + ' ';
}
val = getOptionalValues( NOVALS );
if ( val.length() > 0 ) {
s += val + ' ';
@@ -305,100 +313,55 @@ public class LDAPAttributeSchema extends LDAPSchemaElement {
}
/**
* Get the definition of the attribute type in a user friendly format.
* Gets the definition of the attribute type in a user friendly format.
* This is the format that the attribute type definition uses when
* you print the attribute type or the schema.
* @return Definition of the attribute type in a user friendly format.
* @return definition of the attribute type in a user friendly format
*/
public String toString() {
String s = "Name: " + name + "; OID: " + oid + "; Type: ";
s += syntaxToString();
s += syntaxElement.syntaxToString();
s += "; Description: " + description + "; ";
if ( single ) {
if ( isSingleValued() ) {
s += "single-valued";
} else {
s += "multi-valued";
}
s += getQualifierString( EXPLICIT );
s += getQualifierString( IGNOREVALS );
s += getAliasString();
return s;
}
protected int syntaxCheck( String syntax ) {
int i = unknown;
if ( syntax.equals( cisString ) ) {
i = cis;
} else if ( syntax.equals( binaryString ) ) {
i = binary;
} else if ( syntax.equals( cesString ) ) {
i = ces;
} else if ( syntax.equals( intString ) ) {
i = integer;
} else if ( syntax.equals( telephoneString ) ) {
i = telephone;
} else if ( syntax.equals( dnString ) ) {
i = dn;
}
return i;
}
/**
* Parses an attribute schema definition to see if the SYNTAX value
* is quoted. It shouldn't be (according to RFC 2252), but it is for
* some LDAP servers. It will either be:<BR>
* <CODE>SYNTAX 1.3.6.1.4.1.1466.115.121.1.15</CODE> or<BR>
* <CODE>SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'</CODE>
* @param raw Definition of the attribute type in the
* AttributeTypeDescription format.
*/
static boolean isSyntaxQuoted( String raw ) {
int ind = raw.indexOf( " SYNTAX " );
if ( ind >= 0 ) {
ind += 8;
int l = raw.length() - ind;
// Extract characters
char[] ch = new char[l];
raw.getChars( ind, raw.length(), ch, 0 );
ind = 0;
// Skip to ' or start of syntax value
while( (ind < ch.length) && (ch[ind] == ' ') ) {
ind++;
}
if ( ind < ch.length ) {
return ( ch[ind] == '\'' );
}
}
return false;
}
// Predefined qualifiers
public static final String EQUALITY = "EQUALITY";
public static final String ORDERING = "ORDERING";
public static final String SUBSTR = "SUBSTR";
public static final String SINGLE = "SINGLE-VALUE";
public static final String COLLECTIVE = "COLLECTIVE";
public static final String NO_USER_MODIFICATION = "NO-USER-MODIFICATION";
public static final String USAGE = "USAGE";
public static final String SYNTAX = "SYNTAX";
protected int syntax = unknown;
protected String syntaxString = null;
protected boolean single = false;
static String[] NOVALS = { SINGLE,
COLLECTIVE,
public static final String EQUALITY = "EQUALITY";
public static final String ORDERING = "ORDERING";
public static final String SUBSTR = "SUBSTR";
public static final String SINGLE = "SINGLE-VALUE";
public static final String COLLECTIVE = "COLLECTIVE";
public static final String NO_USER_MODIFICATION = "NO-USER-MODIFICATION";
public static final String USAGE = "USAGE";
// Qualifiers known to not have values; prepare a Hashtable
static String[] NOVALS = { SINGLE,
COLLECTIVE,
NO_USER_MODIFICATION };
static {
for( int i = 0; i < NOVALS.length; i++ ) {
novalsTable.put( NOVALS[i], NOVALS[i] );
}
}
static final String[] MATCHING_RULES = { EQUALITY,
static {
for( int i = 0; i < NOVALS.length; i++ ) {
novalsTable.put( NOVALS[i], NOVALS[i] );
}
}
static final String[] MATCHING_RULES = { EQUALITY,
ORDERING,
SUBSTR };
// Qualifiers tracked explicitly
static final String[] EXPLICIT = { SINGLE,
OBSOLETE,
COLLECTIVE,
NO_USER_MODIFICATION,
SYNTAX};
// Qualifiers which we output explicitly in toString()
static final String[] IGNOREVALS = { SINGLE,
OBSOLETE,
SUPERIOR,
SINGLE,
COLLECTIVE,
NO_USER_MODIFICATION,
SYNTAX};
private LDAPSyntaxSchemaElement syntaxElement =
new LDAPSyntaxSchemaElement();
}

View File

@@ -686,6 +686,7 @@ class Timer {
void start() {
TimerRunnable trun = new TimerRunnable(this);
t = new Thread(trun);
t.setDaemon(true);
t.start();
}

View File

@@ -62,11 +62,12 @@ class LDAPConnThread extends Thread {
transient private Vector m_registered;
transient private boolean m_disconnected = false;
transient private LDAPCache m_cache = null;
transient private boolean m_failed = false;
transient private boolean m_doRun = true;
private Socket m_socket = null;
transient private Thread m_thread = null;
transient Object m_sendRequestLock = new Object();
transient LDAPConnSetupMgr m_connMgr = null;
transient PrintWriter m_traceOutput = null;
/**
* Constructs a connection thread that maintains connection to the
@@ -75,14 +76,15 @@ class LDAPConnThread extends Thread {
* @param port LDAP port number
* @param factory LDAP socket factory
*/
public LDAPConnThread(LDAPConnSetupMgr connMgr, LDAPCache cache)
public LDAPConnThread(LDAPConnSetupMgr connMgr, LDAPCache cache, OutputStream traceOutput)
throws LDAPException {
super("LDAPConnection " + connMgr.getHost() +":"+ connMgr.getPort());
super("LDAPConnThread " + connMgr.getHost() +":"+ connMgr.getPort());
m_requests = new Hashtable ();
m_registered = new Vector ();
m_connMgr = connMgr;
m_socket = connMgr.getSocket();
setCache( cache );
setTraceOutputStream(traceOutput);
setDaemon(true);
@@ -97,8 +99,8 @@ class LDAPConnThread extends Thread {
// been created, the only way to clean up the thread is to call the
// start() method. Otherwise, the exit method will be never called
// because the start() was never called. In the run method, the stop
// method calls right away if the m_failed is set to true.
m_failed = true;
// method calls right away if the m_doRun is set to false.
m_doRun = false;
start();
throw new LDAPException ( "failed to connect to server " +
m_connMgr.getHost(), LDAPException.CONNECT_ERROR );
@@ -122,6 +124,13 @@ class LDAPConnThread extends Thread {
m_serverOutput = os;
}
void setTraceOutputStream(OutputStream os) {
synchronized (m_sendRequestLock) {
m_traceOutput = (os == null) ? null : new PrintWriter(os);
}
}
/**
* Set the cache to use for searches.
* @param cache The cache to use for searches; <CODE>null</CODE> for no cache
@@ -130,14 +139,26 @@ class LDAPConnThread extends Thread {
m_cache = cache;
m_messages = (m_cache != null) ? new Hashtable() : null;
}
/**
* Allocates a new LDAP message ID. These are arbitrary numbers used to
* correlate client requests with server responses.
* @return new unique msgId
*/
private int allocateId () {
synchronized (m_sendRequestLock) {
m_highMsgId = (m_highMsgId + 1) % MAXMSGID;
return m_highMsgId;
}
}
/**
* Sends LDAP request via this connection thread.
* @param request request to send
* @param toNotify response listener to invoke when the response
* is ready
*/
synchronized void sendRequest (LDAPConnection conn, JDAPProtocolOp request,
void sendRequest (LDAPConnection conn, JDAPProtocolOp request,
LDAPMessageQueue toNotify, LDAPConstraints cons)
throws LDAPException {
if (m_serverOutput == null)
@@ -151,16 +172,20 @@ class LDAPConnThread extends Thread {
if (!(request instanceof JDAPAbandonRequest ||
request instanceof JDAPUnbindRequest)) {
/* Only worry about toNotify if we expect a response... */
this.m_requests.put (new Integer (msg.getId()), toNotify);
this.m_requests.put (new Integer (msg.getID()), toNotify);
/* Notify the backlog checker that there may be another outstanding
request */
resultRetrieved();
}
toNotify.addRequest(msg.getId(), conn, this);
toNotify.addRequest(msg.getID(), conn, this, cons.getTimeLimit());
}
synchronized( m_sendRequestLock ) {
try {
if (m_traceOutput != null) {
m_traceOutput.println(msg.toTraceString());
m_traceOutput.flush();
}
msg.write (m_serverOutput);
m_serverOutput.flush ();
} catch (IOException e) {
@@ -191,13 +216,30 @@ class LDAPConnThread extends Thread {
m_registered.removeElement(conn);
if (m_registered.size() == 0) {
try {
LDAPConstraints cons = conn.getSearchConstraints();
sendRequest (null, new JDAPUnbindRequest (), null, cons);
cleanUp();
if ( m_thread != null ) {
m_doRun =false;
if (!m_disconnected) {
LDAPSearchConstraints cons = conn.getSearchConstraints();
sendRequest (null, new JDAPUnbindRequest (), null, cons);
}
if ( m_thread != null && m_thread != Thread.currentThread()) {
m_thread.interrupt();
// Wait up to 1 sec for thread to accept disconnect
// notification. When the interrupt is accepted,
// m_thread is set to null. See run() method.
try {
wait(1000);
}
catch (InterruptedException e) {
}
}
this.sleep(100); /* give enough time for threads to shutdown */
cleanUp();
} catch (Exception e) {
LDAPConnection.printDebug(e.toString());
}
@@ -238,6 +280,18 @@ class LDAPConnThread extends Thread {
*/
m_connMgr.disconnect();
/**
* Cancel all outstanding requests
*/
if (m_requests != null) {
Enumeration requests = m_requests.elements();
while (requests.hasMoreElements()) {
LDAPMessageQueue listener =
(LDAPMessageQueue)requests.nextElement();
listener.removeAllRequests(this);
}
}
/**
* Notify all the registered about this bad moment.
* IMPORTANT: This needs to be done at last. Otherwise, the socket
@@ -265,7 +319,7 @@ class LDAPConnThread extends Thread {
/**
* Sleep if there is a backlog of search results
*/
private void checkBacklog() {
private void checkBacklog() throws InterruptedException{
boolean doWait;
do {
doWait = false;
@@ -286,23 +340,20 @@ class LDAPConnThread extends Thread {
// Asynch operation ?
if (sl.isAsynchOp()) {
if (sl.getMessageCount() >= sl.getConstraints().getMaxBacklog()) {
if (sl.getMessageCount() >= sl.getSearchConstraints().getMaxBacklog()) {
doWait = true;
}
}
// synch op with non-zero batch size ?
else if (sl.getConstraints().getBatchSize() != 0) {
if (sl.getMessageCount() >= sl.getConstraints().getMaxBacklog()) {
else if (sl.getSearchConstraints().getBatchSize() != 0) {
if (sl.getMessageCount() >= sl.getSearchConstraints().getMaxBacklog()) {
doWait = true;
}
}
}
if ( doWait ) {
synchronized(this) {
try {
wait();
} catch (InterruptedException e ) {
}
wait();
}
}
} while ( doWait );
@@ -324,7 +375,7 @@ class LDAPConnThread extends Thread {
// if there is a problem of establishing connection to the server,
// stop the thread right away...
if (m_failed) {
if (!m_doRun) {
return;
}
@@ -332,54 +383,55 @@ class LDAPConnThread extends Thread {
LDAPMessage msg = null;
JDAPBERTagDecoder decoder = new JDAPBERTagDecoder();
while (true) {
while (m_doRun) {
yield();
int[] nread = new int[1];
nread[0] = 0;
// Avoid too great a backlog of results
checkBacklog();
try {
if (m_thread.isInterrupted()) {
break;
}
// Avoid too great a backlog of results
checkBacklog();
BERElement element = BERElement.getElement(decoder,
m_serverInput,
nread);
msg = LDAPMessage.parseMessage(element);
if (m_traceOutput != null) {
synchronized( m_sendRequestLock ) {
m_traceOutput.println(msg.toTraceString());
m_traceOutput.flush();
}
}
// passed in the ber element size to approximate the size of the cache
// entry, thereby avoiding serialization of the entry stored in the
// cache
processResponse (msg, nread[0]);
} catch (Exception e) {
networkError(e);
if (m_doRun) {
networkError(e);
m_doRun =false;
}
else {
synchronized (this) {
m_thread = null;
notifyAll();
}
}
}
if (m_disconnected)
break;
}
}
/**
* Allocates a new LDAP message ID. These are arbitrary numbers used to
* correlate client requests with server responses.
* @return new unique msgId
*/
private synchronized int allocateId () {
m_highMsgId = (m_highMsgId + 1) % MAXMSGID;
return m_highMsgId;
}
/**
* When a response arrives from the LDAP server, it is processed by
* this routine. It will pass the message on to the listening object
* associated with the LDAP msgId.
* @param incoming New message from LDAP server
*/
private synchronized void processResponse (LDAPMessage incoming, int size) {
Integer messageID = new Integer (incoming.getId());
private void processResponse (LDAPMessage incoming, int size) {
Integer messageID = new Integer (incoming.getID());
LDAPMessageQueue l = (LDAPMessageQueue)m_requests.get (messageID);
if (l == null) {
@@ -395,7 +447,7 @@ class LDAPConnThread extends Thread {
/* Were there any controls for this client? */
LDAPControl[] con = incoming.getControls();
if (con != null) {
int msgid = incoming.getId();
int msgid = incoming.getID();
LDAPConnection ldc = l.getConnection(msgid);
if (ldc != null) {
ldc.setResponseControls( this,
@@ -404,83 +456,81 @@ class LDAPConnThread extends Thread {
}
}
if ((l instanceof LDAPSearchListener) && m_cache != null) {
cacheSearchResult((LDAPSearchListener)l, incoming, size);
}
l.addMessage (incoming);
if (incoming instanceof LDAPResponse) {
m_requests.remove (messageID);
}
}
private synchronized void cacheSearchResult (LDAPSearchListener l, LDAPMessage incoming, int size) {
Integer messageID = new Integer (incoming.getID());
Long key = l.getKey();
Vector v = null;
JDAPProtocolOp op = incoming.getProtocolOp ();
if ((op instanceof JDAPSearchResponse) ||
(op instanceof JDAPSearchResultReference)) {
if ((m_cache == null) || (key == null)) {
return;
}
if ((incoming instanceof LDAPSearchResult)/* ||
(incoming instanceof LDAPSearchResultReference)*/) {
l.addMessage (incoming);
Long key = ((LDAPSearchListener)l).getKey();
// get the vector containing the LDAPMessages for the specified messageID
v = (Vector)m_messages.get(messageID);
if ((m_cache != null) && (key != null)) {
// get the vector containing the LDAPMessages for the specified messageID
v = (Vector)m_messages.get(messageID);
if (v == null) {
v = new Vector();
// keeps track of the total size of all LDAPMessages belonging to the
// same messageID, now the size is 0
v.addElement(new Long(0));
}
// add the size of the current LDAPMessage to the lump sum
// assume the size of LDAPMessage is more or less the same as the size
// of LDAPEntry. Eventually LDAPEntry object gets stored in the cache
// instead of LDAPMessage object.
long entrySize = ((Long)v.firstElement()).longValue() + size;
// update the lump sum located in the first element of the vector
v.setElementAt(new Long(entrySize), 0);
// convert LDAPMessage object into LDAPEntry which is stored to the
// end of the Vector
v.addElement(((LDAPSearchResult)incoming).getEntry());
// replace the entry
m_messages.put(messageID, v);
} else if (incoming instanceof LDAPResponse) {
boolean fail = ((LDAPResponse)incoming).getResultCode() > 0;
if (!fail) {
// Collect all the LDAPMessages for the specified messageID
// no need to keep track of this entry. Remove it.
v = (Vector)m_messages.remove(messageID);
// If v is null, meaning there are no search results from the
// server
if (v == null) {
v = new Vector();
// keeps track of the total size of all LDAPMessages belonging to the
// same messageID, now the size is 0
// set the entry size to be 0
v.addElement(new Long(0));
}
// add the size of the current LDAPMessage to the lump sum
// assume the size of LDAPMessage is more or less the same as the size
// of LDAPEntry. Eventually LDAPEntry object gets stored in the cache
// instead of LDAPMessage object.
long entrySize = ((Long)v.firstElement()).longValue() + size;
// update the lump sum located in the first element of the vector
v.setElementAt(new Long(entrySize), 0);
// convert LDAPMessage object into LDAPEntry which is stored to the
// end of the Vector
v.addElement(((LDAPSearchResult)incoming).getEntry());
// replace the entry
m_messages.put(messageID, v);
}
} else {
l.addMessage (incoming);
if (l instanceof LDAPSearchListener) {
Long key = ((LDAPSearchListener)l).getKey();
if (key != null) {
boolean fail = false;
JDAPProtocolOp protocolOp = incoming.getProtocolOp();
if (protocolOp instanceof JDAPSearchResult) {
JDAPResult res = (JDAPResult)protocolOp;
if (res.getResultCode() > 0) {
fail = true;
}
}
if ((!fail) && (m_cache != null)) {
// Collect all the LDAPMessages for the specified messageID
// no need to keep track of this entry. Remove it.
v = (Vector)m_messages.remove(messageID);
// If v is null, meaning there are no search results from the
// server
if (v == null) {
v = new Vector();
// set the entry size to be 0
v.addElement(new Long(0));
}
try {
// add the new entry with key and value (a vector of
// LDAPEntry objects)
m_cache.addEntry(key, v);
} catch (LDAPException e) {
System.out.println("Exception: "+e.toString());
}
}
try {
// add the new entry with key and value (a vector of
// LDAPEntry objects)
m_cache.addEntry(key, v);
} catch (LDAPException e) {
System.out.println("Exception: "+e.toString());
}
}
m_requests.remove (messageID);
}
}
@@ -488,12 +538,12 @@ class LDAPConnThread extends Thread {
* Stop dispatching responses for a particular message ID.
* @param id Message ID for which to discard responses.
*/
synchronized void abandon (int id ) {
void abandon (int id ) {
LDAPMessageQueue l = (LDAPMessageQueue)m_requests.remove(new Integer(id));
if (l != null) {
l.removeRequest(id);
}
notifyAll(); // If LDAPConnThread is blocked in checkBacklog()
resultRetrieved(); // If LDAPConnThread is blocked in checkBacklog()
}
/**
@@ -502,10 +552,11 @@ class LDAPConnThread extends Thread {
* input stream.
*/
private synchronized void networkError (Exception e) {
try {
// notify the Connection Setup Manager that the connection is lost
m_connMgr.invalidateConnection();
// notify the Connection Setup Manager that the connection is lost
m_connMgr.invalidateConnection();
try {
// notify each listener that the server is down.
Enumeration requests = m_requests.elements();
@@ -515,29 +566,11 @@ class LDAPConnThread extends Thread {
listener.setException(this, new LDAPException("Server down",
LDAPException.OTHER));
}
cleanUp();
} catch (NullPointerException ee) {
System.err.println("Exception: "+ee.toString());
}
/**
* Notify all the registered connections.
* IMPORTANT: This needs to be done last. Otherwise, the socket
* input stream and output stream might never get closed and the whole
* task will get stuck in the stop method when we try to stop the
* LDAPConnThread.
*/
if (m_registered != null) {
Vector registerCopy = (Vector)m_registered.clone();
Enumeration cancelled = registerCopy.elements();
while (cancelled.hasMoreElements ()) {
LDAPConnection c = (LDAPConnection)cancelled.nextElement();
c.deregisterConnection();
}
}
cleanUp();
}
}

View File

@@ -162,6 +162,25 @@ public class LDAPConnection
*/
public final static String LDAP_PROPERTY_SECURITY = "version.security";
/**
* 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
* <CODE>setProperty</CODE> method.
* <P>
* When -D command line option is used, defining the property with
* no value will send the trace output to the standard error. If the
* value is defined, it is assumed to be the name of an output file.
* <P>
* When the property is set with <CODE>getProperty</CODE> method,
* the property must have an output stream as the value. To stop
* tracing, <CODE>null</CODE> should be passed as the property value.
*
* @see netscape.ldap.LDAPConnection#setProperty(java.lang.String, java.lang.Object)
*/
public final static String TRACE_PROPERTY = "com.netscape.ldap.trace";
/**
* Specifies the serial connection setup policy when a list of hosts is
* passed to the <CODE>connect</CODE> method.
@@ -408,6 +427,23 @@ public class LDAPConnection
m_properties.put( SASL_PACKAGE_PROPERTY, val );
} else if ( name.equalsIgnoreCase( "debug" ) ) {
debug = ((String)val).equalsIgnoreCase( "true" );
} else if ( name.equalsIgnoreCase( TRACE_PROPERTY ) ) {
if (val == null) {
m_properties.remove(TRACE_PROPERTY);
}
else if (! (val instanceof OutputStream)) {
throw new LDAPException(TRACE_PROPERTY + " must be OutputStream" );
}
else {
m_properties.put( TRACE_PROPERTY, val );
}
if (m_thread != null) {
m_thread.setTraceOutputStream((OutputStream)val);
}
} else {
throw new LDAPException("Unknown property: " + name);
}
@@ -862,6 +898,45 @@ public class LDAPConnection
authenticateSSLConnection();
}
/**
* Returns the trace output stream if set by the user
*/
OutputStream getTraceOutputStream() {
// Check first if trace output has been set using setProperty()
OutputStream os = (OutputStream)m_properties.get(TRACE_PROPERTY);
if (os != null) {
return os;
}
// Check if the property has been set with java -Dcom.netscape.ldap.trace
// If the property does not have a value, send the trace to the System.err,
// otherwise use the value as the output file name
try {
String traceProp = System.getProperty(TRACE_PROPERTY);
if (traceProp != null) {
if (traceProp.length() == 0) {
return System.err;
}
else {
try {
FileOutputStream fos = new FileOutputStream(traceProp);
return new BufferedOutputStream(fos);
}
catch (Exception e) {
System.err.println("Can not open output trace file: " + e);
return null;
}
}
}
}
catch (Exception e) {
;// In browser access to property might not be allowed
}
return null;
}
private synchronized LDAPConnThread getNewThread(LDAPConnSetupMgr connMgr,
LDAPCache cache)
throws LDAPException {
@@ -892,7 +967,8 @@ public class LDAPConnection
// need to move all the LDAPConnections from the dead thread
// to the new thread
try {
newThread = new LDAPConnThread(connMgr, cache);
newThread = new LDAPConnThread(connMgr, cache,
getTraceOutputStream());
v = (Vector)m_threadConnTable.remove(connThread);
break;
} catch (Exception e) {
@@ -913,7 +989,8 @@ public class LDAPConnection
// connection is dead
if (!connExists) {
try {
newThread = new LDAPConnThread(connMgr, cache);
newThread = new LDAPConnThread(connMgr, cache,
getTraceOutputStream());
v = new Vector();
v.addElement(this);
} catch (Exception e) {

View File

@@ -195,10 +195,13 @@ public class LDAPConstraints implements Cloneable {
/**
* Sets the maximum number of milliseconds to wait for any operation
* under these constraints. If 0, there is no maximum time limit
* on waiting for the operation results.
* on waiting for the operation results. If the time limit is exceeded,
* an LDAPException with the result code <CODE>LDAPException.TIME_LIMIT
* </CODE> is thrown.
* @param msLimit Maximum number of milliseconds to wait for operation
* results.
* (0 by default, which means that there is no maximum time limit.)
* @see netscape.ldap.LDAPException#LDAP_TIMEOUT
*/
public void setTimeLimit( int msLimit ) {
m_time_limit = msLimit;
@@ -221,7 +224,7 @@ public class LDAPConstraints implements Cloneable {
* Alternatively, the <CODE>LDAPBind</CODE> object identifies an
* authentication mechanism to be used instead of the default
* authentication mechanism when following referrals. This
* object should be passed to the <CODE>setBindProc</BIND> method.
* object should be passed to the <CODE>setBindProc</CODE> method.
* @param doReferrals Set to <CODE>true</CODE> if referrals should be
* followed automatically, or <CODE>False</CODE> if referrals should throw
* an <CODE>LDAPReferralException</CODE>.

View File

@@ -110,6 +110,7 @@ import java.io.*;
* 71 <A HREF="#AFFECTS_MULTIPLE_DSAS">AFFECTS_MULTIPLE_DSAS</A> (LDAP v3)
* 80 <A HREF="#OTHER">OTHER</A>
* 81 <A HREF="#SERVER_DOWN">SERVER_DOWN</A>
* 85 <A HREF="#LDAP_TIMEOUT">LDAP_TIMEOUT</A>
* 89 <A HREF="#PARAM_ERROR">PARAM_ERROR</A>
* 91 <A HREF="#CONNECT_ERROR">CONNECT_ERROR</A>
* 92 <A HREF="#LDAP_NOT_SUPPORTED">LDAP_NOT_SUPPORTED</A>
@@ -484,6 +485,17 @@ public class LDAPException extends java.lang.Exception {
*/
public final static int SERVER_DOWN = 0x51;
/**
* (85) The operation could not be completed within the
* maximum time limit. You can specify the maximum time limit
* by calling the <CODE>LDAPConstraints.setTimeLimit</CODE>
* method.<P>
*
* @see netscape.ldap.LDAPConstraints#setTimeLimit
*/
public final static int LDAP_TIMEOUT = 0x55;
/**
* (89) When calling a constructor or method from your client,
* one or more parameters were incorrectly specified.

View File

@@ -67,6 +67,7 @@ import java.util.*;
* RFC 2252 defines MatchingRuleDescription and MatchingRuleUseDescription
* as follows:
* <P>
* <PRE>
* MatchingRuleDescription = "(" whsp
* numericoid whsp ; MatchingRule identifier
* [ "NAME" qdescrs ]
@@ -84,7 +85,7 @@ import java.util.*;
* [ "DESC" qdstring ]
* [ "OBSOLETE" ]
* "APPLIES" oids ; AttributeType identifiers
* whsp ")" * <PRE>
* whsp ")"
* </PRE>
* <P>
* <CODE>LDAPMatchingRuleSchema</CODE> abstracts away from the two types and
@@ -94,17 +95,17 @@ import java.util.*;
* @see netscape.ldap.LDAPSchemaElement
**/
public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
public class LDAPMatchingRuleSchema extends LDAPSchemaElement {
/**
* Construct a matching rule definition, using the specified
* Constructs a matching rule definition, using the specified
* information.
* @param name Name of the matching rule.
* @param oid Object identifier (OID) of the matching rule
* in dotted-string 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.
* @param syntax Syntax of this matching rule. The value of this
* @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
* @param syntax syntax of this matching rule. The value of this
* argument can be one of the following:
* <UL>
* <LI><CODE>cis</CODE> (case-insensitive string)
@@ -116,13 +117,68 @@ public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
* <LI><CODE>dn</CODE> (distinguished name)
* </UL>
*/
public LDAPMatchingRuleSchema( String name, String oid, String description,
String[] attributes, int syntax ) {
super( name, oid, description, syntax, true );
public LDAPMatchingRuleSchema( String name, String oid,
String description,
String[] attributes, int syntax ) {
this( name, oid, description, attributes, cisString );
syntaxElement.syntax = syntax;
String syntaxType = syntaxElement.internalSyntaxToString( syntax );
if ( syntaxType != null ) {
syntaxElement.syntaxString = syntaxType;
}
setQualifier( SYNTAX, syntaxElement.syntaxString );
}
/**
* Constructs a matching rule 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.
* @param syntaxString syntax of this matching rule in dotted-decimal
* format
*/
public LDAPMatchingRuleSchema( String name, String oid,
String description,
String[] attributes,
String syntaxString ) {
this( name, oid, description, attributes, syntaxString, null );
}
/**
* Constructs a matching rule 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.
* @param syntaxString syntax of this matching rule in dotted-decimal
* format
* @param aliases names which are to be considered aliases for this
* matching rule; <CODE>null</CODE> if there are no aliases
*/
public LDAPMatchingRuleSchema( String name, String oid,
String description,
String[] attributes,
String syntaxString,
String[] aliases ) {
super( name, oid, description );
attrName = "matchingrules";
syntaxElement.syntax = syntaxElement.syntaxCheck( syntaxString );
syntaxElement.syntaxString = syntaxString;
setQualifier( SYNTAX, syntaxElement.syntaxString );
this.attributes = new String[attributes.length];
for( int i = 0; i < attributes.length; i++ )
this.attributes[i] = new String( attributes[i] );
for( int i = 0; i < attributes.length; i++ ) {
this.attributes[i] = attributes[i];
}
if ( (aliases != null) && (aliases.length > 0) ) {
this.aliases = aliases;
}
}
/**
@@ -131,7 +187,7 @@ public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
* 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
* 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".
@@ -139,14 +195,16 @@ public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
* in this format.
* <P>
*
* @param raw Definition of the matching rule in the
* MatchingRuleDescription format.
* @param use Definition of the use of the matching rule in the
* MatchingRuleUseDescription format.
* @param raw definition of the matching rule in the
* MatchingRuleDescription format
* @param use definition of the use of the matching rule in the
* MatchingRuleUseDescription format
*/
public LDAPMatchingRuleSchema( String raw, String use ) {
attrName = "matchingrules";
parseValue( raw );
if ( raw != null ) {
parseValue( raw );
}
if ( use != null ) {
parseValue( use );
}
@@ -158,32 +216,68 @@ public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
}
String val = (String)properties.get( "SYNTAX" );
if ( val != null ) {
syntaxString = val;
syntax = syntaxCheck( val );
syntaxElement.syntaxString = val;
syntaxElement.syntax = syntaxElement.syntaxCheck( val );
}
}
/**
* Get the list of the OIDs of the attribute types which can be used
* with the matching rule. The list is a deep copy.
* @return Array of the OIDs of the attribute types which can be used
* 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[] getAttributes() {
return attributes;
}
/**
* 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 attribute type in dotted-decimal format,
* for example "1.2.3.4.5"
* @return The attribute syntax in dotted-decimal format.
*/
public String getSyntaxString() {
return syntaxElement.syntaxString;
}
/**
* Prepare 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 to be submitted to an LDAP server
*/
String getValue( boolean quotingBug ) {
String s = getValuePrefix();
s += "SYNTAX ";
if ( quotingBug ) {
s += '\'';
if ( syntaxElement.syntaxString != null ) {
s += "SYNTAX ";
if ( quotingBug ) {
s += '\'';
}
s += syntaxElement.syntaxString;
if ( quotingBug ) {
s += '\'';
}
s += ' ';
}
s += syntaxString;
if ( quotingBug ) {
s += '\'';
}
s += ' ';
String val = getCustomValues();
if ( val.length() > 0 ) {
s += val + ' ';
@@ -193,7 +287,7 @@ public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
}
/**
* Get the matching rule definition in the string representation
* Gets the matching rule definition in the string representation
* of the MatchingRuleDescription data type defined in X.501 (see
* <A HREF="http://ds.internic.net/rfc/rfc2252.txt"
* TARGET="_blank">RFC 2252, Lightweight Directory Access Protocol
@@ -207,16 +301,16 @@ public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
* matching rule use description in these formats.)
* <P>
*
* @return A string in a format that can be used as the value of
* @return a string in a format that can be used as the value of
* the <CODE>matchingrule</CODE> attribute (which describes
* a matching rule in the schema) of a <CODE>subschema</CODE> object.
* a matching rule in the schema) of a <CODE>subschema</CODE> object
*/
public String getValue() {
return getValue( false );
}
/**
* Get the matching rule use definition in the string representation
* 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
@@ -230,36 +324,34 @@ public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
* matching rule use description in these formats.)
* <P>
*
* @return A string in a format that can be used as the value of
* @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.
* a matching rule in the schema) of a <CODE>subschema</CODE> object
*/
public String getUseValue() {
String s = getValuePrefix();
s += "APPLIES ( ";
for( int i = 0; i < attributes.length; i++ ) {
if ( i > 0 )
s += " $ ";
s += attributes[i];
}
s += ") ";
String val = getCustomValues();
if ( val.length() > 0 ) {
s += val + ' ';
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;
}
/**
* Add, remove or modify the definition from a Directory.
* @param ld An open connection to a Directory Server. Typically the
* Adds, removes or modifies the definition from a Directory.
* @param ld an open connection to a Directory Server. Typically the
* connection must have been authenticated to add a definition.
* @param op Type of modification to make.
* @param name Name of attribute in the schema entry to modify. This
* @param op type of modification to make
* @param name name of attribute in the schema entry to modify. This
* is ignored here.
* @param dn The entry at which to update the schema.
* @exception LDAPException if the definition can't be added/removed.
* @param dn the entry at which to update the schema
* @exception LDAPException if the definition can't be added/removed
*/
protected void update( LDAPConnection ld, int op, String name, String dn )
throws LDAPException {
@@ -273,14 +365,14 @@ public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
}
/**
* Get the definition of the matching rule in a user friendly format.
* Gets the definition of the matching rule in a user friendly format.
* This is the format that the matching rule definition uses when
* you print the matching rule or the schema.
* @return Definition of the matching rule in a user friendly format.
* @return definition of the matching rule in a user friendly format
*/
public String toString() {
String s = "Name: " + name + "; OID: " + oid + "; Type: ";
s += syntaxToString();
s += syntaxElement.syntaxToString();
s += "; Description: " + description;
if ( attributes != null ) {
s += "; Applies to: ";
@@ -291,8 +383,15 @@ public class LDAPMatchingRuleSchema extends LDAPAttributeSchema {
}
}
s += getQualifierString( EXPLICIT );
s += getAliasString();
return s;
}
// Qualifiers tracked explicitly
static final String[] EXPLICIT = { OBSOLETE,
SYNTAX };
private String[] attributes = null;
private LDAPSyntaxSchemaElement syntaxElement =
new LDAPSyntaxSchemaElement();
}

View File

@@ -22,6 +22,8 @@ import netscape.ldap.client.opers.*;
import netscape.ldap.ber.stream.*;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
/**
* Base class for LDAP request and response messages.
@@ -73,6 +75,9 @@ public class LDAPMessage {
private JDAPProtocolOp m_protocolOp = null;
private LDAPControl m_controls[] = null;
// Time Stemp format Hour(0-23):Minute:Second.Milliseconds used for trace msgs
static SimpleDateFormat m_timeFormat = new SimpleDateFormat("HH:mm:ss.SSS");
/**
* Constructs a ldap message.
* @param msgid message identifier
@@ -184,7 +189,7 @@ public class LDAPMessage {
* Returns the message identifer.
* @return message identifer
*/
public int getId(){
public int getID(){
return m_msgid;
}
@@ -241,17 +246,35 @@ public class LDAPMessage {
* @return ldap message
*/
public String toString() {
if (m_controls == null) {
return "[LDAPMessage] " + m_msgid + " " + m_protocolOp.toString();
StringBuffer sb = new StringBuffer("[LDAPMessage] ");
sb.append(m_msgid);
sb.append(" ");
sb.append(m_protocolOp.toString());
for (int i =0; m_controls != null && i < m_controls.length; i++) {
sb.append(" ");
sb.append(m_controls[i].toString());
}
else {
StringBuffer sb = new StringBuffer(
"[LDAPMessage] " + m_msgid + " " + m_protocolOp.toString());
for (int i =0; i < m_controls.length; i++) {
sb.append(" ctrl"+i+"=");
sb.append(m_controls[i].toString());
}
return sb.toString();
}
return sb.toString();
}
/**
* Returns string representation of a ldap message with
* the time stamp. Used for message trace
* @return ldap message with the time stamp
*/
String toTraceString() {
String timeStamp = m_timeFormat.format(new Date());
StringBuffer sb = new StringBuffer(timeStamp);
sb.append(" ");
sb.append(m_msgid);
sb.append(" ");
sb.append(m_protocolOp.toString());
for (int i =0; m_controls != null && i < m_controls.length; i++) {
sb.append(" ");
sb.append(m_controls[i].toString());
}
return sb.toString();
}
}

View File

@@ -38,11 +38,16 @@ class LDAPMessageQueue {
int id;
LDAPConnection connection;
LDAPConnThread connThread;
long timeToComplete;
RequestEntry(int id, LDAPConnection connection, LDAPConnThread connThread) {
RequestEntry(int id, LDAPConnection connection,
LDAPConnThread connThread, int timeLimit) {
this.id= id;
this.connection = connection;
this.connThread = connThread;
this.timeToComplete = (timeLimit == 0) ?
Long.MAX_VALUE : (System.currentTimeMillis() + timeLimit);
}
}
@@ -53,6 +58,9 @@ class LDAPMessageQueue {
private /*RequestEntry*/ Vector m_requestList = new Vector(1);
private LDAPException m_exception; /* For network errors */
private boolean m_asynchOp;
// A flag whether there are time constrained requests
private boolean m_timeConstrained;
/**
* Constructor
@@ -84,11 +92,7 @@ class LDAPMessageQueue {
synchronized LDAPMessage nextMessage () throws LDAPException {
while(m_requestList.size() != 0 && m_exception == null && m_messageQueue.size() == 0) {
try {
wait ();
} catch (InterruptedException e) {
throw new LDAPInterruptedException("Interrupted LDAP operation");
}
waitForMessage();
}
// Network exception occurred ?
@@ -109,7 +113,7 @@ class LDAPMessageQueue {
// Is the ldap operation completed?
if (msg instanceof LDAPResponse) {
removeRequest(msg.getId());
removeRequest(msg.getID());
}
return msg;
@@ -127,12 +131,7 @@ class LDAPMessageQueue {
while (true) {
while(m_requestList.size() != 0 && m_exception == null && m_messageQueue.size() == 0) {
try {
wait ();
} catch (InterruptedException e) {
throw new LDAPInterruptedException("Interrupted LDAP operation");
}
waitForMessage();
}
// Network exception occurred ?
@@ -159,13 +158,54 @@ class LDAPMessageQueue {
}
// Not found, wait for the next message
waitForMessage();
}
}
/**
* Wait for a response message. Process interrupts and honor
* time limit if set for any request
*/
synchronized private void waitForMessage () throws LDAPException{
if (!m_timeConstrained) {
try {
wait ();
return;
} catch (InterruptedException e) {
throw new LDAPInterruptedException("Interrupted LDAP operation");
}
}
}
/**
* Perform time constrained wait
*/
long minTimeToComplete = Long.MAX_VALUE;
long now = System.currentTimeMillis();
for (int i=0; i < m_requestList.size(); i++) {
RequestEntry entry = (RequestEntry)m_requestList.elementAt(i);
// time limit exceeded ?
if (entry.timeToComplete <= now) {
entry.connection.abandon(entry.id);
throw new LDAPException("Time to complete operation exceeded",
LDAPException.LDAP_TIMEOUT);
}
if (entry.timeToComplete < minTimeToComplete) {
minTimeToComplete = entry.timeToComplete;
}
}
long timeLimit = (minTimeToComplete == Long.MAX_VALUE)?
0 :(minTimeToComplete - now);
try {
m_timeConstrained = (timeLimit != 0);
wait (timeLimit);
} catch (InterruptedException e) {
throw new LDAPInterruptedException("Interrupted LDAP operation");
}
}
/**
@@ -268,7 +308,7 @@ class LDAPMessageQueue {
int removeCount=0;
for (int i=(m_messageQueue.size()-1); i>=0; i--) {
LDAPMessage msg = (LDAPMessage)m_messageQueue.elementAt(i);
if (msg.getId() == id) {
if (msg.getID() == id) {
m_messageQueue.removeElementAt(i);
removeCount++;
}
@@ -286,6 +326,7 @@ class LDAPMessageQueue {
m_exception = null;
m_messageQueue.removeAllElements();
m_requestList.removeAllElements();
m_timeConstrained = false;
}
/**
@@ -353,11 +394,18 @@ class LDAPMessageQueue {
* @param id LDAP request message ID
* @param connection LDAP Connection for the message ID
* @param connThread A physical connection to the server
* @param timeLimit The maximum number of milliseconds to wait for
* the request to complete
*/
synchronized void addRequest(int id, LDAPConnection connection,
LDAPConnThread connThread) {
LDAPConnThread connThread, int timeLimit) {
m_requestList.addElement(new RequestEntry(id, connection, connThread));
m_requestList.addElement(new RequestEntry(id, connection,
connThread, timeLimit));
if (timeLimit != 0) {
m_timeConstrained = true;
}
notifyAll();
}
/**

View File

@@ -102,57 +102,69 @@ import java.util.*;
public class LDAPObjectClassSchema extends LDAPSchemaElement {
/**
* Constructs an object class definition, using the specified
* information.
* 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 the names of the attributes required
* in this object class.
* @param optional Array of the names of the optional attributes
* allowed in this 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
*/
public LDAPObjectClassSchema( String name, String oid, String superior,
String description,
String[] required, String[] optional ) {
super( name, oid, description );
attrName = "objectclasses";
this.superiors = new String[] { superior };
setQualifier( SUPERIOR, superior );
for( int i = 0; i < required.length; i++ ) {
must.addElement( required[i] );
if ( required != null ) {
for( int i = 0; i < required.length; i++ ) {
must.addElement( required[i] );
}
}
for( int i = 0; i < optional.length; i++ ) {
may.addElement( optional[i] );
if ( optional != null ) {
for( int i = 0; i < optional.length; i++ ) {
may.addElement( optional[i] );
}
}
}
/**
* Constructs an object class definition, using the specified
* information.
* @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 superiors Name of parent object classes
* (the object class that the new object class inherits from).
* @param required Array of the names of the attributes required
* in this object class.
* @param optional Array of the names of the optional attributes
* allowed in this object class.
* @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 superiors names of parent object classes
* (the object classes that this object class inherits from)
* @param required array of names of attributes required
* in this object class
* @param optional array names of optional attributes
* allowed in this object class
* @param type Either ABSTRACT, STRUCTURAL, or AUXILIARY
* @param aliases names which are to be considered aliases for this
* object class; <CODE>null</CODE> if there are no aliases
*/
public LDAPObjectClassSchema( String name, String oid,
String[] superiors,
String description,
String[] required, String[] optional,
int type ) {
this( name, oid, superiors[0], description, required, optional );
this.superiors = superiors;
setQualifier( SUPERIOR, this.superiors );
this.type = type;
int type, String[] aliases ) {
this( name, oid,
((superiors != null) && (superiors.length > 0)) ?
superiors[0] : null,
description, required, optional );
if ( (superiors != null) && (superiors.length > 1) ) {
setQualifier( SUPERIOR, superiors );
}
setQualifier( TYPE, typeToString( type ) );
if ( (aliases != null) && (aliases.length > 0) ) {
this.aliases = aliases;
}
}
/**
@@ -168,25 +180,13 @@ public class LDAPObjectClassSchema extends LDAPSchemaElement {
* in this format.)
* <P>
*
* @param raw Definition of the object in the ObjectClassDescription
* format.
* @param raw definition of the object in the ObjectClassDescription
* format
*/
public LDAPObjectClassSchema( String raw ) {
attrName = "objectclasses";
parseValue( raw );
String[] vals = getQualifier( SUPERIOR );
if ( vals != null ) {
superiors = vals;
setQualifier( SUPERIOR, (String)null );
}
if ( properties.containsKey( "AUXILIARY" ) ) {
type = AUXILIARY;
} else if ( properties.containsKey( "ABSTRACT" ) ) {
type = ABSTRACT;
} else if ( properties.containsKey( "STRUCTURAL" ) ) {
type = STRUCTURAL;
}
obsolete = properties.containsKey( OBSOLETE );
setQualifier( TYPE, typeToString( getType() ) );
Object o = properties.get( "MAY" );
if ( o != null ) {
if ( o instanceof Vector ) {
@@ -206,72 +206,91 @@ public class LDAPObjectClassSchema extends LDAPSchemaElement {
}
/**
* Get the name of the object class that this class inherits from.
* @return The name of the object class that this class
* inherits from.
* Gets the name of the object class that this class inherits from.
* @return the name of the object class that this class
* inherits from. If it inherits from more than one class, only one
* is returned.
* @see netscape.ldap.LDAPObjectClassSchema#getSuperiors
*/
public String getSuperior() {
return superiors[0];
String[] superiors = getSuperiors();
return (superiors != null) ? superiors[0] : null;
}
/**
* Get the names of all object classes that this class inherits
* Gets the names of all object classes that this class inherits
* from. Typically only one, but RFC 2252 allows multiple
* inheritance.
* @return The names of the object classes that this class
* inherits from.
* @return the names of the object classes that this class
* inherits from
*/
public String[] getSuperiors() {
return superiors;
return getQualifier( SUPERIOR );
}
/**
* Get an enumeration of the names of the required attribute for
* Gets an enumeration of the names of the required attributes for
* this object class.
* @return An enumeration of the names of the required attributes
* for this object class.
* @return an enumeration of the names of the required attributes
* for this object class
*/
public Enumeration getRequiredAttributes() {
return must.elements();
}
/**
* Get an enumeration of names of optional attributes allowed
* Gets an enumeration of names of optional attributes allowed
* in this object class.
* @return An enumeration of the names of optional attributes
* allowed in this object class.
* @return an enumeration of the names of optional attributes
* allowed in this object class
*/
public Enumeration getOptionalAttributes() {
return may.elements();
}
/**
* Get the type of the object class.
* Gets the type of the object class.
* @return STRUCTURAL, ABSTRACT, or AUXILIARY
*/
public int getType() {
int type = STRUCTURAL;
if ( properties.containsKey( "AUXILIARY" ) ) {
type = AUXILIARY;
} else if ( properties.containsKey( "ABSTRACT" ) ) {
type = ABSTRACT;
}
return type;
}
/**
* Prepare a value in RFC 2252 format for submitting to a server
* 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 to be submitted to an LDAP server
* @return a String ready to be submitted to an LDAP server
*/
String getValue( boolean quotingBug ) {
String getValue( boolean quotingBug ) {
String s = getValuePrefix();
s += getValue( SUPERIOR, quotingBug );
s += ' ';
String val = getOptionalValues( NOVALS );
String val = getValue( SUPERIOR, quotingBug );
if ( (val != null) && (val.length() > 0) ) {
s += val + ' ';
}
String[] vals = getQualifier( TYPE );
if ( (vals != null) && (vals.length > 0) ) {
s += vals[0] + ' ';
}
val = getOptionalValues( NOVALS );
if ( val.length() > 0 ) {
s += val + ' ';
}
s += "MUST " + vectorToList( must );
s += ' ';
s += "MAY " + vectorToList( may );
s += ' ';
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 + ' ';
@@ -281,18 +300,21 @@ public class LDAPObjectClassSchema extends LDAPSchemaElement {
}
/**
* Get the definition of the object class in a user friendly format.
* Gets the definition of the object class in a user friendly format.
* This is the format that the object class definition uses when
* you print the object class or the schema.
* @return Definition of the object class in a user friendly format.
* @return definition of the object class in a user friendly format
*/
public String toString() {
String s = "Name: " + name + "; OID: " + oid +
"; Superior: ";
for( int i = 0; i < superiors.length; i++ ) {
s += superiors[i];
if ( i < (superiors.length-1) ) {
s += ", ";
String[] superiors = getSuperiors();
if ( superiors != null ) {
for( int i = 0; i < superiors.length; i++ ) {
s += superiors[i];
if ( i < (superiors.length-1) ) {
s += ", ";
}
}
}
s += "; Description: " + description + "; Required: ";
@@ -313,28 +335,23 @@ public class LDAPObjectClassSchema extends LDAPSchemaElement {
i++;
s += (String)e.nextElement();
}
switch ( type ) {
case STRUCTURAL:
break;
case ABSTRACT:
s += "; ABSTRACT";
break;
case AUXILIARY:
s += "; AUXILIARY";
break;
String[] vals = getQualifier( TYPE );
if ( (vals != null) && (vals.length > 0) ) {
s += "; " + vals[0];
}
if ( obsolete ) {
if ( isObsolete() ) {
s += "; OBSOLETE";
}
s += getQualifierString( IGNOREVALS );
s += getAliasString();
return s;
}
/**
* Create a list within parentheses, with $ as delimiter
* Creates a list within parentheses, with $ as delimiter
*
* @param vals Values for list
* @return A String with a list of values
* @param vals values for list
* @return a String with a list of values
*/
protected String vectorToList( Vector vals ) {
String val = "( ";
@@ -348,23 +365,43 @@ public class LDAPObjectClassSchema extends LDAPSchemaElement {
return val;
}
/**
* Returns the object class type as a String
*
* @param type one of STRUCTURAL, ABSTRACT, or AUXILIARY
* @return one of "STRUCTURAL", "ABSTRACT", "AUXILIARY", or <CODE>null</CODE>
*/
protected String typeToString( int type ) {
switch( type ) {
case STRUCTURAL: return "STRUCTURAL";
case ABSTRACT: return "ABSTRACT";
case AUXILIARY: return "AUXILIARY";
default: return null;
}
}
public static final int STRUCTURAL = 0;
public static final int ABSTRACT = 1;
public static final int AUXILIARY = 2;
private String[] superiors = { "" };
private Vector must = new Vector();
private Vector may = new Vector();
private int type = STRUCTURAL;
// Qualifers known to not have values
static String[] NOVALS = { "ABSTRACT", "STRUCTURAL",
"AUXILIARY" };
static {
for( int i = 0; i < NOVALS.length; i++ ) {
novalsTable.put( NOVALS[i], NOVALS[i] );
}
}
static String[] IGNOREVALS = { "ABSTRACT", "STRUCTURAL",
"AUXILIARY", "MUST", "MAY" };
// Qualifiers known to not have values; prepare a Hashtable
static final String[] NOVALS = { "ABSTRACT", "STRUCTURAL",
"AUXILIARY", "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 = { "ABSTRACT", "STRUCTURAL",
"AUXILIARY", "MUST", "MAY",
"SUP", "OBSOLETE"};
// Key for type in the properties Hashtable
static final String TYPE = "TYPE";
}

View File

@@ -57,11 +57,6 @@ public class LDAPSSLSocketFactory implements LDAPSSLSocketFactoryExt {
*/
private Object m_cipherSuites = null;
/**
* The Ldap connection
*/
private LDAPConnection m_connection = null;
/**
* Constructs an <CODE>LDAPSSLSocketFactory</CODE> object using
* the default SSL socket implementation,

View File

@@ -449,8 +449,7 @@ public class LDAPSchema {
if ( attr != null ) {
Enumeration en = attr.getStringValues();
if( en.hasMoreElements() ) {
compliant = !LDAPAttributeSchema.isSyntaxQuoted(
(String)en.nextElement() );
compliant = !isSyntaxQuoted( (String)en.nextElement() );
}
}
ld.setProperty( ld.SCHEMA_BUG_PROPERTY, compliant ? "standard" :
@@ -458,6 +457,35 @@ public class LDAPSchema {
return compliant;
}
/**
* Parses an attribute schema definition to see if the SYNTAX value
* is quoted. It shouldn't be (according to RFC 2252), but it is for
* some LDAP servers. It will either be:<BR>
* <CODE>SYNTAX 1.3.6.1.4.1.1466.115.121.1.15</CODE> or<BR>
* <CODE>SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'</CODE>
* @param raw Definition of the attribute type in the
* AttributeTypeDescription format.
*/
static boolean isSyntaxQuoted( String raw ) {
int ind = raw.indexOf( " SYNTAX " );
if ( ind >= 0 ) {
ind += 8;
int l = raw.length() - ind;
// Extract characters
char[] ch = new char[l];
raw.getChars( ind, raw.length(), ch, 0 );
ind = 0;
// Skip to ' or start of syntax value
while( (ind < ch.length) && (ch[ind] == ' ') ) {
ind++;
}
if ( ind < ch.length ) {
return ( ch[ind] == '\'' );
}
}
return false;
}
/**
* Displays the schema (including the descriptions of its object
* classes, attribute types, and matching rules) in an easily

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- 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.0 (the "NPL"); you may not use this file except in
@@ -75,19 +75,22 @@ import java.util.*;
public abstract class LDAPSchemaElement {
/**
* Construct a blank element.
* Constructs a blank element.
*/
protected LDAPSchemaElement() {
}
/**
* Construct a definition explicitly.
* @param name Name of element.
* @param oid Dotted-string object identifier.
* @param description Description of element.
* Constructs a definition explicitly.
* @param name name of element
* @param oid dotted-string object identifier
* @param description description of element
*/
protected LDAPSchemaElement( String name, String oid,
String description ) {
if ( (oid == null) || (oid.trim().length() < 1) ) {
throw new IllegalArgumentException( "OID required" );
}
this.name = name;
this.oid = oid;
this.description = description;
@@ -95,8 +98,8 @@ public abstract class LDAPSchemaElement {
/**
* Gets the name of the object class, attribute type, or matching rule.
* @return The name of the object class, attribute type, or
* matching rule.
* @return the name of the object class, attribute type, or
* matching rule
*/
public String getName() {
return name;
@@ -105,30 +108,30 @@ public abstract class LDAPSchemaElement {
/**
* Gets the object ID (OID) of the object class, attribute type,
* or matching rule in dotted-string format (for example, "1.2.3.4").
* @return The OID of the object class, attribute type,
* or matching rule.
* @return the OID of the object class, attribute type,
* or matching rule
*/
public String getOID() {
return oid;
}
/**
* Get the description of the object class, attribute type,
* or matching rule.
* @return The description of the object class, attribute type,
* Gets the description of the object class, attribute type,
* or matching rule.
* @return the description of the object class, attribute type,
* or matching rule
*/
public String getDescription() {
return description;
}
/**
* Add, remove or modify the definition from a Directory.
* @param ld An open connection to a Directory Server. Typically the
* Adds, removes or modifies the definition from a Directory.
* @param ld an open connection to a Directory Server. Typically the
* connection must have been authenticated to add a definition.
* @param op Type of modification to make.
* @param atrr Attribute in the schema entry to modify.
* @exception LDAPException if the definition can't be added/removed.
* @param op type of modification to make
* @param attr attribute in the schema entry to modify
* @exception LDAPException if the definition can't be added/removed
*/
protected void update( LDAPConnection ld, int op, LDAPAttribute attr,
String dn )
@@ -139,12 +142,12 @@ public abstract class LDAPSchemaElement {
}
/**
* Add, remove or modify the definition from a Directory.
* @param ld An open connection to a Directory Server. Typically the
* Adds, removes or modifies the definition from a Directory.
* @param ld an open connection to a Directory Server. Typically the
* connection must have been authenticated to add a definition.
* @param op Type of modification to make.
* @param attrs Attributes in the schema entry to modify.
* @exception LDAPException if the definition can't be added/removed.
* @param op type of modification to make
* @param attrs attributes in the schema entry to modify
* @exception LDAPException if the definition can't be added/removed
*/
protected void update( LDAPConnection ld, int op, LDAPAttribute[] attrs,
String dn )
@@ -158,12 +161,12 @@ public abstract class LDAPSchemaElement {
}
/**
* Add, remove or modify the definition from a Directory.
* @param ld An open connection to a Directory Server. Typically the
* Adds, removes or modifies the definition from a Directory.
* @param ld an open connection to a Directory Server. Typically the
* connection must have been authenticated to add a definition.
* @param op Type of modification to make.
* @param name Name of attribute in the schema entry to modify.
* @exception LDAPException if the definition can't be added/removed.
* @param op type of modification to make
* @param name name of attribute in the schema entry to modify
* @exception LDAPException if the definition can't be added/removed
*/
protected void update( LDAPConnection ld, int op, String name,
String dn )
@@ -180,11 +183,11 @@ public abstract class LDAPSchemaElement {
* definition to the schema. Typically, most servers
* will require you to authenticate before allowing you to
* edit the schema.
* @param ld The <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server.
* @param dn The entry at which to add the schema definition.
* @exception LDAPException The specified definition cannot be
* added to the schema.
* @param ld the <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server
* @param dn the entry at which to add the schema definition
* @exception LDAPException if the specified definition cannot be
* added to the schema
*/
public void add( LDAPConnection ld, String dn ) throws LDAPException {
update( ld, LDAPModification.ADD, attrName, dn );
@@ -195,26 +198,26 @@ public abstract class LDAPSchemaElement {
* definition to the schema at the root DSE. Typically, most servers
* will require you to authenticate before allowing you to
* edit the schema.
* @param ld The <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server.
* @exception LDAPException The specified definition cannot be
* added to the schema.
* @param ld the <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server
* @exception LDAPException if the specified definition cannot be
* added to the schema
*/
public void add( LDAPConnection ld ) throws LDAPException {
add( ld, "" );
}
/**
* Replace a single value of the object class, attribute type,
* Replaces a single value of the object class, attribute type,
* or matching rule definition in the schema. Typically, most servers
* will require you to authenticate before allowing you to
* edit the schema.
* @param ld The <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server.
* @param newValue The new value
* @param dn The entry at which to modify the schema definition.
* @exception LDAPException The specified definition cannot be
* modified.
* @param ld the <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server
* @param newValue the new value
* @param dn the entry at which to modify the schema definition
* @exception LDAPException if the specified definition cannot be
* modified
*/
public void modify( LDAPConnection ld, LDAPSchemaElement newValue,
String dn )
@@ -232,16 +235,16 @@ public abstract class LDAPSchemaElement {
}
/**
* Replace a single value of the object class, attribute type,
* Replaces a single value of the object class, attribute type,
* or matching rule definition in the schema at the root DSE.
* Typically, most servers
* will require you to authenticate before allowing you to
* edit the schema.
* @param ld The <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server.
* @param newValue The new value
* @exception LDAPException The specified definition cannot be
* modified.
* @param ld the <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server
* @param newValue the new value
* @exception LDAPException if the specified definition cannot be
* modified
*/
public void modify( LDAPConnection ld, LDAPSchemaElement newValue )
throws LDAPException {
@@ -253,11 +256,11 @@ public abstract class LDAPSchemaElement {
* definition from the schema. Typically, most servers
* will require you to authenticate before allowing you to
* edit the schema.
* @param ld The <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server.
* @param dn The entry at which to remove the schema definition.
* @exception LDAPException The specified definition cannot be
* removed from the schema.
* @param ld the <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server
* @param dn the entry at which to remove the schema definition
* @exception LDAPException if the specified definition cannot be
* removed from the schema
*/
public void remove( LDAPConnection ld, String dn ) throws LDAPException {
update( ld, LDAPModification.DELETE, attrName, dn );
@@ -268,28 +271,28 @@ public abstract class LDAPSchemaElement {
* definition from the schema at the root DSE. Typically, most servers
* will require you to authenticate before allowing you to
* edit the schema.
* @param ld The <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server.
* @exception LDAPException The specified definition cannot be
* removed from the schema.
* @param ld the <CODE>LDAPConnection</CODE> object representing
* a connection to an LDAP server
* @exception LDAPException if the specified definition cannot be
* removed from the schema
*/
public void remove( LDAPConnection ld ) throws LDAPException {
remove( ld, "" );
}
/**
* Report if the element is marked as obsolete.
* Reports if the element is marked as obsolete.
* @return <CODE>true<CODE> if the element is defined as obsolete.
*/
public boolean isObsolete() {
return obsolete;
return properties.containsKey(OBSOLETE);
}
/**
* Parse a raw schema value into OID, name, description, and
* Parses a raw schema value into OID, name, description, and
* a Hashtable of other qualifiers and values
*
* @param raw A raw schema definition
* @param raw a raw schema definition
*/
protected void parseValue( String raw ) {
if ( properties == null ) {
@@ -333,10 +336,10 @@ public abstract class LDAPSchemaElement {
// Found a token
s = new String( ch, ind, last-ind );
ind = last;
if ( novalsTable.containsKey( s ) ) {
properties.put( s, "" );
continue;
}
if ( novalsTable.containsKey( s ) ) {
properties.put( s, "" );
continue;
}
} else {
// Reached end of string with no end of token
s = "";
@@ -362,7 +365,7 @@ public abstract class LDAPSchemaElement {
while( (last < l) && (ch[last] != '\'') ) {
last++;
}
} else if ( ch[ind] == '(' ) {
} else if ( ch[ind] == '(' ) {
// The value is a list
list = true;
ind++;
@@ -375,42 +378,54 @@ public abstract class LDAPSchemaElement {
last++;
}
}
if ( (ind < last) && (last < l) ) {
if ( list ) {
Vector v = new Vector();
if ( (ind < last) && (last <= l) ) {
if ( list ) {
Vector v = new Vector();
val = new String( ch, ind+1, last-ind-1 );
StringTokenizer st = new StringTokenizer( val, " " );
// Is this a quoted list? If so, use ' as delimiter,
// otherwise use ' '. The space between quoted
// values will be returned as tokens containing only
// white space. White space is not valid in a list
// value, so we just remove all tokens containing
// only white space.
String delim = (val.indexOf( '\'' ) >= 0) ? "'" : " ";
StringTokenizer st = new StringTokenizer( val, delim );
while ( st.hasMoreTokens() ) {
String tok = st.nextToken();
if ( !tok.equals( "$" ) ) {
// Remove quotes, if any
if ( tok.charAt( 0 ) == '\'' ) {
tok = tok.substring( 1, tok.length()-1 );
}
String tok = st.nextToken().trim();
if ( (tok.length() > 0) && !tok.equals( "$" ) ) {
v.addElement( tok );
}
}
properties.put( s, v );
} else {
val = new String( ch, ind, last-ind );
if ( s.equals( "NAME" ) ) {
name = val;
} else if ( s.equals( "DESC" ) ) {
description = val;
} else {
properties.put( s, val );
}
if ( quoted ) {
last++;
}
properties.put( s, v );
} else {
val = new String( ch, ind, last-ind );
if ( s.equals( "NAME" ) ) {
name = val;
} else if ( s.equals( "DESC" ) ) {
description = val;
} else {
properties.put( s, val );
}
if ( quoted ) {
last++;
}
}
}
ind = last + 1;
}
// Aliases end up as values of NAME
String[] vals = getQualifier( "NAME" );
if ( (vals != null) && (vals.length > 0) ) {
name = vals[0];
if ( vals.length > 1 ) {
aliases = new String[vals.length-1];
System.arraycopy( vals, 1, aliases, 0, aliases.length );
}
}
}
/**
* Format a String in the format defined in X.501 (see
* Formats a String in the format defined in X.501 (see
* <A HREF="http://ds.internic.net/rfc/rfc2252.txt"
* >RFC 2252, Lightweight Directory Access Protocol
* (v3): Attribute Syntax Definitions</A>
@@ -424,24 +439,40 @@ public abstract class LDAPSchemaElement {
* <P>
* @param quotingBug <CODE>true</CODE> if single quotes are to be
* supplied around the SYNTAX and SUP value
* @return A formatted String for defining a schema element
* @return a formatted String for defining a schema element
*/
public String getValue() {
return getValue( false );
}
abstract String getValue( boolean quotingBug );
String getValue( boolean quotingBug ) {
return null;
}
/**
* Prepare the initial common part of a schema element value in
* Prepares the initial common part of a schema element value in
* RFC 2252 format for submitting to a server
*
* @return The OID, name, description, and possibly OBSOLETE
* @return the OID, name, description, and possibly OBSOLETE
* fields of a schema element definition
*/
String getValuePrefix() {
String s = "( " + oid + " NAME \'" + name + "\' DESC \'" +
description + "\' ";
String getValuePrefix() {
String s = "( " + oid + ' ';
if ( name != null ) {
s += "NAME ";
if ( aliases != null ) {
s += "( " + '\'' + name + "\' ";
for( int i = 0; i < aliases.length; i++ ) {
s += '\'' + aliases[i] + "\' ";
}
s += ") ";
} else {
s += '\'' + name + "\' ";
}
}
if ( description != null ) {
s += "DESC \'" + description + "\' ";
}
if ( isObsolete() ) {
s += OBSOLETE + ' ';
}
@@ -449,9 +480,9 @@ public abstract class LDAPSchemaElement {
}
/**
* Get qualifiers which may or may not be present
* Gets qualifiers which may or may not be present
*
* @param names List of qualifiers to look up
* @param names list of qualifiers to look up
* @return String in RFC 2252 format containing any values
* found, not terminated with ' '
*/
@@ -467,32 +498,41 @@ public abstract class LDAPSchemaElement {
}
/**
* Get any qualifiers marked as custom
* Gets any qualifiers marked as custom (starting with "X-")
*
* @return String in RFC 2252 format, without a terminating
* ' '
*/
protected String getCustomValues() {
String s = "";
Enumeration en = properties.keys();
while( en.hasMoreElements() ) {
String key = (String)en.nextElement();
if ( !key.startsWith( "X-" ) ) {
Enumeration en = properties.keys();
while( en.hasMoreElements() ) {
String key = (String)en.nextElement();
if ( !key.startsWith( "X-" ) ) {
continue;
}
s += getValue( key, true );
}
return s;
}
s += getValue( key, true, false ) + ' ';
}
// Strip trailing ' '
if ( (s.length() > 0) && (s.charAt( s.length() - 1 ) == ' ') ) {
s = s.substring( 0, s.length() - 1 );
}
return s;
}
/**
* Get a qualifier's value or values, if present, and format
* Gets a qualifier's value or values, if present, and formats
* the String according to RFC 2252
*
* @param key the qualifier to get
* @param doQuote <CODE>true</CODE> if values should be enveloped
* with single quotes
* @param doDollar <CODE>true</CODE> if a list of values should use
* " $ " as separator; that is true for object class attribute lists
* @return String in RFC 2252 format, without a terminating
* ' '
*/
String getValue( String key, boolean doQuote ) {
String getValue( String key, boolean doQuote, boolean doDollar ) {
String s = "";
Object o = properties.get( key );
if ( o == null ) {
@@ -521,19 +561,34 @@ public abstract class LDAPSchemaElement {
s += '\'';
}
s += ' ';
if ( i < (v.size() - 1) ) {
if ( doDollar && (i < (v.size() - 1)) ) {
s += "$ ";
}
}
s += ')';
}
return s;
}
return s;
}
/**
* Keep track of qualifiers which are not predefined.
* @param name Name of qualifier
* @param value Value of qualifier. "" for no value
* Gets a qualifier's value or values, if present, and format
* the String according to RFC 2252
*
* @param key the qualifier to get
* @param doQuote <CODE>true</CODE> if values should be enveloped
* with single quotes
* @return String in RFC 2252 format, without a terminating
* ' '
*/
String getValue( String key, boolean doQuote ) {
return getValue( key, doQuote, true );
}
/**
* Keeps track of qualifiers which are not predefined.
* @param name name of qualifier
* @param value value of qualifier. "" for no value, <CODE>null</CODE>
* to remove the qualifier
*/
public void setQualifier( String name, String value ) {
if ( properties == null ) {
@@ -547,9 +602,9 @@ public abstract class LDAPSchemaElement {
}
/**
* Keep track of qualifiers which are not predefined.
* Keeps track of qualifiers which are not predefined.
* @param name Name of qualifier
* @param values Array of values
* @param values array of values
*/
public void setQualifier( String name, String[] values ) {
if ( values == null ) {
@@ -559,16 +614,16 @@ public abstract class LDAPSchemaElement {
properties = new Hashtable();
}
Vector v = new Vector();
for( int i = 0; i < v.size(); i++ ) {
for( int i = 0; i < values.length; i++ ) {
v.addElement( values[i] );
}
properties.put( name, v );
}
/**
* Get the value of a qualifier which is not predefined.
* @param name Name of qualifier
* @return Value or values of qualifier. <CODE>null</CODE> if not
* Gets the value of a qualifier which is not predefined.
* @param name name of qualifier
* @return value or values of qualifier; <CODE>null</CODE> if not
* present, a zero-length array if present but with no value
*/
public String[] getQualifier( String name ) {
@@ -594,18 +649,27 @@ public abstract class LDAPSchemaElement {
}
/**
* Get an enumeration of all qualifiers which are not predefined.
* @return Enumeration of qualifiers.
* Gets an enumeration of all qualifiers which are not predefined.
* @return Enumeration of qualifiers
*/
public Enumeration getQualifierNames() {
return properties.keys();
}
/**
* Create a string for use in toString with any qualifiers of the element.
* Gets the aliases of the attribute, if any
* @return the aliases of the attribute, or <CODE>null</CODE> if
* it does not have any aliases
*/
public String[] getAliases() {
return aliases;
}
/**
* Creates a string for use in toString with any qualifiers of the element.
*
* @param ignore Any qualifiers to NOT include
* @return A String with any known qualifiers
* @param ignore any qualifiers to NOT include
* @return a String with any known qualifiers
*/
String getQualifierString( String[] ignore ) {
Hashtable toIgnore = null;
@@ -633,9 +697,29 @@ public abstract class LDAPSchemaElement {
s += vals[i] + ' ';
}
}
// Strip trailing ' '
if ( (s.length() > 0) && (s.charAt( s.length() - 1 ) == ' ') ) {
s = s.substring( 0, s.length() - 1 );
}
return s;
}
/**
* Gets any aliases for this element
*
* @return a string with any aliases, for use in toString()
*/
String getAliasString() {
if ( aliases != null ) {
String s = "; aliases:";
for( int i = 0; i < aliases.length; i++ ) {
s += ' ' + aliases[i];
}
return s;
}
return "";
}
// Constants for known syntax types
public static final int unknown = 0;
public static final int cis = 1;
@@ -657,19 +741,22 @@ public abstract class LDAPSchemaElement {
"1.3.6.1.4.1.1466.115.121.1.27";
protected static final String dnString =
"1.3.6.1.4.1.1466.115.121.1.12";
// Predefined qualifiers which apply to any schema element type
public static final String OBSOLETE = "OBSOLETE";
public static final String SUPERIOR = "SUP";
// Predefined qualifiers which apply to any schema element type
public static final String OBSOLETE = "OBSOLETE";
public static final String SUPERIOR = "SUP";
// Predefined qualifiers
public static final String SYNTAX = "SYNTAX";
// Properties which are common to all schema elements
protected String oid = null;
protected String oid = null;
protected String name = "";
protected String description = "";
protected String attrName = null;
protected boolean obsolete = false;
protected String rawValue = null;
protected String[] aliases = null;
// Additional qualifiers
protected Hashtable properties = null;
// Qualifiers known to not have values
static protected Hashtable novalsTable = new Hashtable();
static protected Hashtable novalsTable = new Hashtable();
}

View File

@@ -71,7 +71,7 @@ public class LDAPSearchListener extends LDAPMessageQueue {
public LDAPMessage getResponse () throws LDAPException{
LDAPMessage result = nextMessage();
// Notify LDAPConnThread to wake up if backlog limit has been reached
// Notify LDAPConnThread to wake up if backlog limit has been reached
if (result instanceof LDAPSearchResult || result instanceof LDAPSearchResultReference) {
LDAPConnection ld = getConnection(result.getID());
if (ld != null) {
@@ -103,6 +103,15 @@ public class LDAPSearchListener extends LDAPMessageQueue {
*/
public void merge(LDAPSearchListener listener2) {
super.merge(listener2);
}
/**
* Reports true if a response has been received from the server.
*
* @return A flag whether the response message queue is empty
*/
public boolean isResponseReceived() {
return super.isMessageReceived();
}
/**
@@ -115,7 +124,7 @@ public class LDAPSearchListener extends LDAPMessageQueue {
/**
* Return the search constraints used to create this object
* @return the search constraints used to create this object
* @return the search constraints used to create this object
*/
LDAPSearchConstraints getSearchConstraints() {
return m_constraints;

View File

@@ -509,6 +509,7 @@ public class LDAPSearchResults implements Enumeration {
} catch (LDAPException e) {
add(e);
currConn.releaseSearchListener(resultSource);
searchComplete = true;
return;
}

View File

@@ -137,6 +137,26 @@ public class LDAPSortKey {
return m_matchRule;
}
public String toString() {
StringBuffer sb = new StringBuffer("{SortKey:");
sb.append(" key=");
sb.append(m_key);
sb.append(" reverse=");
sb.append(m_reverse);
if (m_matchRule != null) {
sb.append(" matchRule=");
sb.append(m_matchRule);
}
sb.append("}");
return sb.toString();
}
private String m_key;
private boolean m_reverse;
private String m_matchRule;

View File

@@ -0,0 +1,146 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package netscape.ldap;
import java.util.*;
/**
* Helper class supporting schema elements that include syntax
* definitions - attributes and matching rules
*
* @version 1.0
* @see netscape.ldap.LDAPAttributeSchema
* @see netscape.ldap.LDAPMatchingRuleSchema
**/
class LDAPSyntaxSchemaElement extends LDAPSchemaElement {
/**
* Construct a blank element.
*/
LDAPSyntaxSchemaElement() {
super();
}
/**
* 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>
*/
int getSyntax() {
return syntax;
}
/**
* Gets the syntax of the attribute type in dotted-decimal format,
* for example "1.2.3.4.5"
* @return The attribute syntax in dotted-decimal format.
*/
String getSyntaxString() {
return syntaxString;
}
/**
* Convert from enumerated syntax types to an OID
* @param syntax One of the enumerated syntax types
* @return The OID corresponding to the internal type
*/
static String internalSyntaxToString( int syntax ) {
String s;
if ( syntax == cis ) {
s = cisString;
} else if ( syntax == binary ) {
s = binaryString;
} else if ( syntax == ces ) {
s = cesString;
} else if ( syntax == telephone ) {
s = telephoneString;
} else if ( syntax == dn ) {
s = dnString;
} else if ( syntax == integer ) {
s = intString;
} else {
s = null;
}
return s;
}
/**
* Convert from enumerated syntax type to a user-friendly
* string
* @param syntax One of the enumerated syntax types
* @return A user-friendly syntax description
*/
String syntaxToString() {
String s;
if ( syntax == cis ) {
s = "case-insensitive string";
} else if ( syntax == binary ) {
s = "binary";
} else if ( syntax == integer ) {
s = "integer";
} else if ( syntax == ces ) {
s = "case-exact string";
} else if ( syntax == telephone ) {
s = "telephone";
} else if ( syntax == dn ) {
s = "distinguished name";
} else {
s = syntaxString;
}
return s;
}
/**
* Convert from an OID to one of the enumerated syntax types
* @param syntax A dotted-decimal OID
* @return The internal enumerated type corresponding to the
* OID; <CODE>unknown</CODE> if it is not one of the known
* types
*/
int syntaxCheck( String syntax ) {
int i = unknown;
if ( syntax == null ) {
} else if ( syntax.equals( cisString ) ) {
i = cis;
} else if ( syntax.equals( binaryString ) ) {
i = binary;
} else if ( syntax.equals( cesString ) ) {
i = ces;
} else if ( syntax.equals( intString ) ) {
i = integer;
} else if ( syntax.equals( telephoneString ) ) {
i = telephone;
} else if ( syntax.equals( dnString ) ) {
i = dn;
}
return i;
}
int syntax = unknown;
String syntaxString = null;
}

View File

@@ -84,6 +84,6 @@ public class JDAPAbandonRequest implements JDAPProtocolOp {
* @return string representation
*/
public String toString() {
return "JDAPAbandonRequest {msgid=" + m_msgid + "}";
return "AbandonRequest {msgid=" + m_msgid + "}";
}
}

View File

@@ -136,6 +136,6 @@ public class JDAPAddRequest extends JDAPBaseDNRequest
* @return string representation of add request
*/
public String toString() {
return "JDAPAddRequest " + getParamString();
return "AddRequest " + getParamString();
}
}

View File

@@ -91,6 +91,6 @@ public class JDAPBindResponse extends JDAPResult implements JDAPProtocolOp {
* @return string representation
*/
public String toString() {
return "JDAPBindResponse " + super.getParamString();
return "BindResponse " + super.getParamString();
}
}

View File

@@ -95,7 +95,7 @@ public class JDAPCompareRequest extends JDAPBaseDNRequest
* @return string representation
*/
public String toString() {
return "JDAPCompareRequest {entry=" + m_dn + ", ava=" + m_ava.toString() +
return "CompareRequest {entry=" + m_dn + ", ava=" + m_ava.toString() +
"}";
}
}

View File

@@ -92,6 +92,6 @@ public class JDAPDeleteRequest extends JDAPBaseDNRequest
* @return string representation
*/
public String toString() {
return "JDAPDeleteRequest {entry=" + m_dn + "}";
return "DeleteRequest {entry=" + m_dn + "}";
}
}

View File

@@ -96,6 +96,6 @@ public class JDAPExtendedRequest implements JDAPProtocolOp {
* @return string representation of add request
*/
public String toString() {
return "JDAPExtendedRequest " + getParamString();
return "ExtendedRequest " + getParamString();
}
}

View File

@@ -109,7 +109,7 @@ public class JDAPModifyRequest extends JDAPBaseDNRequest
* @return string representation of request
*/
public String toString() {
String s = null;
String s = "";
for (int i = 0; i < m_mod.length; i++) {
if (i != 0)
s = s + "+";

View File

@@ -248,6 +248,6 @@ public class JDAPResult {
* @return string representation
*/
public String toString() {
return "JDAPResult " + getParamString();
return "Result " + getParamString();
}
}

View File

@@ -208,7 +208,7 @@ public class JDAPSearchRequest extends JDAPBaseDNRequest
s = s + m_attrs[i];
}
}
return "JDAPSearchRequest {baseObject=" + m_base_dn + ", scope=" +
return "SearchRequest {baseObject=" + m_base_dn + ", scope=" +
m_scope + ", derefAliases=" + m_deref + ",sizeLimit=" +
m_size_limit + ", timeLimit=" + m_time_limit + ", attrsOnly=" +
m_attrs_only + ", filter=" + m_filter + ", attributes=" +

View File

@@ -68,6 +68,6 @@ public class JDAPUnbindRequest implements JDAPProtocolOp {
* @return string representation
*/
public String toString() {
return "JDAPUnbindRequest {}";
return "UnbindRequest {}";
}
}

View File

@@ -79,6 +79,21 @@ public class LDAPPasswordExpiredControl extends LDAPStringControl {
public String getMessage() {
return m_msg;
}
public String toString() {
StringBuffer sb = new StringBuffer("{PasswordExpiredCtrl:");
sb.append(" isCritical=");
sb.append(isCritical());
sb.append(" msg=");
sb.append(m_msg);
sb.append("}");
return sb.toString();
}
}

View File

@@ -91,4 +91,19 @@ public class LDAPPasswordExpiringControl extends LDAPStringControl {
public static String parseResponse( LDAPControl[] controls ) {
return LDAPStringControl.parseResponse( controls, EXPIRING );
}
public String toString() {
StringBuffer sb = new StringBuffer("{PasswordExpiringCtrl:");
sb.append(" isCritical=");
sb.append(isCritical());
sb.append(" msg=");
sb.append(m_msg);
sb.append("}");
return sb.toString();
}
}

View File

@@ -74,6 +74,8 @@ public class LDAPProxiedAuthControl extends LDAPControl {
public final static String PROXIEDAUTHREQUEST =
"2.16.840.1.113730.3.4.12";
private String m_dn;
/**
* Constructs an <CODE>LDAPProxiedAuthControl</CODE> object with a
* DN to use as identity.
@@ -86,7 +88,7 @@ public class LDAPProxiedAuthControl extends LDAPControl {
public LDAPProxiedAuthControl( String dn,
boolean critical) {
super( PROXIEDAUTHREQUEST, critical, null );
m_value = createSpecification( dn );
m_value = createSpecification( m_dn = dn );
}
/**
@@ -103,5 +105,19 @@ public class LDAPProxiedAuthControl extends LDAPControl {
/* Suck out the data and return it */
return flattenBER( ber );
}
public String toString() {
StringBuffer sb = new StringBuffer("{ProxiedAuthCtrl:");
sb.append(" isCritical=");
sb.append(isCritical());
sb.append(" dn=");
sb.append(m_dn);
sb.append("}");
return sb.toString();
}
}

View File

@@ -216,8 +216,12 @@ public class LDAPSortControl extends LDAPControl {
public final static String SORTREQUEST = "1.2.840.113556.1.4.473";
public final static String SORTRESPONSE = "1.2.840.113556.1.4.474";
// Response varibales
private String m_failedAttribute = null;
private int m_resultCode = 0;
// Request variables
private LDAPSortKey[] m_keys;
/**
* Constructs a sort response <CODE>LDAPSortControl</CODE> object.
@@ -300,7 +304,8 @@ public class LDAPSortControl extends LDAPControl {
super( SORTREQUEST, critical, null );
LDAPSortKey[] keys = new LDAPSortKey[1];
keys[0] = key;
m_value = createSortSpecification( keys );
m_value = createSortSpecification( m_keys = keys );
}
/**
@@ -316,7 +321,7 @@ public class LDAPSortControl extends LDAPControl {
public LDAPSortControl(LDAPSortKey[] keys,
boolean critical) {
super( SORTREQUEST, critical, null );
m_value = createSortSpecification( keys );
m_value = createSortSpecification( m_keys = keys );
}
/**
@@ -561,6 +566,47 @@ public class LDAPSortControl extends LDAPControl {
/* Suck out the data and return it */
return flattenBER( ber );
}
public String toString() {
return (getID() == SORTREQUEST) ? reqToString() : rspToString();
}
String reqToString() {
StringBuffer sb = new StringBuffer("{SortCtrl:");
sb.append(" isCritical=");
sb.append(isCritical());
sb.append(" ");
for (int i=0; i < m_keys.length; i++) {
sb.append(m_keys[i]);
}
sb.append("}");
return sb.toString();
}
String rspToString() {
StringBuffer sb = new StringBuffer("{SortResponseCtrl:");
sb.append(" isCritical=");
sb.append(isCritical());
if (m_failedAttribute != null) {
sb.append(" failedAttr=");
sb.append(m_failedAttribute);
}
sb.append(" resultCode=");
sb.append(m_resultCode);
sb.append("}");
return sb.toString();
}
// register SORTRESPONSE with LDAPControl
static {

View File

@@ -428,6 +428,34 @@ public class LDAPVirtualListControl extends LDAPControl {
return flattenBER( seq );
}
public String toString() {
StringBuffer sb = new StringBuffer("{VirtListCtrl:");
sb.append(" isCritical=");
sb.append(isCritical());
sb.append(" beforeCount=");
sb.append(m_beforeCount);
sb.append(" afterCount=");
sb.append(m_afterCount);
sb.append(" listIndex=");
sb.append(m_listIndex);
sb.append(" listSize=");
sb.append(m_listSize);
if (m_context != null) {
sb.append(" conext=");
sb.append(m_context);
}
sb.append("}");
return sb.toString();
}
private final static int TAG_BYINDEX = 0;
private final static int TAG_BYFILTER = 1;
private int m_beforeCount = 0;

View File

@@ -184,6 +184,32 @@ public class LDAPVirtualListResponse extends LDAPControl {
return con;
}
public String toString() {
StringBuffer sb = new StringBuffer("{VirtListResponseCtrl:");
sb.append(" isCritical=");
sb.append(isCritical());
sb.append(" firstPosition=");
sb.append(m_firstPosition);
sb.append(" contentCount=");
sb.append(m_contentCount);
sb.append(" resultCode=");
sb.append(m_resultCode);
if (m_context != null) {
sb.append(" conext=");
sb.append(m_context);
}
sb.append("}");
return sb.toString();
}
private int m_firstPosition = 0;
private int m_contentCount = 0;
private int m_resultCode = -1;

View File

@@ -40,6 +40,7 @@
71=Affects multiple DSAs
80=Unknown error
81=Cannot contact LDAP server
85=Client Timelimit exceeded
89=Bad parameter to an LDAP method
91=Cannot connect to the LDAP server
92=Not supported by this version of the LDAP protocol

View File

@@ -40,6 +40,7 @@
71=Wirkt sich auf mehrere DSAs aus
80=Unbekannter Fehler
81=Verbindung zu LDAP-Server nicht möglich
85=Client-Zeitbeschränkung überschritten
89=Falscher Parameter für LDAP-Methode
91=Verbindung zu LDAP-Server nicht möglich
92=Wird von dieser Version des LDAP-Protokolls nicht unterstützt

View File

@@ -40,6 +40,7 @@
71=Concerne plusieurs DSA
80=Erreur inconnue
81=Impossible de contacter le serveur LDAP
85=Client délai dépassé
89=Mauvais paramètre attribué à une méthode LDAP
91=Impossible d'établir une connexion au serveur LDAP
92=Non pris en charge par cette version du protocole LDAP

View File

@@ -40,6 +40,7 @@
71=\u8907\u6570\u306E DSA \u306B\u5F71\u97FF\u3057\u307E\u3059
80=\u539F\u56E0\u4E0D\u660E\u306E\u30A8\u30E9\u30FC
81=LDAP \u30B5\u30FC\u30D0\u3068\u901A\u4FE1\u3067\u304D\u307E\u305B\u3093
85=\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u304C\u5236\u9650\u6642\u9593\u3092\u8D85\u904E\u3057\u307E\u3057\u305F
89=LDAP \u30E1\u30BD\u30C3\u30C9\u306B\u4E0D\u6B63\u306A\u30D1\u30E9\u30E1\u30FC\u30BF\u304C\u6E21\u3055\u308C\u307E\u3057\u305F
91=LDAP \u30B5\u30FC\u30D0\u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093
92=\u3053\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u306E LDAP \u30D7\u30ED\u30C8\u30B3\u30EB\u3067\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002