зеркало из https://github.com/mozilla/gecko-dev.git
JNDI LDAP Service Provider
This commit is contained in:
Родитель
075e9d09d6
Коммит
b8e4bc8655
|
@ -0,0 +1,118 @@
|
|||
# -*- 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) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
#
|
||||
# Makefile for the LDAP classes
|
||||
#
|
||||
# An optimized compile is done by default. You can specify "DEBUG=1" on
|
||||
# the make line to generate debug symbols in the bytecode.
|
||||
#
|
||||
ARCH := $(shell uname -s)
|
||||
|
||||
MCOM_ROOT=.
|
||||
ifeq ($(ARCH), WINNT)
|
||||
MOZ_DIR:=$(subst \,/,$(MOZ_SRC))
|
||||
BASEDIR:=$(MOZ_DIR)/mozilla/directory/java-sdk
|
||||
else
|
||||
ifeq ($(ARCH), WIN95)
|
||||
MOZ_DIR:=$(subst \,/,$(MOZ_SRC))
|
||||
BASEDIR:=$(MOZ_DIR)/mozilla/directory/java-sdk
|
||||
else
|
||||
BASEDIR := $(shell cd $(MCOM_ROOT); pwd)
|
||||
endif
|
||||
endif
|
||||
# Destination for class files and packages
|
||||
CLASS_DEST=$(BASEDIR)/dist/classes
|
||||
|
||||
# Set up the CLASSPATH automatically,
|
||||
ifeq ($(ARCH), WINNT)
|
||||
JDK := $(subst \,/,$(JAVA_HOME))
|
||||
JAR:=$(JDK)/bin/jar
|
||||
SEP=;
|
||||
else
|
||||
ifeq ($(ARCH), WIN95)
|
||||
JDK := $(subst \,/,$(JAVA_HOME))
|
||||
JAR:=$(JDK)/bin/jar
|
||||
SEP=;
|
||||
else
|
||||
JDK := $(JAVA_HOME)
|
||||
JAR:=$(JAVA_HOME)/bin/jar
|
||||
SEP=:
|
||||
endif
|
||||
endif
|
||||
JNDILIB:=$(BASEDIR)/ldapsp/lib/jndi.jar
|
||||
JAVACLASSPATH:=$(CLASS_DEST)$(SEP)$(BASEDIR)/ldapsp$(SEP)$(JDKLIB)$(SEP)$(JNDILIB)$(SEP)$(CLASSPATH)
|
||||
|
||||
SRCDIR=com/netscape/jndi/ldap
|
||||
DISTDIR=$(MCOM_ROOT)/dist
|
||||
CLASSDIR=$(MCOM_ROOT)/dist/classes
|
||||
CLASSPACKAGEDIR=$(DISTDIR)/packages
|
||||
#PACKAGENAME=jndi.zip
|
||||
ifeq ($(DEBUG), full)
|
||||
BASEPACKAGENAME=ldapsp_debug.jar
|
||||
else
|
||||
BASEPACKAGENAME=ldapsp.jar
|
||||
endif
|
||||
CLASSPACKAGE=$(CLASSPACKAGEDIR)/$(PACKAGENAME)
|
||||
MANIFEST=$(BASEDIR)/ldapsp/manifest.mf
|
||||
|
||||
ifndef JAVAC
|
||||
ifdef JAVA_HOME
|
||||
JDKBIN=$(JDK)/bin/
|
||||
endif
|
||||
ifeq ($(DEBUG), 1)
|
||||
JAVAC=$(JDKBIN)javac -g -classpath "$(JAVACLASSPATH)"
|
||||
else
|
||||
JAVAC=$(JDKBIN)javac -O -classpath "$(JAVACLASSPATH)"
|
||||
endif
|
||||
endif
|
||||
|
||||
all: classes
|
||||
|
||||
basics: $(DISTDIR) $(CLASSDIR)
|
||||
|
||||
classes: JNDICLASSES
|
||||
|
||||
basepackage: $(CLASSPACKAGEDIR)
|
||||
cd $(DISTDIR)/classes; rm -f ../packages/$(BASEPACKAGENAME); $(JAR) cvfm ../packages/$(BASEPACKAGENAME) $(MANIFEST) com/netscape/jndi/ldap/*.class com/netscape/jndi/ldap/common/*.class com/netscape/jndi/ldap/schema/*.class com/netscape/jndi/ldap/controls/*.class
|
||||
|
||||
MAIN: basics
|
||||
cd ldapsp/$(SRCDIR); $(JAVAC) -d $(CLASS_DEST) *.java
|
||||
|
||||
SCHEMA: basics
|
||||
cd ldapsp/$(SRCDIR)/schema; $(JAVAC) -d $(CLASS_DEST) *.java
|
||||
|
||||
COMMON: basics
|
||||
cd ldapsp/$(SRCDIR)/common; $(JAVAC) -d $(CLASS_DEST) *.java
|
||||
|
||||
CONTROLS: basics
|
||||
cd ldapsp/$(SRCDIR)/controls; $(JAVAC) -d $(CLASS_DEST) *.java
|
||||
|
||||
|
||||
JNDICLASSES: COMMON CONTROLS SCHEMA MAIN
|
||||
|
||||
clean:
|
||||
rm -rf $(DISTDIR)/classes/com/netscape/jndi/ldap
|
||||
|
||||
$(CLASSPACKAGEDIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(DISTDIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(CLASSDIR):
|
||||
mkdir -p $@
|
||||
|
|
@ -0,0 +1,541 @@
|
|||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Miodrag Kekic">
|
||||
<meta name="GENERATOR" content="Mozilla/4.5 [en]C-NSCP (WinNT; U) [Netscape]">
|
||||
<title>Netscape LDAP Service Provider - Readme</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>
|
||||
|
||||
Netscape LDAP Service Provider for JNDI (06-04-99)</h2>
|
||||
The Netscape LDAP service provider for JNDI implements the JNDI DirContext
|
||||
interface. It is implemented as a layer on top of the Netscape Directory
|
||||
SDK for Java (ldapjdk.jar). While the ldapjdk uses the LDAP connection
|
||||
as the primary abstraction enabling the access to the directory services,
|
||||
the JNDI provider uses the concept of a Directory Context (the
|
||||
DirContext interface) to achieve the same functionality. A DirContext as
|
||||
an equivalent of a directory entry in the ldapjdk.
|
||||
<p>The following sections are available in this document:
|
||||
<p><a href="#Using">Using Netscape Ldap Service Provider</a>
|
||||
<br><a href="#Env Props">Environment Properties</a>
|
||||
<br><a href="#Controls">Working With Controls</a>
|
||||
<br><a href="#Not Impl">What's Not Implemented</a>
|
||||
<br>
|
||||
<h3>
|
||||
<a NAME="Using"></a>Using Netscape LDAP Service Provider</h3>
|
||||
The current implementation is based on the JNDI 1.2 beta1. In addition
|
||||
to the DirContext interface implementation, the Netscape LDAP provider
|
||||
implements the new JNDI event service (<i>javax.naming.event</i> package)
|
||||
and support for controls (<i>javax.naming.ldap</i> package) which were
|
||||
introduced with the JNDI 1.2.
|
||||
<p>To use the service provider, you'll need to:
|
||||
<p>(1) Add the provider and the jars it depends on in the classpath. For
|
||||
example, on Windows NT the classpath should be set as follows:
|
||||
<p><tt>set classpath=%classpath%;ldapsp.jar;ldapjdk.jar;jndi.jar;</tt>
|
||||
<p>Assuming that all the jars are available in the current directory. The
|
||||
listed jar files are:
|
||||
<br>
|
||||
<table CELLSPACING=0 COLS=2 WIDTH="477" >
|
||||
<tr>
|
||||
<td WIDTH="100">ldapsp.jar </td>
|
||||
|
||||
<td WIDTH="400">Netscape LDAP Service Provider for JNDI</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ldapjdk.jar</td>
|
||||
|
||||
<td>Netscape Directory SDK for Java 3.1</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>jndi.jar</td>
|
||||
|
||||
<td>JNDI 1.2 beta1</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>(2) Specify the Netscape LDAP provider as the provider in the context
|
||||
environment created for the initial context;
|
||||
<br> <tt>Hashtable env = new Hashtable();</tt>
|
||||
<br><tt> env.put(Context.INITIAL_CONTEXT_FACTORY,</tt>
|
||||
<br><tt> "com.netscape.jndi.ldap.LdapContextFactory");</tt>
|
||||
<br><tt> env.put(...</tt>
|
||||
<br><tt> ...</tt>
|
||||
<br><tt> DirContext ctx = new InitialDirContext(env);</tt>
|
||||
<p>(3) For storing of Java objects in a LDAP Directory, the JNDI
|
||||
java object schema must be added to the directory. To enable the JNDI schema
|
||||
copy the file <i>jndi-object-schema.conf</i> to your <i><server-root>/slapd-<id>/config</i>
|
||||
directory, and include the file into your <i><server-root>/slapd-<id>/config/ns-schema.conf</i>
|
||||
schema configuration file.
|
||||
<p>For examples of using JNDI please go to the official JNDI site.
|
||||
<h3>
|
||||
<a NAME="Env Props"></a>Environment Properties</h3>
|
||||
The environment properties can be passed directly to the initial context
|
||||
as a hash table, or specified as system properties. For compatibility reasons,
|
||||
for those environment properties that are relevant to LDAP protocol but
|
||||
are not defined in the JNDI, the Netscape LDAP provider is using the same
|
||||
property names as the SUN LDAP service provided, if a property with the
|
||||
same semantics is defined by the SUN provider.
|
||||
<p>Note: If a new property is added to the context environment, or an existing
|
||||
property is changed after the initial context is created, the change will
|
||||
be immediately visible unless the changed property pertains to the connection.
|
||||
For changes related to connection, in order to take effect you'll need
|
||||
to invoke <i>LdapContext.reconnect().</i>
|
||||
<p>The following table contains JNDI environment properties are relevant
|
||||
for the Netscape LDAP service provider. Properties not found in this table
|
||||
are silently ignored.
|
||||
<br>
|
||||
<table BORDER CELLSPACING=0 COLS=2 WIDTH="100%" >
|
||||
<tr>
|
||||
<th WIDTH="20%" BGCOLOR="#000000"><font color="#FFFFFF">Environment Property</font></th>
|
||||
|
||||
<th BGCOLOR="#000000"><font color="#FFFFFF">Description</font></th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.factory.initial</td>
|
||||
|
||||
<td>
|
||||
<br>This environment property is used to select the LDAP provider. To select
|
||||
the Netscape LDAP provider "<b>com.netscape.jndi.ldap.LdapContextFactory</b>"
|
||||
should be specified.
|
||||
<p><tt> env.put(Context.INITIAL_CONTEXT_FACTORY, "com.netscape.jndi.ldap.LdapContextFactory");</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.provider.url</td>
|
||||
|
||||
<td>
|
||||
<br>Specifies LDAP server information. For example:
|
||||
<p><tt>env.put(Context.PROVIDER_URL, "ldap://dilly.mcom.com:389");</tt>
|
||||
<p>If it has not been set then the provider will attempt to access an LDAP
|
||||
server at port 389 on the local host.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.version</td>
|
||||
|
||||
<td>
|
||||
<br>Specifies the protocol version for the provider. Two values are
|
||||
<br>possible:
|
||||
<ul>
|
||||
<li>
|
||||
2 - selects LDAP Version 2 (LDAPv2)</li>
|
||||
|
||||
<li>
|
||||
3 - selects LDAP Version 3 (LDAPv3)</li>
|
||||
</ul>
|
||||
For example, <tt>env.put("java.naming.ldap.version", "3");</tt>
|
||||
<p>If this environment property has not been set then the provider will
|
||||
<br>attempt to use LDAPv3.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.security.authentication</td>
|
||||
|
||||
<td>
|
||||
<br>Specifies the authentication mechanism for the provider to use.
|
||||
<br>The following values are permitted for this property:
|
||||
<ul>
|
||||
<li>
|
||||
<b>none</b> - use no authentication
|
||||
(anonymous)</li>
|
||||
|
||||
<li>
|
||||
<b>simple</b> - use weak authentication (clear
|
||||
text password)</li>
|
||||
</ul>
|
||||
If this environment property has not been set but the
|
||||
java.naming.security.principal environment property has been
|
||||
<br>set then the provider will use 'simple'. If neither have been set then
|
||||
the provider will use anonymous bind.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td WIDTH="20%">java.naming.security.principal</td>
|
||||
|
||||
<td>
|
||||
<br>Specifies the DN of the principal to be authenticated. For example:
|
||||
<p><tt>env.put(Context.SECURITY_PRINCIPAL, "cn=Directory manager");</tt>
|
||||
<p>If this environment property has not been set then the provider
|
||||
<br>will use anonymous bind.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.security.credentials</td>
|
||||
|
||||
<td>
|
||||
<br>Specifies the password of the principal to be authenticated. For example:
|
||||
<p><tt>env.put(Context.SECURITY_CREDENTIALS, "secret");</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.security.protocol</td>
|
||||
|
||||
<td>
|
||||
<br> Specifies the security protocol for the provider to use. One
|
||||
possible value is defined: <b>ssl</b> - use Secure Socket Layer
|
||||
<p><tt> env.put(Context.SECURITY_PROTOCOL, "ssl");</tt>
|
||||
<p>When this environment property has been set and the
|
||||
<br> <i>java.naming.ldap.factory.socket</i> property has not been
|
||||
set, then
|
||||
<br>the ldapjdk default socket factory <i>netscape.net.SSLSocket</i>
|
||||
is used. This class is provided with Netscape Communicator 4.05 and higher.
|
||||
If java.naming.ldap.factory.socket property has been set, the
|
||||
<br>socket factory specified therein is used.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.factory.socket</td>
|
||||
|
||||
<td>Specifies the class name of a socket factory. This environment
|
||||
<br>property is used to override the default socket factory. For example:
|
||||
<p><tt>env.put("java.naming.ldap.factory.socket", "crysec.SSL.SSLSocket");</tt>
|
||||
<p>If the security protocol environment property has been set but
|
||||
this property has not been set, then this property's value is set to <i>netscape.net.SSLSocket</i>.
|
||||
See ldapjdk documentation for more information for connecting over SSL.
|
||||
<br> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.ssl.ciphers</td>
|
||||
|
||||
<td>Specifies the suite of ciphers used for SSL connections made through
|
||||
sockets created by the factory specified with <i>java.naming.ldap.factory.socket</i>.
|
||||
The value of this property is of type <i>java.lang.Object</i>. For example:
|
||||
<p><tt><font size=-1>try {</font></tt>
|
||||
<br><tt><font size=-1> Class c = Class.forName("crysec.SSL.SSLParams");</font></tt>
|
||||
<br><tt><font size=-1> java.lang.reflect.Method m = </font></tt>
|
||||
<br><tt><font size=-1>
|
||||
getMethod("getCipherSuite",new Class[0]);</font></tt>
|
||||
<br><tt><font size=-1> Object cipherSuite = m.invoke(null,null);</font></tt>
|
||||
<br><tt><font size=-1> if (cipherSuite != null) {</font></tt>
|
||||
<br><tt><font size=-1> env.put("java.naming.ldap.ssl.ciphers",
|
||||
cipherSuite);</font></tt>
|
||||
<br><tt><font size=-1> }</font></tt>
|
||||
<br><tt><font size=-1>}</font></tt>
|
||||
<br><tt><font size=-1>catch (Exception e) {}</font></tt>
|
||||
<br> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.batchsize</td>
|
||||
|
||||
<td>Specifies that search results are to be returned in batches. A setting
|
||||
of zero indicates that the provider should block until all results have
|
||||
been received. If this environment property has not been set then search
|
||||
results are returned in batches of one.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.maxresults</td>
|
||||
|
||||
<td>
|
||||
<br>The default maximum number of search results to be returned for
|
||||
a search request. 0 means no limit. If not specified, the ldapjdk default
|
||||
is 1000. This value can be overridden per request with the parameter <i>SearchConstraints</i>
|
||||
in the <i>DirContex.search()</i> method.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.timelimit</td>
|
||||
|
||||
<td>The default maximum number of milliseconds to wait for a search operation
|
||||
to complete. If 0, which is the ldapjdk default, there is no maximum time
|
||||
limit for a search operation. This value can be overridden per request
|
||||
with the parameter <i>SearchConstraints</i> in the <i>DirContex.search()</i>
|
||||
method.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.referral</td>
|
||||
|
||||
<td>
|
||||
<br> Specifies how referrals shall be handled by the provider. Three
|
||||
possible values are defined:
|
||||
<ul>
|
||||
<li>
|
||||
<b> follow</b> - automatically follow any referrals</li>
|
||||
|
||||
<li>
|
||||
<b>throw</b> - throw a ReferralException for each referral</li>
|
||||
|
||||
<li>
|
||||
<b>ignore</b> - ignore referrals if they appear in results and treat
|
||||
them like ordinary attributes if they appear in entries.</li>
|
||||
</ul>
|
||||
If this environment property has not been set then the LDAP provider by
|
||||
default follows referrals.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.referral.limit</td>
|
||||
|
||||
<td>
|
||||
<br>Specifies the maximum number of referrals to follow in a chain of
|
||||
<br>referrals. A setting of zero indicates that there is no limit. The
|
||||
default limit is 10.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.deleteRDN</td>
|
||||
|
||||
<td> Specifies whether the old RDN is removed during rename().
|
||||
<br> If the value is "true", the old RDN is removed; otherwise,
|
||||
<br> the RDN is not removed. The default value is true.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.derefAliases</td>
|
||||
|
||||
<td>
|
||||
<br> Specifies how aliases are dereferenced during search operations.
|
||||
<br> The possible values are:
|
||||
<ul>
|
||||
<li>
|
||||
<b>always</b> always dereference
|
||||
aliases</li>
|
||||
|
||||
<li>
|
||||
<b>never</b> never dereference
|
||||
aliases</li>
|
||||
|
||||
<li>
|
||||
<b>finding</b> dereference aliases
|
||||
only during name resolution</li>
|
||||
|
||||
<li>
|
||||
<b>searching</b> dereference aliases only after name resolution</li>
|
||||
</ul>
|
||||
NOTE: Netscape LDAP Server 3.x and 4.x do not support aliases</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.typesOnly</td>
|
||||
|
||||
<td>
|
||||
<br> Specifies whether only attribute types are to be returned during
|
||||
<br> searches and getAttributes(). Its possible values are "true"
|
||||
or "false". The default is false.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.conntrol.connect</td>
|
||||
|
||||
<td>An array of <i>Control</i>s to be set on the LDAPConnection before
|
||||
a connection attempt is made to the server. </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.attributes.binary</td>
|
||||
|
||||
<td>Specifies attributes that have binary syntax. It extends the provider's
|
||||
list of known binary attributes. Its value is a space separated list of
|
||||
attribute names.
|
||||
<p><tt>env.put("java.naming.ldap.attributes.binary", "mpegVideo");</tt>
|
||||
<p>In contrast to ldapjdk, JNDI does not provide for reading of attribute
|
||||
values as either Strings or byte arrays. All attributes are returned as
|
||||
Strings unless recognized as having binary syntax. The values of attributes
|
||||
that have binary syntax are returned as byte arrays instead of Strings.
|
||||
<p>If this environment property has not been set then, by default, only
|
||||
the following attributes are considered to have binary syntax:
|
||||
<ul>
|
||||
<li>
|
||||
attribute names containing '<b>;binary'</b></li>
|
||||
|
||||
<li>
|
||||
photo
|
||||
(0.9.2342.19200300.100.1.7)</li>
|
||||
|
||||
<li>
|
||||
personalSignature (0.9.2342.19200300.100.1.53)</li>
|
||||
|
||||
<li>
|
||||
audio
|
||||
(0.9.2342.19200300.100.1.55)</li>
|
||||
|
||||
<li>
|
||||
jpegPhoto
|
||||
(0.9.2342.19200300.100.1.60)</li>
|
||||
|
||||
<li>
|
||||
javaSerializedData (1.3.6.1.4.1.42.2.27.4.1.7)</li>
|
||||
|
||||
<li>
|
||||
thumbnailPhoto (1.3.6.1.4.1.1466.101.120.35)</li>
|
||||
|
||||
<li>
|
||||
thumbnailLogo (1.3.6.1.4.1.1466.101.120.36)</li>
|
||||
|
||||
<li>
|
||||
userPassword
|
||||
(2.5.4.35)</li>
|
||||
|
||||
<li>
|
||||
userCertificate (2.5.4.36)</li>
|
||||
|
||||
<li>
|
||||
cACertificate
|
||||
(2.5.4.37)</li>
|
||||
|
||||
<li>
|
||||
authorityRevocationList (2.5.4.38)</li>
|
||||
|
||||
<li>
|
||||
certificateRevocationList (2.5.4.39)</li>
|
||||
|
||||
<li>
|
||||
crossCertificatePair
|
||||
(2.5.4.40)</li>
|
||||
|
||||
<li>
|
||||
x500UniqueIdentifier (2.5.4.45)</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>java.naming.ldap.ref.separator</td>
|
||||
|
||||
<td>Specifies the character to use when encoding a RefAddr object in
|
||||
<br>the javaReferenceAddress attribute. This environment property should
|
||||
be used to avoid a conflict in the case where the default separator
|
||||
character appears in the components of a RefAddr object.
|
||||
<p> If unspecified, the default separator is the hash character '#'.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>
|
||||
<a NAME="Controls"></a>Working with Controls</h3>
|
||||
JNDI 1.2 adds support for Controls which are fully implemented with the
|
||||
Netscape LDAP provider. However, JNDI 1.2 does not define interfaces for
|
||||
any of the standard controls, like for example the sort control. Instead,
|
||||
the task of defining particular controls and their interfaces is left to
|
||||
service providers. Therefore, if using controls, you will also need to
|
||||
import the <i>com.netscape.jndi.ldap.controls</i> package in your
|
||||
souce in addition to the JNDI packages.
|
||||
<p>Being implemented on the top of ldapjdk, the Netscape LDAP provider
|
||||
simply exposes all of the ldapjdk controls as JNDI controls. Thus, the
|
||||
control APIs are exactly the same as in ldapjdk. The only difference is
|
||||
that for the LDAP provider controls class names start with "Ldap"
|
||||
while in ldapjdk the class names start with "LDAP". For instance, the ldapjdk
|
||||
control LDAPSortControl is LdapSortControl in the Netscape LDAP provider.
|
||||
<p>Here is an example of how to use the LdapSortControl. Notice that you'll
|
||||
need to obtain a LdapContext object as an initial context, because controls
|
||||
are not part of the directory context (DirContext). That means that instead
|
||||
of calling <i>getInitialDirContext()</i> you 'll need to call <i>getInitialLdapContext()</i>.
|
||||
<p><tt>import java.util.Hashtable;</tt>
|
||||
<br><tt>import javax.naming.*;</tt>
|
||||
<br><tt>import javax.naming.directory.*;</tt>
|
||||
<br><b><tt>import javax.naming.ldap.*;</tt></b>
|
||||
<br><b><tt>import com.netscape.jndi.ldap.controls.*;</tt></b>
|
||||
<p><tt>public class SortReverseOrder {</tt>
|
||||
<p><tt>public static void main(String[] args) {</tt>
|
||||
<p><tt> Hashtable env = new Hashtable(5, 0.75f);</tt>
|
||||
<br><tt> /*</tt>
|
||||
<br><tt> * Specify the initial context implementation
|
||||
to use.</tt>
|
||||
<br><tt> */</tt>
|
||||
<br><tt> env.put(Context.INITIAL_CONTEXT_FACTORY,</tt>
|
||||
<br><tt> "com.netscape.jndi.ldap.LdapContextFactory");</tt>
|
||||
<p><tt> /* Specify host and port to use for directory
|
||||
service */</tt>
|
||||
<br><tt> //env.put(Context.PROVIDER_URL, "ldap://localhost:389");</tt>
|
||||
<p><tt> LdapContext ctx = null;</tt>
|
||||
<br><tt> try {</tt>
|
||||
<br><tt> /* get a handle to an
|
||||
Initial DirContext */</tt>
|
||||
<br><tt> <b>ctx = new InitialLdapContext(env,
|
||||
null);</b></tt>
|
||||
<p><tt> /* specify search constraints
|
||||
to search subtree */</tt>
|
||||
<br><tt> SearchControls cons
|
||||
= new SearchControls();</tt>
|
||||
<br><tt> cons.setSearchScope(SearchControls.SUBTREE_SCOPE);</tt>
|
||||
<br><tt> cons.setReturningAttributes(new
|
||||
String[] { "sn" });</tt>
|
||||
<p><tt> // specify sort control</tt>
|
||||
<br><tt> <b>ctx.setRequestControls(</b></tt>
|
||||
<br><tt>
|
||||
<b>new
|
||||
Control[] {new LdapSortControl(</b></tt>
|
||||
<br><tt>
|
||||
|
||||
<b>new LdapSortKey[]{</b></tt>
|
||||
<br><tt>
|
||||
|
||||
<b>new LdapSortKey("sn", true,null)},Control.CRITICAL)});</b></tt>
|
||||
<p><tt> /* search for all entries
|
||||
with surname of Jensen */</tt>
|
||||
<br><tt> NamingEnumeration results</tt>
|
||||
<br><tt>
|
||||
= ctx.search("o=mcom.com", "(objectclass=person)", cons);</tt>
|
||||
<p><tt> /* for each entry print
|
||||
out name + all attrs and values */</tt>
|
||||
<br><tt> while (results != null
|
||||
&& results.hasMore()) {</tt>
|
||||
<br><tt>
|
||||
SearchResult si = (SearchResult)results.next();</tt>
|
||||
<p><tt>
|
||||
Attributes attrs = si.getAttributes();</tt>
|
||||
<br><tt>
|
||||
/* print each attribute */</tt>
|
||||
<br><tt>
|
||||
for (NamingEnumeration ae = attrs.getAll(); ae.hasMoreElements();) {</tt>
|
||||
<br><tt>
|
||||
Attribute attr = (Attribute)ae.next();</tt>
|
||||
<br><tt>
|
||||
String attrId = attr.getID();</tt>
|
||||
<p><tt>
|
||||
/* print each value */</tt>
|
||||
<br><tt>
|
||||
for (NamingEnumeration vals = attr.getAll(); vals.hasMore();</tt>
|
||||
<br><tt>
|
||||
System.out.println(attrId + ": " + vals.next()));</tt>
|
||||
<br><tt>
|
||||
}</tt>
|
||||
<br><tt>
|
||||
System.out.println();</tt>
|
||||
<br><tt> }</tt>
|
||||
<br><tt> }</tt>
|
||||
<br><tt> catch (NamingException e) {</tt>
|
||||
<br><tt> System.err.println("Search
|
||||
example failed.");</tt>
|
||||
<br><tt> e.printStackTrace();</tt>
|
||||
<br><tt> }</tt>
|
||||
<br><tt> finally {</tt>
|
||||
<br><tt> // cleanup</tt>
|
||||
<br><tt> if (ctx != null) {</tt>
|
||||
<br><tt> try
|
||||
{ ctx.close(); } catch (Exception e) {}</tt>
|
||||
<br><tt> }</tt>
|
||||
<br><tt> }</tt>
|
||||
<br><tt>}</tt>
|
||||
<br><tt>}</tt>
|
||||
<p>For full documenation on available controls and their interfaces, please
|
||||
check the ldapjdk documentation.
|
||||
<h3>
|
||||
<a NAME="Not Impl"></a>What's Not Implemented</h3>
|
||||
Currently, the following JNDI features are not implemented by the Netscape
|
||||
JNDI provider:
|
||||
<ul>
|
||||
<li>
|
||||
Support for federated names</li>
|
||||
|
||||
<li>
|
||||
Support for the code base attribute for objects stored in LDAP directory.
|
||||
Therefore, the class name specified with the <i>javaClassName</i> attribute
|
||||
must be available in the local <i>CLASSPATH</i>.</li>
|
||||
|
||||
<li>
|
||||
<i>search()</i> method for schema directory contexts. Instead of <i>DirContext.search()</i>,
|
||||
the <i>Context.lookup()</i> request should be used for a schema directory
|
||||
context.</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,312 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Wrapper for LDAPAttributes which implements JNDI Attribute interface
|
||||
*/
|
||||
class AttributesImpl implements Attributes {
|
||||
|
||||
// TODO Create JndiAttribute class so that getAttributeDefinition and
|
||||
// getAttributeSyntaxDefinition can be implemented
|
||||
|
||||
LDAPAttributeSet m_attrSet;
|
||||
|
||||
/**
|
||||
* A list of predefined binary attribute name
|
||||
*/
|
||||
static String[] m_binaryAttrs = {
|
||||
"photo", "userpassword", "jpegphoto", "audio", "thumbnailphoto", "thumbnaillogo",
|
||||
"usercertificate", "cacertificate", "certificaterevocationlist",
|
||||
"authorityrevocationlist", "crosscertificatepair", "personalsignature",
|
||||
"x500uniqueidentifier", "javaserializeddata"};
|
||||
|
||||
/**
|
||||
* A list of user defined binary attributes specified with the environment
|
||||
* property java.naming.ldap.attributes.binary
|
||||
*/
|
||||
static String[] m_userBinaryAttrs = null;
|
||||
|
||||
public AttributesImpl(LDAPAttributeSet attrSet, String[] userBinaryAttrs) {
|
||||
m_attrSet = attrSet;
|
||||
m_userBinaryAttrs = userBinaryAttrs;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new AttributesImpl((LDAPAttributeSet)m_attrSet.clone(), m_userBinaryAttrs);
|
||||
}
|
||||
|
||||
public Attribute get(String attrID) {
|
||||
LDAPAttribute attr = m_attrSet.getAttribute(attrID);
|
||||
return (attr == null) ? null : ldapAttrToJndiAttr(attr);
|
||||
}
|
||||
|
||||
public NamingEnumeration getAll() {
|
||||
return new AttributeEnum(m_attrSet.getAttributes());
|
||||
}
|
||||
|
||||
public NamingEnumeration getIDs() {
|
||||
return new AttributeIDEnum(m_attrSet.getAttributes());
|
||||
}
|
||||
|
||||
public boolean isCaseIgnored() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Attribute put(String attrID, Object val) {
|
||||
LDAPAttribute attr = m_attrSet.getAttribute(attrID);
|
||||
if (val == null) { // no Value
|
||||
m_attrSet.add(new LDAPAttribute(attrID));
|
||||
}
|
||||
else if (val instanceof byte[]) {
|
||||
m_attrSet.add(new LDAPAttribute(attrID, (byte[])val));
|
||||
}
|
||||
else {
|
||||
m_attrSet.add(new LDAPAttribute(attrID, val.toString()));
|
||||
}
|
||||
return (attr == null) ? null : ldapAttrToJndiAttr(attr);
|
||||
}
|
||||
|
||||
public Attribute put(Attribute jndiAttr) {
|
||||
try {
|
||||
LDAPAttribute oldAttr = m_attrSet.getAttribute(jndiAttr.getID());
|
||||
m_attrSet.add(jndiAttrToLdapAttr(jndiAttr));
|
||||
return (oldAttr == null) ? null : ldapAttrToJndiAttr(oldAttr);
|
||||
}
|
||||
catch (NamingException e) {
|
||||
System.err.println( "Error in AttributesImpl.put(): " + e.toString() );
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Attribute remove(String attrID) {
|
||||
Attribute attr = get(attrID);
|
||||
m_attrSet.remove(attrID);
|
||||
return attr;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return m_attrSet.size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if an attribute is a binary one
|
||||
*/
|
||||
static boolean isBinaryAttribute(String attrID) {
|
||||
|
||||
// attr name contains ";binary"
|
||||
if (attrID.indexOf(";binary") >=0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
attrID = attrID.toLowerCase();
|
||||
|
||||
// check the predefined binary attr table
|
||||
for (int i=0; i < m_binaryAttrs.length; i++) {
|
||||
if (m_binaryAttrs[i].equals(attrID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// check user specified binary attrs with
|
||||
for (int i=0; m_userBinaryAttrs != null && i < m_userBinaryAttrs.length; i++) {
|
||||
if (m_userBinaryAttrs[i].equals(attrID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a JNDI Attributes object into a LDAPAttributeSet
|
||||
*/
|
||||
static LDAPAttributeSet jndiAttrsToLdapAttrSet(Attributes jndiAttrs) throws NamingException{
|
||||
LDAPAttributeSet attrs = new LDAPAttributeSet();
|
||||
for (Enumeration enum = jndiAttrs.getAll(); enum.hasMoreElements();) {
|
||||
attrs.add(jndiAttrToLdapAttr((Attribute) enum.nextElement()));
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a JNDI Attribute to a LDAPAttribute
|
||||
*/
|
||||
static LDAPAttribute jndiAttrToLdapAttr(Attribute jndiAttr) throws NamingException{
|
||||
LDAPAttribute attr = new LDAPAttribute(jndiAttr.getID());
|
||||
|
||||
for (NamingEnumeration vals = jndiAttr.getAll(); vals.hasMoreElements();) {
|
||||
Object val = vals.nextElement();
|
||||
if (val == null) {
|
||||
; // no value
|
||||
}
|
||||
else if (val instanceof byte[]) {
|
||||
attr.addValue((byte[])val);
|
||||
}
|
||||
else {
|
||||
attr.addValue(val.toString());
|
||||
}
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a LDAPAttribute to a JNDI Attribute
|
||||
*/
|
||||
static Attribute ldapAttrToJndiAttr(LDAPAttribute attr) {
|
||||
BasicAttribute jndiAttr = new BasicAttribute(attr.getName());
|
||||
Enumeration enumVals = null;
|
||||
if (isBinaryAttribute(attr.getName())) {
|
||||
enumVals = attr.getByteValues();
|
||||
}
|
||||
else {
|
||||
enumVals = attr.getStringValues();
|
||||
}
|
||||
if (enumVals != null) {
|
||||
while ( enumVals.hasMoreElements() ) {
|
||||
jndiAttr.add(enumVals.nextElement());
|
||||
}
|
||||
}
|
||||
return jndiAttr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert and array of JNDI ModificationItem to a LDAPModificationSet
|
||||
*/
|
||||
static LDAPModificationSet jndiModsToLdapModSet(ModificationItem[] jndiMods) throws NamingException{
|
||||
LDAPModificationSet mods = new LDAPModificationSet();
|
||||
for (int i=0; i < jndiMods.length; i++) {
|
||||
int modop = jndiMods[i].getModificationOp();
|
||||
LDAPAttribute attr = jndiAttrToLdapAttr(jndiMods[i].getAttribute());
|
||||
if (modop == DirContext.ADD_ATTRIBUTE) {
|
||||
mods.add(LDAPModification.ADD, attr);
|
||||
}
|
||||
else if (modop == DirContext.REPLACE_ATTRIBUTE) {
|
||||
mods.add(LDAPModification.REPLACE, attr);
|
||||
}
|
||||
else if (modop == DirContext.REMOVE_ATTRIBUTE) {
|
||||
mods.add(LDAPModification.DELETE, attr);
|
||||
}
|
||||
else {
|
||||
// Should never come here. ModificationItem can not
|
||||
// be constructed with a wrong value
|
||||
}
|
||||
}
|
||||
return mods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a LDAPModificationSet from a JNDI mod operation and JNDI Attributes
|
||||
*/
|
||||
static LDAPModificationSet jndiAttrsToLdapModSet(int modop, Attributes jndiAttrs) throws NamingException{
|
||||
LDAPModificationSet mods = new LDAPModificationSet();
|
||||
for (NamingEnumeration attrEnum = jndiAttrs.getAll(); attrEnum.hasMore();) {
|
||||
LDAPAttribute attr = jndiAttrToLdapAttr((Attribute)attrEnum.next());
|
||||
if (modop == DirContext.ADD_ATTRIBUTE) {
|
||||
mods.add(LDAPModification.ADD, attr);
|
||||
}
|
||||
else if (modop == DirContext.REPLACE_ATTRIBUTE) {
|
||||
mods.add(LDAPModification.REPLACE, attr);
|
||||
}
|
||||
else if (modop == DirContext.REMOVE_ATTRIBUTE) {
|
||||
mods.add(LDAPModification.DELETE, attr);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Illegal Attribute Modification Operation");
|
||||
}
|
||||
}
|
||||
return mods;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for enumeration of LDAPAttrubute-s. Convert each LDAPAttribute
|
||||
* into a JNDI Attribute accessed through the NamingEnumeration
|
||||
*/
|
||||
class AttributeEnum implements NamingEnumeration {
|
||||
|
||||
Enumeration _attrEnum;
|
||||
|
||||
public AttributeEnum(Enumeration attrEnum) {
|
||||
_attrEnum = attrEnum;
|
||||
}
|
||||
|
||||
public Object next() throws NamingException{
|
||||
LDAPAttribute attr = (LDAPAttribute) _attrEnum.nextElement();
|
||||
return AttributesImpl.ldapAttrToJndiAttr(attr);
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
LDAPAttribute attr = (LDAPAttribute) _attrEnum.nextElement();
|
||||
return AttributesImpl.ldapAttrToJndiAttr(attr);
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException{
|
||||
return _attrEnum.hasMoreElements();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return _attrEnum.hasMoreElements();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for enumeration of LDAPAttrubute-s. Return the name for each
|
||||
* LDAPAttribute accessed through the NamingEnumeration
|
||||
*/
|
||||
class AttributeIDEnum implements NamingEnumeration {
|
||||
|
||||
Enumeration _attrEnum;
|
||||
|
||||
public AttributeIDEnum(Enumeration attrEnum) {
|
||||
_attrEnum = attrEnum;
|
||||
}
|
||||
|
||||
public Object next() throws NamingException{
|
||||
LDAPAttribute attr = (LDAPAttribute) _attrEnum.nextElement();
|
||||
return attr.getName();
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
LDAPAttribute attr = (LDAPAttribute) _attrEnum.nextElement();
|
||||
return attr.getName();
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException{
|
||||
return _attrEnum.hasMoreElements();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return _attrEnum.hasMoreElements();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
import com.netscape.jndi.ldap.common.ExceptionMapper;
|
||||
|
||||
import netscape.ldap.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Wrapper for the LDAPSearchResult. Convert each LDAPEntry entry into
|
||||
* a JNDI Binding. Bindings are accessed through the NamingEnumeration
|
||||
* interface
|
||||
*/
|
||||
class BindingEnum implements NamingEnumeration {
|
||||
|
||||
LDAPSearchResults m_res;
|
||||
LdapContextImpl m_ctx;
|
||||
Name m_ctxName;
|
||||
|
||||
public BindingEnum(LDAPSearchResults res, LdapContextImpl ctx) throws NamingException {
|
||||
m_res = res;
|
||||
m_ctx = ctx;
|
||||
try {
|
||||
m_ctxName = LdapNameParser.getParser().parse(m_ctx.m_ctxDN);
|
||||
}
|
||||
catch ( NamingException e ) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object next() throws NamingException{
|
||||
try {
|
||||
LDAPEntry entry = m_res.next();
|
||||
String name = LdapNameParser.getRelativeName(m_ctxName, entry.getDN());
|
||||
Object obj = ObjectMapper.entryToObject(entry, m_ctx);
|
||||
String className = obj.getClass().getName();
|
||||
return new Binding(name, className, obj, /*isRelative=*/true);
|
||||
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(m_ctx, e);
|
||||
}
|
||||
catch ( LDAPException e ) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
try {
|
||||
return next();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
System.err.println( "Error in BindingEnum.nextElement(): " + e.toString() );
|
||||
e.printStackTrace(System.err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException{
|
||||
return m_res.hasMoreElements();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return m_res.hasMoreElements();
|
||||
}
|
||||
|
||||
public void close() throws NamingException{
|
||||
try {
|
||||
m_ctx.m_ldapSvc.getConnection().abandon(m_res);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,535 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import com.netscape.jndi.ldap.common.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Context Environment
|
||||
*/
|
||||
class ContextEnv extends ShareableEnv {
|
||||
|
||||
public static final String DEFAULT_HOST = "localhost";
|
||||
public static final int DEFAULT_PORT = LDAPv2.DEFAULT_PORT;
|
||||
public static final int DEFAULT_SSL_PORT = 636;
|
||||
public static final int DEFAULT_LDAP_VERSION = 3;
|
||||
|
||||
// JNDI defined environment propertiies
|
||||
public static final String P_PROVIDER_URL = Context.PROVIDER_URL;
|
||||
public static final String P_SECURITY_PROTOCOL = Context.SECURITY_PROTOCOL;
|
||||
public static final String P_SECURITY_AUTHMODE = Context.SECURITY_AUTHENTICATION;
|
||||
public static final String P_USER_DN = Context.SECURITY_PRINCIPAL;
|
||||
public static final String P_USER_PASSWORD = Context.SECURITY_CREDENTIALS;
|
||||
public static final String P_APPLET = Context.APPLET;
|
||||
public static final String P_AUTHORITATIVE = Context.AUTHORITATIVE;
|
||||
public static final String P_LANGUAGE = Context.LANGUAGE;
|
||||
public static final String P_BATCHSIZE = Context.BATCHSIZE;
|
||||
public static final String P_REFERRAL_MODE = Context.REFERRAL;
|
||||
|
||||
// Custom properties
|
||||
public static final String P_CONNECT_CTRLS = "java.naming.ldap.control.connect";
|
||||
public static final String P_BINARY_ATTRS = "java.naming.ldap.attributes.binary";
|
||||
public static final String P_ATTRS_ONLY = "java.naming.ldap.typesOnly";
|
||||
public static final String P_DELETE_OLDRDN = "java.naming.ldap.deleteRDN";
|
||||
public static final String P_SOCKET_FACTORY = "java.naming.ldap.factory.socket";
|
||||
public static final String P_CIPHER_SUITE = "java.naming.ldap.ssl.ciphers"; // new
|
||||
public static final String P_TIME_LIMIT = "java.naming.ldap.timelimit"; // new
|
||||
public static final String P_MAX_RESULTS = "java.naming.ldap.maxresults"; // new
|
||||
public static final String P_DEREF_ALIASES = "java.naming.ldap.derefAliases";
|
||||
public static final String P_REFERRAL_HOPLIMIT = "java.naming.referral.limit";
|
||||
public static final String P_LDAP_VERSION = "java.naming.ldap.version";
|
||||
public static final String P_JNDIREF_SEPARATOR = "java.naming.ref.separator";
|
||||
|
||||
// Possible values for the Context.REFERRAL env property
|
||||
private static final String V_REFERRAL_FOLLOW = "follow";
|
||||
private static final String V_REFERRAL_IGNORE = "ignore";
|
||||
private static final String V_REFERRAL_THROW_EXCEPTION = "throw";
|
||||
|
||||
// Possible values for the java.naming.ldap.derefAliases env property
|
||||
private static final String V_DEREF_NEVER = "never";
|
||||
|
||||
private static final String V_DEREF_SEARCHING = "searching";
|
||||
private static final String V_DEREF_FINDING = "finding";
|
||||
private static final String V_DEREF_ALWAYS = "always";
|
||||
|
||||
// Possible values for the java.naming... env property
|
||||
private static final String V_AUTH_NONE = "none";
|
||||
private static final String V_AUTH_SIMPLE = "simple";
|
||||
private static final String V_AUTH_STRONG = "strong";
|
||||
|
||||
/**
|
||||
* Constructor for non root Contexts
|
||||
*
|
||||
* @param parent A reference to the parent context environment
|
||||
* @param parentSharedEnvIdx index into parent's shared environemnt list
|
||||
*/
|
||||
public ContextEnv(ShareableEnv parent, int parentSharedEnvIdx) {
|
||||
super(parent, parentSharedEnvIdx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the root context
|
||||
*
|
||||
* @param initialEnv a hashtable with environemnt properties
|
||||
*/
|
||||
public ContextEnv(Hashtable initialEnv) {
|
||||
super(initialEnv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone ContextEnv
|
||||
*
|
||||
* @return A "clone" of the current context environment
|
||||
*/
|
||||
/**
|
||||
* Clone ShareableEnv
|
||||
* The code is the same as in the superclass (ShareableEnv) except that
|
||||
* a ContextEnv instance is returned
|
||||
*
|
||||
* @return A "clone" of the current context environment
|
||||
*/
|
||||
public Object clone() {
|
||||
|
||||
// First freeze updates for this context
|
||||
freezeUpdates();
|
||||
|
||||
// If the context has been modified, then it is the parent of the clone
|
||||
if (m_sharedEnv != null) {
|
||||
return new ContextEnv(this, m_sharedEnv.size()-1);
|
||||
}
|
||||
|
||||
// No changes has been done to the inherited parent context. Pass the parent
|
||||
// context to the clone
|
||||
else {
|
||||
return new ContextEnv(m_parentEnv, m_parentSharedEnvIdx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update property value. Properties that pertain to LDAPSearchConstraints
|
||||
* are immediately propagated. To take effect of properties that are connection
|
||||
* related, (like user name/password, ssl mode) the context mujst be reconnected
|
||||
* after the change of environment
|
||||
*/
|
||||
Object updateProperty(String name, Object val, LDAPSearchConstraints cons) throws NamingException{
|
||||
Object oldVal = getProperty(name);
|
||||
setProperty(name,val);
|
||||
try {
|
||||
if (name.equalsIgnoreCase(P_BATCHSIZE)) {
|
||||
updateBatchSize(cons);
|
||||
}
|
||||
else if (name.equalsIgnoreCase(P_TIME_LIMIT)) {
|
||||
updateTimeLimit(cons);
|
||||
}
|
||||
else if (name.equalsIgnoreCase(P_MAX_RESULTS)) {
|
||||
updateMaxResults(cons);
|
||||
}
|
||||
else if (name.equalsIgnoreCase(P_DEREF_ALIASES)) {
|
||||
updateDerefAliases(cons);
|
||||
}
|
||||
else if (name.equalsIgnoreCase(P_REFERRAL_MODE)) {
|
||||
updateReferralMode(cons);
|
||||
}
|
||||
else if (name.equalsIgnoreCase(P_REFERRAL_HOPLIMIT)) {
|
||||
updateReferralHopLimit(cons);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
if (oldVal == null) {
|
||||
removeProperty(name);
|
||||
}
|
||||
else {
|
||||
setProperty(name, oldVal);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return oldVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize LDAPSearchConstraints with environment properties
|
||||
*/
|
||||
void updateSearchCons(LDAPSearchConstraints cons) throws NamingException{
|
||||
updateBatchSize(cons);
|
||||
updateTimeLimit(cons);
|
||||
updateMaxResults(cons);
|
||||
updateDerefAliases(cons);
|
||||
updateReferralMode(cons);
|
||||
updateReferralHopLimit(cons);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the suggested number of result to return at a time during search in the
|
||||
* default SearchConstraints for the connection.
|
||||
* Specified with the env property java.naming.batchsize
|
||||
*/
|
||||
void updateBatchSize(LDAPSearchConstraints cons) {
|
||||
String size = (String)getProperty(P_BATCHSIZE);
|
||||
if (size != null) {
|
||||
int n = -1;
|
||||
try {
|
||||
n = Integer.parseInt(size);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalArgumentException("Illegal value for " + P_BATCHSIZE);
|
||||
}
|
||||
cons.setBatchSize(n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of miliseconds to wait for any operation under default
|
||||
* SearchConstraints for the connection.
|
||||
* Specified with the env property java.naming.ldap.timelimit
|
||||
* Note: sun ldap does not have this property
|
||||
*/
|
||||
void updateTimeLimit(LDAPSearchConstraints cons) {
|
||||
String millis = (String)getProperty(P_TIME_LIMIT);
|
||||
if (millis != null) {
|
||||
int n = -1;
|
||||
try {
|
||||
n = Integer.parseInt(millis);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalArgumentException("Illegal value for " + P_TIME_LIMIT);
|
||||
}
|
||||
cons.setTimeLimit(n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of search results to be returned under default
|
||||
* SearchConstraints for the connection.
|
||||
* Specified with the env property java.naming.ldap.maxresults
|
||||
* Note: sun ldap does not have this property
|
||||
*/
|
||||
void updateMaxResults(LDAPSearchConstraints cons) {
|
||||
String max = (String)getProperty(P_MAX_RESULTS);
|
||||
if (max != null) {
|
||||
int n = -1;
|
||||
try {
|
||||
n = Integer.parseInt(max);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal value for " + P_MAX_RESULTS);
|
||||
}
|
||||
cons.setMaxResults(n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set how aliases should be dereferenced under default SearchConstraints for the
|
||||
* connection.
|
||||
* Specified with the env property java.naming.ldap.derefAliases
|
||||
*/
|
||||
final void updateDerefAliases(LDAPSearchConstraints cons) throws IllegalArgumentException{
|
||||
String deref = (String)getProperty(P_DEREF_ALIASES);
|
||||
if(deref != null) {
|
||||
if(deref.equalsIgnoreCase(V_DEREF_NEVER)) {
|
||||
cons.setDereference(LDAPv2.DEREF_NEVER);
|
||||
}
|
||||
else if(deref.equalsIgnoreCase(V_DEREF_SEARCHING)) {
|
||||
cons.setDereference(LDAPv2.DEREF_SEARCHING);
|
||||
}
|
||||
else if(deref.equalsIgnoreCase(V_DEREF_FINDING)) {
|
||||
cons.setDereference(LDAPv2.DEREF_FINDING);
|
||||
}
|
||||
else if(deref.equalsIgnoreCase(V_DEREF_ALWAYS)) {
|
||||
cons.setDereference(LDAPv2.DEREF_ALWAYS);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Illegal value for " + P_DEREF_ALIASES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set referral parameters for the default SearchConstraints for the connection.
|
||||
* Specified with the env property java.naming.referral
|
||||
*/
|
||||
void updateReferralMode(LDAPSearchConstraints cons) {
|
||||
String mode = (String)getProperty(P_REFERRAL_MODE);
|
||||
if(mode != null) {
|
||||
if(mode.equalsIgnoreCase(V_REFERRAL_FOLLOW)) {
|
||||
cons.setReferrals(true);
|
||||
String user = getUserDN(), passwd = getUserPassword();
|
||||
if (user != null && passwd != null) {
|
||||
cons.setRebindProc(new ReferralRebindProc(user, passwd));
|
||||
}
|
||||
}
|
||||
else if(mode.equalsIgnoreCase(V_REFERRAL_THROW_EXCEPTION)) {
|
||||
cons.setReferrals(false);
|
||||
}
|
||||
else if(mode.equalsIgnoreCase(V_REFERRAL_IGNORE)) {
|
||||
cons.setServerControls(new LDAPControl(
|
||||
LDAPControl.MANAGEDSAIT, true, null));
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Illegal value for " + P_REFERRAL_MODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation for LDAPRebind interface. Provide user name, password
|
||||
* to autenticate with the referred to directory server.
|
||||
*/
|
||||
static class ReferralRebindProc implements LDAPRebind {
|
||||
LDAPRebindAuth auth;
|
||||
|
||||
public ReferralRebindProc(String user, String passwd) {
|
||||
auth = new LDAPRebindAuth(user, passwd);
|
||||
}
|
||||
|
||||
public LDAPRebindAuth getRebindAuthentication(String host, int port) {
|
||||
return auth;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set maximal number of referral hops under default SearchConstraints for the
|
||||
* connection.
|
||||
* Specified with the env property java.naming.referral.limit
|
||||
*/
|
||||
void updateReferralHopLimit(LDAPSearchConstraints cons) throws IllegalArgumentException{
|
||||
String limit = (String)getProperty(P_REFERRAL_HOPLIMIT);
|
||||
if(limit != null) {
|
||||
int n = -1;
|
||||
try {
|
||||
n = Integer.parseInt(limit);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalArgumentException("Illegal value for " + P_REFERRAL_HOPLIMIT);
|
||||
}
|
||||
cons.setHopLimit(n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if simple auth mode is explicitly requested. If that's the case
|
||||
* user DN and password must be specified as well
|
||||
*/
|
||||
boolean useSimpleAuth() throws NamingException {
|
||||
String authMode = (String)getProperty(P_SECURITY_AUTHMODE);
|
||||
if(authMode != null) {
|
||||
if(authMode.equalsIgnoreCase(V_AUTH_NONE)) {
|
||||
return false;
|
||||
}
|
||||
else if (authMode.equalsIgnoreCase(V_AUTH_SIMPLE)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
throw new AuthenticationNotSupportedException(
|
||||
"Unsupported value for " + P_SECURITY_AUTHMODE);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if SSL mode is enabled
|
||||
*/
|
||||
boolean isSSLEnabled() throws NamingException {
|
||||
String secMode = (String)getProperty(P_SECURITY_PROTOCOL);
|
||||
if(secMode != null) {
|
||||
if(secMode.equalsIgnoreCase("ssl")) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
throw new AuthenticationNotSupportedException(
|
||||
"Unsupported value for " + P_SECURITY_PROTOCOL);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Directory Server URL
|
||||
*/
|
||||
LDAPUrl getDirectoryServerURL() throws NamingException{
|
||||
String url = (String) getProperty(Context.PROVIDER_URL);
|
||||
try {
|
||||
return (url == null) ? null : new LDAPUrl(url);
|
||||
}
|
||||
catch (java.net.MalformedURLException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal value for " + Context.PROVIDER_URL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Ldap Version. If not specified the default is version 3
|
||||
*/
|
||||
int getLdapVersion() throws NamingException{
|
||||
String version = (String) getProperty(P_LDAP_VERSION);
|
||||
if (version != null) {
|
||||
int v = -1;
|
||||
try {
|
||||
v = Integer.parseInt(version);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal value for java.naming.ldap.version property.");
|
||||
}
|
||||
/*if ( v !=2 && v !=3) {
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal value for + java.naming.ldap.version property.");
|
||||
}BLITS*/
|
||||
return v;
|
||||
}
|
||||
return DEFAULT_LDAP_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user authenticate name
|
||||
*/
|
||||
String getUserDN() {
|
||||
return (String) getProperty(Context.SECURITY_PRINCIPAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user authenticate password
|
||||
*/
|
||||
String getUserPassword() {
|
||||
return (String) getProperty(Context.SECURITY_CREDENTIALS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full qualified socket factory class name
|
||||
*/
|
||||
String getSocketFactory() {
|
||||
return (String)getProperty(P_SOCKET_FACTORY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cipher suite for the socket factory
|
||||
*/
|
||||
Object getCipherSuite() {
|
||||
return getProperty(P_CIPHER_SUITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get controls to be used during a connection request like ProxyAuth
|
||||
*/
|
||||
LDAPControl[] getConnectControls() throws NamingException{
|
||||
Control[] reqCtls = (Control[])getProperty(P_CONNECT_CTRLS);
|
||||
if (reqCtls != null) {
|
||||
LDAPControl[] ldapCtls = new LDAPControl[reqCtls.length];
|
||||
for (int i=0; i < reqCtls.length; i++) {
|
||||
try {
|
||||
ldapCtls[i] = (LDAPControl) reqCtls[i];
|
||||
}
|
||||
catch (ClassCastException ex) {
|
||||
throw new NamingException(
|
||||
"Unsupported control type " + reqCtls[i].getClass().getName());
|
||||
}
|
||||
}
|
||||
return ldapCtls;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag whether search operation should return attribute names only
|
||||
* (no values). Read environment property P_ATTRS_ONLY. If not defined
|
||||
* FALSE is returned (return attribute values by default)
|
||||
*/
|
||||
boolean getAttrsOnlyFlag() {
|
||||
String flag = (String)getProperty(P_ATTRS_ONLY);
|
||||
if (flag == null) {
|
||||
return false; //default
|
||||
}
|
||||
else if (flag.equalsIgnoreCase("true")) {
|
||||
return true;
|
||||
}
|
||||
else if (flag.equalsIgnoreCase("false")) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Illegal value for " + P_ATTRS_ONLY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag whether rename operation should delete old RDN
|
||||
* Read environment property P_ATTRS_ONLY. If not defined
|
||||
* TRUE is returned (delete old RDN by default)
|
||||
*/
|
||||
boolean getDeleteOldRDNFlag() {
|
||||
String flag = (String)getProperty(P_DELETE_OLDRDN);
|
||||
if (flag == null) {
|
||||
return true; //default
|
||||
}
|
||||
else if (flag.equalsIgnoreCase("true")) {
|
||||
return true;
|
||||
}
|
||||
else if (flag.equalsIgnoreCase("false")) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Illegal value for " + P_DELETE_OLDRDN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A user defined value for the separator for JNDI References.
|
||||
* The default value is '#'.
|
||||
* Read environment property P_JNDIREF_SEPARATOR.
|
||||
*/
|
||||
char getRefSeparator() throws NamingException{
|
||||
String sep = (String)getProperty(P_JNDIREF_SEPARATOR );
|
||||
if(sep != null) {
|
||||
if (sep.length() !=1) {
|
||||
throw new IllegalArgumentException("Illegal value for " + P_JNDIREF_SEPARATOR);
|
||||
}
|
||||
return sep.charAt(0);
|
||||
}
|
||||
return '#';
|
||||
}
|
||||
|
||||
/**
|
||||
* A user defined list of names of binary attributes. This list augments the
|
||||
* default list of well-known binary attributes. List entries are space separated
|
||||
* Read environment property P_BINARY_ATTRS.
|
||||
*/
|
||||
String[] getUserDefBinaryAttrs() {
|
||||
String binAttrList = (String)getProperty(P_BINARY_ATTRS);
|
||||
if (binAttrList == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringTokenizer tok = new StringTokenizer(binAttrList);
|
||||
String[] binAttrs = new String[tok.countTokens()];
|
||||
for (int i=0; tok.hasMoreTokens(); i++) {
|
||||
binAttrs[i] = tok.nextToken();
|
||||
}
|
||||
return binAttrs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,391 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.event.*;
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
import java.util.*;
|
||||
import com.netscape.jndi.ldap.common.*;
|
||||
|
||||
/**
|
||||
* Event Service. Use Persistant Search control to monitor changes on the
|
||||
* server. Because public ldapjdk APIs do not provide for multiplexing of
|
||||
* multiple requests over the same connection, a separate thread is created
|
||||
* for each monitored event
|
||||
*
|
||||
*/
|
||||
class EventService {
|
||||
|
||||
LdapService m_ldapSvc;
|
||||
Vector m_eventThreads = new Vector();
|
||||
|
||||
public EventService(LdapService ldapSvc) {
|
||||
m_ldapSvc = ldapSvc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a persistent search control.
|
||||
*/
|
||||
private LDAPPersistSearchControl createSrchCtrl(NamingListener listener) throws NamingException{
|
||||
|
||||
int op = 0;
|
||||
|
||||
if (listener instanceof ObjectChangeListener) {
|
||||
op = LDAPPersistSearchControl.MODIFY;
|
||||
}
|
||||
if (listener instanceof NamespaceChangeListener) {
|
||||
op |= LDAPPersistSearchControl.ADD |
|
||||
LDAPPersistSearchControl.DELETE |
|
||||
LDAPPersistSearchControl.MODDN;
|
||||
}
|
||||
if (op == 0) {
|
||||
throw new NamingException("Non supported listener type " + listener.getClass().getName());
|
||||
}
|
||||
return new LDAPPersistSearchControl( op, /*changesOnly=*/true,
|
||||
/*returnControls=*/true, /*isCritical=*/true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove change event listener
|
||||
*/
|
||||
synchronized void removeListener(NamingListener listener) throws NamingException {
|
||||
boolean removed = false;
|
||||
int i=0;
|
||||
while(i < m_eventThreads.size()) {
|
||||
EventThread et = (EventThread)m_eventThreads.elementAt(i);
|
||||
if (et.removeListener(listener)) {
|
||||
removed = true;
|
||||
|
||||
// If no listeners left, stop the thread.
|
||||
if (et.isEmpty()) {
|
||||
et.abandonRequest();
|
||||
et.stop();
|
||||
if (m_eventThreads.removeElement(et)) {
|
||||
continue; // do not advance counter i
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!removed) {
|
||||
throw new NamingException("Listener not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add change event listener
|
||||
*/
|
||||
synchronized void addListener (LdapContextImpl ctx, String name, String filter, SearchControls jndiCtrls, NamingListener l) throws NamingException{
|
||||
Debug.println(1, "ADD LISTENER");
|
||||
|
||||
// Create DN by appending the name to the current context
|
||||
String base = ctx.getDN();
|
||||
if (name.length() > 0) {
|
||||
if (base.length() > 0) {
|
||||
base = name + "," + base;
|
||||
}
|
||||
else {
|
||||
base = name;
|
||||
}
|
||||
}
|
||||
|
||||
//Create search constraints
|
||||
LDAPConnection ld = (LDAPConnection) m_ldapSvc.getConnection().clone();
|
||||
LDAPSearchConstraints cons=ld.getSearchConstraints();
|
||||
LDAPPersistSearchControl psearchCtrl = createSrchCtrl(l);
|
||||
cons.setServerControls(psearchCtrl);
|
||||
|
||||
// return obj flag is ignored in this implementation
|
||||
boolean returnObjs = jndiCtrls.getReturningObjFlag();
|
||||
|
||||
// Because we are not returning objects in the NamingEvent's
|
||||
// oldBinding and newBinding variables, there is no way for
|
||||
// for the listener to read attributes from the event. Thus
|
||||
// jndiCtrls.getReturningAttributes() are ignored. Request only
|
||||
// javaClassName to be able to determine object type
|
||||
String[] attrs = new String[] { "javaclassname" };
|
||||
|
||||
// Search scope
|
||||
int scope = ProviderUtils.jndiSearchScopeToLdap(jndiCtrls.getSearchScope());
|
||||
|
||||
// Check if such change is already monitored
|
||||
EventThread et = null;
|
||||
for (int i=0; i < m_eventThreads.size(); i++) {
|
||||
EventThread activeET = (EventThread) m_eventThreads.elementAt(i);
|
||||
if (activeET.isEqualEvent(ctx, base, scope, filter, attrs, cons)) {
|
||||
et = activeET;
|
||||
et.addListener(l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new event if reqested change is not already monitored
|
||||
if (et == null) {
|
||||
et = new EventThread(ctx, ld, base, scope, filter, attrs, cons);
|
||||
m_eventThreads.addElement(et);
|
||||
et.addListener(l);
|
||||
et.setDaemon(true);
|
||||
et.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change Monitoring Thread
|
||||
*/
|
||||
static private class EventThread extends Thread {
|
||||
|
||||
String base, filter, attrs[];
|
||||
int scope;
|
||||
LDAPSearchConstraints cons;
|
||||
LDAPConnection ld;
|
||||
EventContext src;
|
||||
LDAPSearchResults res = null;
|
||||
LdapContextImpl ctx;
|
||||
boolean doRun;
|
||||
Vector listeners = new Vector(); // vector of NamingListener
|
||||
|
||||
EventThread(LdapContextImpl ctx, LDAPConnection ld, String base, int scope, String filter,
|
||||
String[] attrs, LDAPSearchConstraints cons) {
|
||||
|
||||
this.ctx = ctx;
|
||||
this.ld = ld;
|
||||
this.base = base;
|
||||
this.scope = scope;
|
||||
this.filter = filter;
|
||||
this.attrs = attrs;
|
||||
this.cons = cons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Listsner
|
||||
*/
|
||||
void addListener(NamingListener l) {
|
||||
synchronized(listeners) {
|
||||
listeners.addElement(l);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove listener
|
||||
*/
|
||||
boolean removeListener(NamingListener l) {
|
||||
synchronized(listeners) {
|
||||
return listeners.removeElement(l);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abandon request. Called when no listeners left.
|
||||
* Unfortunatlly, ldapjdk does not allows us the interrupt a waiting
|
||||
* thread and do proper cleanup.
|
||||
* TODO Need improvment here!!
|
||||
*/
|
||||
void abandonRequest() throws NamingException {
|
||||
try {
|
||||
if (res != null) {
|
||||
ld.abandon(res);
|
||||
}
|
||||
ld.disconnect();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw ExceptionMapper.getNamingException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chech whether there are any listeners
|
||||
*/
|
||||
boolean isEmpty() {
|
||||
return listeners.size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this event paramaters are matched
|
||||
*/
|
||||
boolean isEqualEvent(LdapContextImpl ctx, String base, int scope, String filter,
|
||||
String[] attrs, LDAPSearchConstraints cons) {
|
||||
|
||||
if (this.ctx != ctx || !this.base.equals(base) ||
|
||||
this.scope != scope || !this.filter.equals(filter)) {
|
||||
|
||||
return false;
|
||||
}
|
||||
// attrs[]
|
||||
if (this.attrs == null) {
|
||||
if (attrs != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (attrs == null) {
|
||||
return false;
|
||||
}
|
||||
else if (this.attrs.length != attrs.length) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
for (int i=0; i < this.attrs.length; i++) {
|
||||
// TODO not 100% ok. Arrays may contain the same names
|
||||
// but at different positions
|
||||
if (!this.attrs[i].equals(attrs[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if persistant search is for the same change type
|
||||
LDAPPersistSearchControl
|
||||
psearch1 = (LDAPPersistSearchControl)this.cons.getServerControls()[0],
|
||||
psearch2 = (LDAPPersistSearchControl)cons.getServerControls()[0];
|
||||
int types1 = psearch1.getChangeTypes(),
|
||||
types2 = psearch2.getChangeTypes();
|
||||
return (types1 == types2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue persistent search request. Loop waiting for change notifications
|
||||
*/
|
||||
public void run() {
|
||||
doRun = true;
|
||||
try {
|
||||
Debug.println(1, "Do persistent search for " + base);
|
||||
res = ld.search( base, scope, filter, attrs, false, cons);
|
||||
|
||||
/* Loop through the results until finished. */
|
||||
while ( res.hasMoreElements() && doRun) {
|
||||
|
||||
/* Get the next modified directory entry. */
|
||||
LDAPEntry modEntry = res.next();
|
||||
|
||||
Debug.println(1, "Changed " + modEntry.getDN());
|
||||
|
||||
/* Get any entry change controls. */
|
||||
LDAPControl[] ctrls = ld.getResponseControls();
|
||||
|
||||
// Can not create event without change control
|
||||
if (ctrls == null) {
|
||||
throw new NamingException(
|
||||
"Can not create NamingEvent, no change control info");
|
||||
}
|
||||
|
||||
LDAPEntryChangeControl changeCtrl =
|
||||
LDAPPersistSearchControl.parseResponse(ctrls);
|
||||
|
||||
// Can not create event without change control
|
||||
if (changeCtrl == null || changeCtrl.getChangeType() == -1) {
|
||||
throw new NamingException(
|
||||
"Can not create NamingEvent, no change control info");
|
||||
}
|
||||
|
||||
NamingEvent event = createNamingEvent(modEntry, changeCtrl);
|
||||
dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
catch(Exception ex) {
|
||||
NamingException nameEx = ExceptionMapper.getNamingException(ex);
|
||||
dispatchEvent(new NamingExceptionEvent(ctx, nameEx));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch naming event to all listeners
|
||||
*/
|
||||
void dispatchEvent(EventObject event) {
|
||||
NamingListener[] dispatchList = null;
|
||||
|
||||
// Copy listeners so that list can be modifed during dispatching
|
||||
synchronized (listeners) {
|
||||
dispatchList = new NamingListener[listeners.size()];
|
||||
for (int i=0; i < dispatchList.length; i++) {
|
||||
dispatchList[i] = (NamingListener)listeners.elementAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
// dispatch to all listeners
|
||||
for (int i=0; i < dispatchList.length; i++) {
|
||||
if (event instanceof NamingEvent) {
|
||||
((NamingEvent)event).dispatch(dispatchList[i]);
|
||||
}
|
||||
else {
|
||||
((NamingExceptionEvent)event).dispatch(dispatchList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create naming event from the ldap entry and change control
|
||||
*/
|
||||
NamingEvent createNamingEvent(LDAPEntry entry, LDAPEntryChangeControl changeCtrl) throws NamingException{
|
||||
|
||||
Binding oldBd = null, newBd = null;
|
||||
int eventType = -1;
|
||||
Object changeInfo = null;
|
||||
String oldName = null, newName = null;
|
||||
|
||||
// Get the class name from the entry
|
||||
String className = ObjectMapper.getClassName(entry);
|
||||
|
||||
// Get information on the type of change made
|
||||
int changeType = changeCtrl.getChangeType();
|
||||
switch ( changeType ) {
|
||||
case LDAPPersistSearchControl.ADD:
|
||||
eventType = NamingEvent.OBJECT_ADDED;
|
||||
newName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN());
|
||||
break;
|
||||
case LDAPPersistSearchControl.DELETE:
|
||||
eventType = NamingEvent.OBJECT_REMOVED;
|
||||
oldName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN());
|
||||
break;
|
||||
case LDAPPersistSearchControl.MODIFY:
|
||||
eventType = NamingEvent.OBJECT_CHANGED;
|
||||
oldName = newName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN());
|
||||
break;
|
||||
case LDAPPersistSearchControl.MODDN:
|
||||
eventType = NamingEvent.OBJECT_RENAMED;
|
||||
// Get the previous DN of the entry
|
||||
String oldDN = changeCtrl.getPreviousDN();
|
||||
if ( oldDN != null ) {
|
||||
oldName = LdapNameParser.getRelativeName(ctx.m_ctxDN, oldDN);
|
||||
}
|
||||
// newName might be outside the context for which the listener has registred
|
||||
try {
|
||||
newName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN());
|
||||
}
|
||||
catch (NamingException ex) {}
|
||||
break;
|
||||
}
|
||||
|
||||
// Pass the change log number as event's change info
|
||||
// If the change log number is not present the value is -1
|
||||
changeInfo = new Integer(changeCtrl.getChangeNumber());
|
||||
|
||||
|
||||
if (oldName != null) {
|
||||
oldBd = new Binding(oldName, className, /*obj=*/null, /*isRelative=*/true);
|
||||
}
|
||||
if (newName!= null) {
|
||||
newBd = new Binding(newName, className, /*obj=*/null, /*isRelative=*/true);
|
||||
}
|
||||
return new NamingEvent(ctx, eventType, newBd, oldBd, changeInfo);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.event.*;
|
||||
import javax.naming.spi.*;
|
||||
import java.util.*;
|
||||
|
||||
public class LdapContextFactory implements InitialContextFactory {
|
||||
|
||||
public Context getInitialContext(Hashtable env) throws NamingException {
|
||||
Hashtable ctxEnv = (Hashtable)env.clone();
|
||||
|
||||
// Read system properties as well. Add a system property to the
|
||||
// env if it's name start with "java.naming." and it is not already
|
||||
// present in the env (env has precedence over the System properties)
|
||||
for (Enumeration e = System.getProperties().keys(); e.hasMoreElements();) {
|
||||
String key = (String) e.nextElement();
|
||||
if (key.startsWith("java.naming.")) {
|
||||
if (ctxEnv.get(key) == null) {
|
||||
ctxEnv.put(key,System.getProperty(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EventDirContext ctx = new LdapContextImpl(ctxEnv);
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,604 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
import javax.naming.event.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import com.netscape.jndi.ldap.controls.NetscapeControlFactory;
|
||||
import com.netscape.jndi.ldap.common.Debug;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Implementation for the DirContext. The context also supports controls
|
||||
* through the implementation of LdapContext interface and events through
|
||||
* the implementaion of EventDirContext.
|
||||
* Semantically, the LdapContextImpl corresponds to a directory entry.
|
||||
* Thus a context is associated with a DN (m_ctxDN). Multiple contexts share
|
||||
* the same LDAPConnection which is wrapped into a LdapService object
|
||||
* (m_ldapSvc). Each context also maintains a set of environment properties
|
||||
* (m_ctxEnv). A context environment is shared among mutiple contexts using a
|
||||
* variation of copy-on-write algorithm (see common.ShareableEnv class).
|
||||
*
|
||||
* Each context also maintains a set of LDAPSearchConstraints, as search
|
||||
* constrainsts like e.g. server controls, or max number of returned search
|
||||
* search results, are context specific. The LdapService reads the
|
||||
* LDAPSearchConstraints from a context that makes a service request.
|
||||
*/
|
||||
public class LdapContextImpl implements EventDirContext, LdapContext {
|
||||
|
||||
/**
|
||||
* Context environment setting
|
||||
*/
|
||||
protected ContextEnv m_ctxEnv;
|
||||
|
||||
/**
|
||||
* DN associated with this context
|
||||
* The default value is the root DSE ("")
|
||||
*/
|
||||
protected String m_ctxDN;
|
||||
|
||||
/**
|
||||
* Ldap Connection/Service
|
||||
*/
|
||||
protected LdapService m_ldapSvc;
|
||||
|
||||
|
||||
/**
|
||||
* Ldap Connection Search Constraints
|
||||
*/
|
||||
protected LDAPSearchConstraints m_searchCons;
|
||||
|
||||
// TODO Should have a constructor that accepts attributes
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public LdapContextImpl(Hashtable env) throws NamingException{
|
||||
m_ctxEnv = new ContextEnv(env); // no need to clone (Hashtable)env.clone());
|
||||
m_ldapSvc = new LdapService(this);
|
||||
m_ldapSvc.connect(); // BLITS but to be removed, hurts lazy resource usage
|
||||
getDN();
|
||||
getSearchConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
*/
|
||||
public LdapContextImpl(String ctxDN, LdapContextImpl cloneCtx) throws NamingException{
|
||||
|
||||
m_ctxEnv = (ContextEnv)cloneCtx.m_ctxEnv.clone();
|
||||
|
||||
// An instance of ldapService is shared among multiple contexts.
|
||||
// Increment the client reference count
|
||||
m_ldapSvc = cloneCtx.m_ldapSvc;
|
||||
cloneCtx.m_ldapSvc.incrementClientCount();
|
||||
|
||||
if (cloneCtx.getSearchConstraints().getServerControls() == null) {
|
||||
m_searchCons = cloneCtx.getSearchConstraints();
|
||||
}
|
||||
else {
|
||||
// In LdapContext Context Controls are not inherited by derived contexts
|
||||
m_searchCons = (LDAPSearchConstraints) cloneCtx.getSearchConstraints().clone();
|
||||
m_searchCons.setServerControls((LDAPControl[])null);
|
||||
}
|
||||
|
||||
m_ctxDN = ctxDN;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close the context when finalized
|
||||
*/
|
||||
protected void finalize() {
|
||||
Debug.println(1, "finalize ctx");
|
||||
try {
|
||||
close();
|
||||
}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect the Ldap Connection if close is requested
|
||||
* LDAP operations can not be performed any more ones
|
||||
* the context is closed
|
||||
*/
|
||||
public void close() throws NamingException {
|
||||
m_ldapSvc.disconnect();
|
||||
m_ldapSvc = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return LdapJdk search constraints for this context
|
||||
*/
|
||||
LDAPSearchConstraints getSearchConstraints() throws NamingException{
|
||||
if (m_searchCons == null) {
|
||||
LDAPSearchConstraints cons = new LDAPSearchConstraints();
|
||||
m_ctxEnv.updateSearchCons(cons);
|
||||
m_searchCons = cons;
|
||||
}
|
||||
return m_searchCons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return DN for this context
|
||||
*/
|
||||
String getDN() throws NamingException{
|
||||
if (m_ctxDN == null) {
|
||||
LDAPUrl url = m_ctxEnv.getDirectoryServerURL();
|
||||
if (url != null && url.getDN() != null) {
|
||||
m_ctxDN = url.getDN();
|
||||
}
|
||||
else {
|
||||
m_ctxDN = "";
|
||||
}
|
||||
}
|
||||
return m_ctxDN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to the context environment
|
||||
*/
|
||||
ContextEnv getEnv() {
|
||||
return m_ctxEnv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conver object to String
|
||||
*/
|
||||
public String toString() {
|
||||
return this.getClass().getName() + ": " + m_ctxDN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if LdapURL is passed as the name paremetr to a method
|
||||
* If that's the case, craete environment for the ldap url
|
||||
*/
|
||||
String checkLdapUrlAsName(String name) throws NamingException{
|
||||
if (name.startsWith("ldap://")) {
|
||||
m_ctxEnv.setProperty(ContextEnv.P_PROVIDER_URL, name);
|
||||
close(); // Force reconnect
|
||||
m_ldapSvc = new LdapService(this);
|
||||
// Return New name relative to the context
|
||||
return "";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Environment operatins (javax.naming.Context interface)
|
||||
*/
|
||||
|
||||
public Hashtable getEnvironment() throws NamingException {
|
||||
return m_ctxEnv.getAllProperties();
|
||||
}
|
||||
|
||||
public Object addToEnvironment(String propName, Object propValue) throws NamingException {
|
||||
return m_ctxEnv.updateProperty(propName, propValue, getSearchConstraints());
|
||||
}
|
||||
|
||||
public Object removeFromEnvironment(String propName) throws NamingException {
|
||||
return m_ctxEnv.removeProperty(propName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Name operations (javax.naming.Context interface)
|
||||
*/
|
||||
|
||||
public String composeName(String name, String prefix) throws NamingException {
|
||||
return name + "," + prefix;
|
||||
}
|
||||
|
||||
public Name composeName(Name name, Name prefix) throws NamingException {
|
||||
String compoundName = composeName(name.toString(), prefix.toString());
|
||||
return LdapNameParser.getParser().parse(compoundName);
|
||||
}
|
||||
|
||||
public String getNameInNamespace() throws NamingException {
|
||||
return new String(m_ctxDN);
|
||||
}
|
||||
|
||||
public NameParser getNameParser(String name) throws NamingException {
|
||||
return LdapNameParser.getParser();
|
||||
}
|
||||
|
||||
public NameParser getNameParser(Name name) throws NamingException {
|
||||
return LdapNameParser.getParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search operations (javax.naming.DirContext interface)
|
||||
*/
|
||||
|
||||
public NamingEnumeration search(String name, String filter, SearchControls cons) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
return m_ldapSvc.search(this, name, filter, /*attrs=*/null, cons);
|
||||
}
|
||||
|
||||
public NamingEnumeration search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
String filter = ProviderUtils.expandFilterExpr(filterExpr, filterArgs);
|
||||
return m_ldapSvc.search(this, name, filter, /*attrs=*/null, cons);
|
||||
}
|
||||
|
||||
public NamingEnumeration search(String name, Attributes matchingAttributes) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
String filter = ProviderUtils.attributesToFilter(matchingAttributes);
|
||||
return m_ldapSvc.search(this, name, filter, /*attrs=*/null, /*jndiCons=*/null);
|
||||
}
|
||||
|
||||
public NamingEnumeration search(String name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
String filter = ProviderUtils.attributesToFilter(matchingAttributes);
|
||||
return m_ldapSvc.search(this, name, filter, attributesToReturn, /*jndiCons=*/null);
|
||||
}
|
||||
|
||||
public NamingEnumeration search(Name name, String filter, SearchControls cons) throws NamingException {
|
||||
return m_ldapSvc.search(this, name.toString(), filter, /*attrs=*/null, cons);
|
||||
}
|
||||
|
||||
public NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
|
||||
String filter = ProviderUtils.expandFilterExpr(filterExpr, filterArgs);
|
||||
return m_ldapSvc.search(this, name.toString(), filter, /*attrs=*/null, cons);
|
||||
}
|
||||
|
||||
public NamingEnumeration search(Name name, Attributes attrs) throws NamingException {
|
||||
String filter = ProviderUtils.attributesToFilter(attrs);
|
||||
return m_ldapSvc.search(this, name.toString(), filter, /*attr=*/null, /*jndiCons=*/null);
|
||||
}
|
||||
|
||||
public NamingEnumeration search(Name name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
|
||||
String filter = ProviderUtils.attributesToFilter(matchingAttributes);
|
||||
return m_ldapSvc.search(this, name.toString(), filter, attributesToReturn, /*jndiCons=*/null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute Operations (javax.naming.DirContext interface)
|
||||
*/
|
||||
|
||||
public Attributes getAttributes(String name) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
return m_ldapSvc.readAttrs(this, name, null);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
return m_ldapSvc.readAttrs(this, name, attrIds);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name) throws NamingException {
|
||||
return m_ldapSvc.readAttrs(this, name.toString(), null);
|
||||
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
|
||||
return m_ldapSvc.readAttrs(this, name.toString(), attrIds);
|
||||
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
m_ldapSvc.modifyEntry(this, name, AttributesImpl.jndiAttrsToLdapModSet(mod_op, attrs));
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
m_ldapSvc.modifyEntry(this, name, AttributesImpl.jndiModsToLdapModSet(mods));
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
|
||||
m_ldapSvc.modifyEntry(this, name.toString(), AttributesImpl.jndiAttrsToLdapModSet(mod_op, attrs));
|
||||
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
|
||||
m_ldapSvc.modifyEntry(this, name.toString(), AttributesImpl.jndiModsToLdapModSet(mods));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ldap entry operations (javax.naming.DirContext interface)
|
||||
*/
|
||||
|
||||
public Context createSubcontext(String name) throws NamingException {
|
||||
// Directory entry must have attributes
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Context createSubcontext(Name name) throws NamingException {
|
||||
// Directory entry must have attributes
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(String name, Attributes attrs) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
return m_ldapSvc.addEntry(this, name, AttributesImpl.jndiAttrsToLdapAttrSet(attrs));
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException {
|
||||
return m_ldapSvc.addEntry(this, name.toString(), AttributesImpl.jndiAttrsToLdapAttrSet(attrs));
|
||||
|
||||
}
|
||||
|
||||
public void destroySubcontext(String name) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
m_ldapSvc.delEntry(this, name);
|
||||
}
|
||||
|
||||
public void destroySubcontext(Name name) throws NamingException {
|
||||
m_ldapSvc.delEntry(this, name.toString());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Naming Bind/Rename operations
|
||||
* (javax.naming.Context, javax.naming.DirContext interface)
|
||||
*/
|
||||
|
||||
public void bind(String name, Object obj) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
m_ldapSvc.addEntry(this, name.toString(),
|
||||
ObjectMapper.objectToAttrSet(obj, name, this, /*attrs=*/null));
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj) throws NamingException {
|
||||
bind(name.toString(), obj);
|
||||
}
|
||||
|
||||
public void bind(String name, Object obj, Attributes attrs) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
m_ldapSvc.addEntry(this, name.toString(),
|
||||
ObjectMapper.objectToAttrSet(obj, name, this, attrs));
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj, Attributes attrs) throws NamingException {
|
||||
bind(name.toString(), obj, attrs);
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj) throws NamingException {
|
||||
rebind(name, obj, /*attrs=*/null);
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj) throws NamingException {
|
||||
rebind(name.toString(), obj, null);
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj, Attributes attrs) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
try {
|
||||
bind(name, obj, attrs);
|
||||
}
|
||||
catch (NameAlreadyBoundException ex) {
|
||||
unbind(name);
|
||||
bind(name, obj, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj, Attributes attrs) throws NamingException {
|
||||
rebind(name.toString(), obj, attrs);
|
||||
}
|
||||
|
||||
public void rename(String oldName, String newName) throws NamingException {
|
||||
oldName = checkLdapUrlAsName(oldName);
|
||||
LdapNameParser parser = LdapNameParser.getParser();
|
||||
Name oldNameObj = parser.parse(oldName);
|
||||
Name newNameObj = parser.parse(newName);
|
||||
rename(oldNameObj, newNameObj);
|
||||
}
|
||||
|
||||
public void rename(Name oldName, Name newName) throws NamingException {
|
||||
// Can rename only RDN
|
||||
if (newName.size() != oldName.size()) {
|
||||
throw new InvalidNameException("Invalid name " + newName);
|
||||
}
|
||||
Name oldPrefix = oldName.getPrefix(oldName.size() -1);
|
||||
Name newPrefix = newName.getPrefix(oldName.size() -1);
|
||||
if (!newPrefix.equals(oldPrefix)) {
|
||||
throw new InvalidNameException("Invalid name " + newName);
|
||||
}
|
||||
m_ldapSvc.changeRDN(this, oldName.toString(), newName.get(newName.size()-1));
|
||||
}
|
||||
|
||||
public void unbind(String name) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
// In ldap every entry is naming context
|
||||
destroySubcontext(name);
|
||||
}
|
||||
|
||||
public void unbind(Name name) throws NamingException {
|
||||
// In ldap every entry is naming context
|
||||
destroySubcontext(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* List Operations (javax.naming.Context interface)
|
||||
*/
|
||||
|
||||
public NamingEnumeration list(String name) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
return m_ldapSvc.listEntries(this, name, /*returnBindings=*/false);
|
||||
}
|
||||
|
||||
public NamingEnumeration list(Name name) throws NamingException {
|
||||
return m_ldapSvc.listEntries(this, name.toString(), /*returnBindings=*/false);
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(String name) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
return m_ldapSvc.listEntries(this, name, /*returnBindings=*/true);
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(Name name) throws NamingException {
|
||||
return m_ldapSvc.listEntries(this, name.toString(), /*returnBindings=*/true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup Operations (javax.naming.Context interface)
|
||||
*/
|
||||
|
||||
public Object lookup(String name) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
return m_ldapSvc.lookup(this, name);
|
||||
}
|
||||
|
||||
public Object lookup(Name name) throws NamingException {
|
||||
return m_ldapSvc.lookup(this, name.toString());
|
||||
}
|
||||
|
||||
public Object lookupLink(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Object lookupLink(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Schema Operations (javax.naming.DirContext interface)
|
||||
*/
|
||||
public DirContext getSchema(String name) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
return m_ldapSvc.getSchema(name);
|
||||
}
|
||||
|
||||
public DirContext getSchema(Name name) throws NamingException {
|
||||
return m_ldapSvc.getSchema(name.toString());
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(String name) throws NamingException {
|
||||
name = checkLdapUrlAsName(name);
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(Name name) throws NamingException {
|
||||
return getSchemaClassDefinition(name.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Naming Event methods javax.naming.event.EventDirContext interface)
|
||||
*/
|
||||
public void addNamingListener(String target, int scope, NamingListener l) throws NamingException {
|
||||
EventService eventSvc = m_ldapSvc.getEventService();
|
||||
String filter = LdapService.DEFAULT_FILTER;
|
||||
SearchControls ctls = new SearchControls();
|
||||
ctls.setSearchScope(scope);
|
||||
eventSvc.addListener(this, target, filter, ctls, l);
|
||||
}
|
||||
|
||||
public void addNamingListener(Name target, int scope, NamingListener l) throws NamingException {
|
||||
addNamingListener(target.toString(), scope, l);
|
||||
}
|
||||
|
||||
public void addNamingListener(String target, String filter, SearchControls ctls, NamingListener l)throws NamingException {
|
||||
EventService eventSvc = m_ldapSvc.getEventService();
|
||||
eventSvc.addListener(this, target, filter, ctls, l);
|
||||
|
||||
}
|
||||
|
||||
public void addNamingListener(Name target, String filter, SearchControls ctls, NamingListener l)throws NamingException {
|
||||
addNamingListener(target.toString(), filter, ctls, l);
|
||||
}
|
||||
|
||||
public void addNamingListener(String target, String filterExpr, Object[] filterArgs, SearchControls ctls, NamingListener l)throws NamingException {
|
||||
EventService eventSvc = m_ldapSvc.getEventService();
|
||||
String filter = ProviderUtils.expandFilterExpr(filterExpr, filterArgs);
|
||||
eventSvc.addListener(this, target, filter, ctls, l);
|
||||
}
|
||||
|
||||
public void addNamingListener(Name target, String filterExpr, Object[] filterArgs, SearchControls ctls, NamingListener l)throws NamingException {
|
||||
addNamingListener(target.toString(), filterExpr, filterArgs, ctls, l);
|
||||
}
|
||||
|
||||
public void removeNamingListener(NamingListener l) throws NamingException {
|
||||
EventService eventSvc = m_ldapSvc.getEventService();
|
||||
eventSvc.removeListener(l);
|
||||
}
|
||||
|
||||
public boolean targetMustExist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* LdapContext methods (javax.naming.ldap.LdapContext interface)
|
||||
*/
|
||||
public ExtendedResponse extendedOperation(ExtendedRequest req)throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Control[] getRequestControls() throws NamingException {
|
||||
LDAPControl[] ldapCtls = m_searchCons.getServerControls();
|
||||
if (ldapCtls == null) {
|
||||
return null;
|
||||
}
|
||||
Control[] ctls = new Control[ldapCtls.length];
|
||||
for (int i=0; i < ldapCtls.length; i++) {
|
||||
ctls[i] = (Control) ldapCtls[i];
|
||||
}
|
||||
return ctls;
|
||||
}
|
||||
|
||||
public void setRequestControls(Control[] reqCtls) throws NamingException {
|
||||
LDAPControl[] ldapCtls = new LDAPControl[reqCtls.length];
|
||||
for (int i=0; i < reqCtls.length; i++) {
|
||||
try {
|
||||
ldapCtls[i] = (LDAPControl) reqCtls[i];
|
||||
}
|
||||
catch (ClassCastException ex) {
|
||||
throw new NamingException(
|
||||
"Unsupported control type " + reqCtls[i].getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
getSearchConstraints().setServerControls(ldapCtls);
|
||||
}
|
||||
|
||||
public Control[] getResponseControls() throws NamingException {
|
||||
LDAPControl[] ldapCtls = m_ldapSvc.getConnection().getResponseControls();
|
||||
if (ldapCtls == null) {
|
||||
return null;
|
||||
}
|
||||
// Parse raw controls
|
||||
Control[] ctls = new Control[ldapCtls.length];
|
||||
for (int i=0; i < ldapCtls.length; i++) {
|
||||
ctls[i] = NetscapeControlFactory.getControlInstance(ldapCtls[i]);
|
||||
if (ctls[i] == null) {
|
||||
throw new NamingException("Unsupported control " + ldapCtls[i].getID());
|
||||
}
|
||||
}
|
||||
return ctls;
|
||||
}
|
||||
|
||||
public LdapContext newInstance(Control[] reqCtls) throws NamingException {
|
||||
LdapContextImpl clone = new LdapContextImpl(m_ctxDN, this);
|
||||
// This controls are to be set on the the LDAPConnection
|
||||
clone.m_ctxEnv.setProperty(ContextEnv.P_CONNECT_CTRLS, reqCtls);
|
||||
return clone;
|
||||
}
|
||||
|
||||
public void reconnect() throws NamingException {
|
||||
close();
|
||||
m_ldapSvc = new LdapService(this);
|
||||
m_ldapSvc.connect();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Properties;
|
||||
import javax.naming.*;
|
||||
|
||||
class LdapNameParser implements NameParser {
|
||||
|
||||
private static LdapNameParser m_parser;
|
||||
|
||||
// A table with compound name syntax properties
|
||||
static Properties nameSyntax;
|
||||
static {
|
||||
nameSyntax = new Properties();
|
||||
nameSyntax.put("jndi.syntax.direction", "right_to_left");
|
||||
nameSyntax.put("jndi.syntax.separator", ",");
|
||||
nameSyntax.put("jndi.syntax.ignorecase", "true");
|
||||
nameSyntax.put("jndi.syntax.escape", "\\");
|
||||
nameSyntax.put("jndi.syntax.beginquote", "\"");
|
||||
nameSyntax.put("jndi.syntax.trimblanks", "true");
|
||||
nameSyntax.put("jndi.syntax.separator.ava", "+");
|
||||
nameSyntax.put("jndi.syntax.separator.typeval", "=");
|
||||
}
|
||||
|
||||
// Can not be constructed
|
||||
private LdapNameParser() {}
|
||||
|
||||
// Shared instance must be used
|
||||
public static LdapNameParser getParser() {
|
||||
if (m_parser == null) {
|
||||
m_parser = new LdapNameParser();
|
||||
}
|
||||
return m_parser;
|
||||
}
|
||||
|
||||
// implements parse
|
||||
public Name parse(String name) throws NamingException {
|
||||
return new CompoundName(name, nameSyntax);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for extracting RDN
|
||||
* @return RDN for the DN
|
||||
* @param dn Ldap Distinguished name
|
||||
* @throw NamingException Name parsing failed
|
||||
*/
|
||||
static String getRDN(String dn) throws NamingException {
|
||||
Name parsedName = getParser().parse(dn);
|
||||
if (parsedName.size() > 0) {
|
||||
return parsedName.get(parsedName.size()-1);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for extracting attribute name from name=val
|
||||
* @return attribute name or null if "=" not found
|
||||
* @param nameEqVal name=value
|
||||
*/
|
||||
static String getAttrName(String nameEqVal) throws NamingException {
|
||||
int eq = nameEqVal.indexOf("=");
|
||||
return (eq >= 0) ? nameEqVal.substring(0,eq).trim() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for extracting attribute value from name=val
|
||||
* @return attribute value or null if "=" not found
|
||||
* @param nameEqVal name=value
|
||||
*/
|
||||
static String getAttrValue(String nameEqVal) throws NamingException {
|
||||
int eq = nameEqVal.indexOf("=");
|
||||
return (eq >= 0) ? nameEqVal.substring(eq+1).trim() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for extracting relative name from the ancestor context
|
||||
* @return name relative to an ancestor context
|
||||
* @param ctx ancestor context distinguished name
|
||||
* @param entry distinguished name
|
||||
*/
|
||||
static String getRelativeName(String ctx, String entry) throws NamingException{
|
||||
if (entry==null) {
|
||||
entry = "";
|
||||
}
|
||||
Name contextName = getParser().parse(ctx);
|
||||
Name entryName = getParser().parse(entry);
|
||||
if (!entryName.startsWith(contextName)) {
|
||||
throw new NamingException("Name not in context");
|
||||
}
|
||||
return entryName.getSuffix(contextName.size()).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for extracting relative name from the ancestor context
|
||||
* @return name relative to an ancestor context
|
||||
* @param ctx ancestor context distinguished name
|
||||
* @param entry distinguished name
|
||||
*/
|
||||
static String getRelativeName(Name contextName, String entry) throws NamingException{
|
||||
if (entry==null) {
|
||||
entry = "";
|
||||
}
|
||||
Name entryName = getParser().parse(entry);
|
||||
if (!entryName.startsWith(contextName)) {
|
||||
throw new NamingException("Name not in context");
|
||||
}
|
||||
return entryName.getSuffix(contextName.size()).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit test
|
||||
*/
|
||||
public static void main0(String[] args) {
|
||||
if (args.length != 1) {
|
||||
System.out.println("Usage LdapNameParser <name>");
|
||||
System.exit(1);
|
||||
}
|
||||
try {
|
||||
Name name = getParser().parse(args[0]);
|
||||
System.out.println(name);
|
||||
System.out.println("rdn: " + getParser().getRDN(args[0]));
|
||||
name.add("attr=val");
|
||||
System.out.println(name);
|
||||
System.out.println(name.get(0));
|
||||
System.out.println("in name=val name:<" + getAttrName("name=val ") +
|
||||
"> val:<" + getAttrValue("name=val ") + ">");
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Relative name test
|
||||
public static void main(String[] args) {
|
||||
if (args.length != 2) {
|
||||
System.out.println("Usage LdapNameParser <ctxname> <entryname>");
|
||||
System.exit(1);
|
||||
}
|
||||
try {
|
||||
System.out.println("relativeName: " + getParser().getRelativeName(args[0], args[1]));
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A wrapper for the ldapjdk LDAPReferralException
|
||||
*
|
||||
*/
|
||||
class LdapReferralException extends javax.naming.ldap.LdapReferralException {
|
||||
|
||||
LDAPReferralException m_ldapEx;
|
||||
LdapContextImpl m_srcCtx;
|
||||
int m_referralIdx = 0;
|
||||
|
||||
public LdapReferralException(LdapContextImpl srcCtx, LDAPReferralException ldapEx) {
|
||||
m_srcCtx = srcCtx;
|
||||
m_ldapEx = ldapEx;
|
||||
}
|
||||
|
||||
public Object getReferralInfo() {
|
||||
return m_ldapEx.getURLs();
|
||||
}
|
||||
|
||||
public Context getReferralContext() throws NamingException{
|
||||
Hashtable env = m_srcCtx.getEnv().getAllProperties();
|
||||
env.put(ContextEnv.P_PROVIDER_URL, m_ldapEx.getURLs()[m_referralIdx]);
|
||||
return new LdapContextImpl(env);
|
||||
}
|
||||
|
||||
public Context getReferralContext(Hashtable env) throws NamingException{
|
||||
return getReferralContext(env, null);
|
||||
}
|
||||
|
||||
public Context getReferralContext(Hashtable env, Control[] reqCtls) throws NamingException{
|
||||
env.put(ContextEnv.P_PROVIDER_URL, m_ldapEx.getURLs()[m_referralIdx]);
|
||||
if (reqCtls != null) {
|
||||
env.put(ContextEnv.P_CONNECT_CTRLS, reqCtls);
|
||||
}
|
||||
return new LdapContextImpl(env);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Skip the referral to be processed
|
||||
*/
|
||||
public boolean skipReferral() {
|
||||
int maxIdx = m_ldapEx.getURLs().length - 1;
|
||||
if (m_referralIdx < maxIdx) {
|
||||
m_referralIdx++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void retryReferral() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,515 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
import com.netscape.jndi.ldap.common.*;
|
||||
import com.netscape.jndi.ldap.schema.SchemaRoot;
|
||||
|
||||
/**
|
||||
* Ldap Service encapsulates a Ldap connection and Ldap operations over the
|
||||
* connection. The connection is established in a lazy manner, first time a
|
||||
* Ldap operation is initiated. A Ldap Service object is shared by multiple
|
||||
* contexts. The object maintains a reference counter which is incremented
|
||||
* when a context is cloned, and decremeneted when a context is closed. The
|
||||
* associated Ldap Connection is relased when the reference counter reaches
|
||||
* zero.
|
||||
*
|
||||
* LDAPsearchConstraints are always read from a context, because ldap service
|
||||
* is a shared object and each context may request different search constraints.
|
||||
*
|
||||
*/
|
||||
class LdapService {
|
||||
|
||||
public static final String DEFAULT_FILTER = "(objectclass=*)";
|
||||
public static final int DEFAULT_SCOPE = LDAPv3.SCOPE_SUB;
|
||||
public static final String DEFAULT_HOST = "localhost";
|
||||
public static final int DEFAULT_PORT = LDAPv2.DEFAULT_PORT;
|
||||
public static final int DEFAULT_SSL_PORT = 636;
|
||||
|
||||
private LdapContextImpl m_initialCtx;
|
||||
private LDAPConnection m_ld;
|
||||
private EventService m_eventSvc;
|
||||
|
||||
/**
|
||||
* The number of contexts that are currently sharing this LdapService.
|
||||
* Essentially, a reference counter. Incremented in the LdapContextImpl
|
||||
* copy constructor. Decremented in the LdapService.disconnect().
|
||||
* When the count reaches zero, the LDAPConnection is released.
|
||||
*/
|
||||
private int m_clientCount;
|
||||
|
||||
|
||||
public LdapService(LdapContextImpl initialCtx) {
|
||||
m_initialCtx = initialCtx;
|
||||
m_ld = new LDAPConnection();
|
||||
m_clientCount = 1;
|
||||
}
|
||||
|
||||
LDAPConnection getConnection() {
|
||||
return m_ld;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the server and send bind request to authenticate the user
|
||||
*/
|
||||
void connect() throws NamingException{
|
||||
|
||||
if (m_ld.isConnected()) {
|
||||
return; //already connected
|
||||
}
|
||||
|
||||
LDAPUrl url = m_initialCtx.m_ctxEnv.getDirectoryServerURL();
|
||||
String host = (url != null) ? url.getHost() : DEFAULT_HOST;
|
||||
int port = (url != null) ? url.getPort() : DEFAULT_PORT;
|
||||
String user = m_initialCtx.m_ctxEnv.getUserDN();
|
||||
String passwd = m_initialCtx.m_ctxEnv.getUserPassword();
|
||||
String socketFactory = m_initialCtx.m_ctxEnv.getSocketFactory();
|
||||
Object cipherSuite = m_initialCtx.m_ctxEnv.getCipherSuite();
|
||||
int ldapVersion = m_initialCtx.m_ctxEnv.getLdapVersion();
|
||||
boolean isSSLEnabled = m_initialCtx.m_ctxEnv.isSSLEnabled();
|
||||
boolean useSimpleAuth= m_initialCtx.m_ctxEnv.useSimpleAuth();
|
||||
LDAPControl[] ldCtrls= m_initialCtx.m_ctxEnv.getConnectControls();
|
||||
|
||||
// Set default ssl port if DS not specifed
|
||||
if (isSSLEnabled && url == null) {
|
||||
port = DEFAULT_SSL_PORT;
|
||||
}
|
||||
|
||||
// SSL is enabled but no Socket factory specified. Use the
|
||||
// ldapjdk default one
|
||||
if (isSSLEnabled && socketFactory == null) {
|
||||
m_ld = new LDAPConnection(new LDAPSSLSocketFactory());
|
||||
}
|
||||
|
||||
// Set the socket factory and cipher suite if cpecified
|
||||
if (socketFactory != null) {
|
||||
try {
|
||||
LDAPSSLSocketFactory sf = null;
|
||||
if (cipherSuite != null) {
|
||||
Debug.println(1, "CIPHERS=" + cipherSuite);
|
||||
sf = new LDAPSSLSocketFactory(socketFactory, cipherSuite);
|
||||
}
|
||||
else {
|
||||
sf = new LDAPSSLSocketFactory(socketFactory);
|
||||
}
|
||||
m_ld = new LDAPConnection(sf);
|
||||
Debug.println(1, "SSL CONNECTION");
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal value for java.naming.ldap.factory.socket: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (ldCtrls != null) {
|
||||
m_ld.setOption(LDAPv3.SERVERCONTROLS, ldCtrls);
|
||||
}
|
||||
m_ld.connect(ldapVersion, host, port, user, passwd);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalize() {
|
||||
try {
|
||||
m_ld.disconnect();
|
||||
}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
|
||||
boolean isConnected() {
|
||||
return (m_ld.isConnected());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Physically disconect only if the client count is zero
|
||||
*/
|
||||
void disconnect() {
|
||||
try {
|
||||
if (m_clientCount > 0) {
|
||||
m_clientCount--;
|
||||
}
|
||||
if (m_clientCount == 0 && isConnected()) {
|
||||
m_ld.disconnect();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment client count
|
||||
*/
|
||||
void incrementClientCount() {
|
||||
m_clientCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* LDAP search operation
|
||||
*/
|
||||
NamingEnumeration search (LdapContextImpl ctx, String name, String filter, String[] attrs, SearchControls jndiCtrls) throws NamingException{
|
||||
Debug.println(1, "SEARCH");
|
||||
String base = ctx.getDN();
|
||||
int scope = LDAPConnection.SCOPE_SUB;
|
||||
LDAPSearchConstraints cons=ctx.getSearchConstraints();
|
||||
boolean returnObjs = false;
|
||||
|
||||
connect(); // Lazy Connect
|
||||
|
||||
// Create DN by appending the name to the current context
|
||||
if (name.length() > 0) {
|
||||
if (base.length() > 0) {
|
||||
base = name + "," + base;
|
||||
}
|
||||
else {
|
||||
base = name;
|
||||
}
|
||||
}
|
||||
|
||||
// Map JNDI SearchControls to ldapjdk LDAPSearchConstraints
|
||||
if (jndiCtrls != null) {
|
||||
int maxResults = (int)jndiCtrls.getCountLimit();
|
||||
int timeLimitInMsec = jndiCtrls.getTimeLimit();
|
||||
// Convert timeLimit in msec to sec
|
||||
int timeLimit = timeLimitInMsec/1000;
|
||||
if (timeLimitInMsec > 0 && timeLimitInMsec < 1000) {
|
||||
timeLimit = 1; //sec
|
||||
}
|
||||
|
||||
// Clone cons if maxResults or timeLimit is different from the default one
|
||||
if (cons.getServerTimeLimit() != timeLimit || cons.getMaxResults() != maxResults) {
|
||||
cons = (LDAPSearchConstraints)cons.clone();
|
||||
cons.setMaxResults(maxResults);
|
||||
cons.setServerTimeLimit(timeLimit);
|
||||
}
|
||||
|
||||
// TODO The concept of links is not well described in JNDI docs.
|
||||
// We can only specify dereferencing of Aliases, but Links and
|
||||
// Aliases are not the same; IGNORE jndiCtrls.getDerefLinkFlag()
|
||||
|
||||
// Attributes to return
|
||||
attrs = jndiCtrls.getReturningAttributes();
|
||||
if (attrs != null && attrs.length==0) {
|
||||
//return no attributes
|
||||
attrs = new String[] { "1.1" };
|
||||
|
||||
// TODO check whether ldap compare operation should be performed
|
||||
// That's the case if: (1) scope is OBJECT_SCOPE, (2) no attrs
|
||||
// are requested to return (3) filter has the form (name==value)
|
||||
// where no wildcards ()&|!=~><* are used.
|
||||
|
||||
}
|
||||
|
||||
// Search scope
|
||||
scope = ProviderUtils.jndiSearchScopeToLdap(jndiCtrls.getSearchScope());
|
||||
|
||||
// return obj flag
|
||||
returnObjs = jndiCtrls.getReturningObjFlag();
|
||||
}
|
||||
|
||||
try {
|
||||
// Perform Search
|
||||
boolean attrsOnly = ctx.m_ctxEnv.getAttrsOnlyFlag();
|
||||
LDAPSearchResults res = m_ld.search( base, scope, filter, attrs, attrsOnly, cons );
|
||||
return new SearchResultEnum(res, returnObjs, ctx);
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(ctx, e);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List child entries using LDAP lookup operation
|
||||
*/
|
||||
NamingEnumeration listEntries(LdapContextImpl ctx, String name, boolean returnBindings) throws NamingException{
|
||||
Debug.println(1, "LIST " + (returnBindings ? "BINDINGS" : ""));
|
||||
String base = ctx.getDN();
|
||||
|
||||
connect(); // Lazy Connect
|
||||
|
||||
// Create DN by appending the name to the current context
|
||||
if (name.length() > 0) {
|
||||
if (base.length() > 0) {
|
||||
base = name + "," + base;
|
||||
}
|
||||
else {
|
||||
base = name;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Perform One Level Search
|
||||
String[] attrs = null; // return all attributes if Bindings are requested
|
||||
if (!returnBindings) { // for ClassNamePairs
|
||||
attrs = new String[]{"javaclassname"}; //attr names must be in lowercase
|
||||
}
|
||||
LDAPSearchConstraints cons=ctx.getSearchConstraints();
|
||||
LDAPSearchResults res = m_ld.search( base, LDAPConnection.SCOPE_ONE, DEFAULT_FILTER, attrs, /*attrsOnly=*/false, cons);
|
||||
if (returnBindings) {
|
||||
return new BindingEnum(res, ctx);
|
||||
}
|
||||
else {
|
||||
return new NameClassPairEnum(res, ctx);
|
||||
}
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(ctx, e);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup an entry using LDAP search operation
|
||||
*/
|
||||
Object lookup(LdapContextImpl ctx, String name) throws NamingException{
|
||||
Debug.println(1, "LOOKUP");
|
||||
String base = ctx.getDN();
|
||||
|
||||
connect(); // Lazy Connect
|
||||
|
||||
// Create DN by appending the name to the current context
|
||||
if (name.length() > 0) {
|
||||
if (base.length() > 0) {
|
||||
base = name + "," + base;
|
||||
}
|
||||
else {
|
||||
base = name;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Perform Base Search
|
||||
String[] attrs = null; // return all attrs
|
||||
LDAPSearchConstraints cons=ctx.getSearchConstraints();
|
||||
LDAPSearchResults res = m_ld.search( base, LDAPConnection.SCOPE_BASE, DEFAULT_FILTER, attrs, /*attrsOnly=*/false, cons);
|
||||
if (res.hasMoreElements()) {
|
||||
LDAPEntry entry = res.next();
|
||||
return ObjectMapper.entryToObject(entry, ctx);
|
||||
}
|
||||
return null; // should never get here
|
||||
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(ctx, e);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read LDAP entry attributes
|
||||
*/
|
||||
Attributes readAttrs (LdapContextImpl ctx, String name, String[] attrs) throws NamingException{
|
||||
Debug.println(1, "READ ATTRS");
|
||||
String base = ctx.getDN();
|
||||
int scope = LDAPConnection.SCOPE_BASE;
|
||||
|
||||
connect(); // Lazy Connect
|
||||
|
||||
// Create DN by appending the name to the current context
|
||||
if (name.length() > 0) {
|
||||
if (base.length() > 0) {
|
||||
base = name + "," + base;
|
||||
}
|
||||
else {
|
||||
base = name;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Perform Search
|
||||
LDAPSearchConstraints cons=ctx.getSearchConstraints();
|
||||
LDAPSearchResults res = m_ld.search(base, scope, DEFAULT_FILTER, attrs, /*attrsOnly=*/false, cons);
|
||||
while (res.hasMoreElements()) {
|
||||
LDAPEntry entry = res.next();
|
||||
return new AttributesImpl(entry.getAttributeSet(),
|
||||
ctx.m_ctxEnv.getUserDefBinaryAttrs());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(ctx, e);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify LDAP entry attributes
|
||||
*/
|
||||
void modifyEntry(LdapContextImpl ctx, String name, LDAPModificationSet mods) throws NamingException{
|
||||
Debug.println(1, "MODIFY");
|
||||
String base = ctx.getDN();
|
||||
|
||||
if (mods.size() == 0) {
|
||||
return;
|
||||
}
|
||||
connect(); // Lazy Connect
|
||||
|
||||
// Create DN by appending the name to the current context
|
||||
if (name.length() > 0) {
|
||||
if (base.length() > 0) {
|
||||
base = name + "," + base;
|
||||
}
|
||||
else {
|
||||
base = name;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Perform Modify
|
||||
m_ld.modify(base, mods);
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(ctx, e);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new LDAP entry
|
||||
*/
|
||||
LdapContextImpl addEntry(LdapContextImpl ctx, String name, LDAPAttributeSet attrs) throws NamingException{
|
||||
Debug.println(1, "ADD");
|
||||
String dn = ctx.getDN();
|
||||
|
||||
connect(); // Lazy Connect
|
||||
|
||||
// Create DN by appending the name to the current context
|
||||
if (name.length() == 0) {
|
||||
throw new IllegalArgumentException("Name can not be empty");
|
||||
}
|
||||
if (dn.length() > 0) {
|
||||
dn = name + "," + dn;
|
||||
}
|
||||
else {
|
||||
dn = name;
|
||||
}
|
||||
|
||||
try {
|
||||
// Add a new entry
|
||||
m_ld.add(new LDAPEntry(dn, attrs));
|
||||
return new LdapContextImpl(dn, ctx);
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(ctx, e);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a LDAP entry
|
||||
*/
|
||||
void delEntry(LdapContextImpl ctx, String name) throws NamingException{
|
||||
Debug.println(1, "DELETE");
|
||||
String dn = ctx.getDN();
|
||||
|
||||
connect(); // Lazy Connect
|
||||
|
||||
// Create DN by appending the name to the current context
|
||||
if (name.length() == 0) {
|
||||
throw new IllegalArgumentException("Name can not be empty");
|
||||
}
|
||||
if (dn.length() > 0) {
|
||||
dn = name + "," + dn;
|
||||
}
|
||||
else {
|
||||
dn = name;
|
||||
}
|
||||
|
||||
try {
|
||||
// Perform Delete
|
||||
m_ld.delete(dn);
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(ctx, e);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chanage RDN for a LDAP entry
|
||||
*/
|
||||
void changeRDN(LdapContextImpl ctx, String name, String newRDN) throws NamingException{
|
||||
Debug.println(1, "RENAME");
|
||||
String dn = ctx.getDN();
|
||||
|
||||
connect(); // Lazy Connect
|
||||
|
||||
// Create DN by appending the name to the current context
|
||||
if (name.length() == 0 || newRDN.length() == 0) {
|
||||
throw new IllegalArgumentException("Name can not be empty");
|
||||
}
|
||||
if (dn.length() > 0) {
|
||||
dn = name + "," + dn;
|
||||
}
|
||||
else {
|
||||
dn = name;
|
||||
}
|
||||
|
||||
try {
|
||||
// Rename
|
||||
m_ld.rename(dn, newRDN, ctx.m_ctxEnv.getDeleteOldRDNFlag());
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(ctx, e);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schema Operations
|
||||
*/
|
||||
DirContext getSchema(String name) throws NamingException {
|
||||
connect(); // Lazy Connect
|
||||
return new SchemaRoot(m_ld);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the event service
|
||||
*/
|
||||
EventService getEventService() throws NamingException {
|
||||
connect(); // Lazy Connect
|
||||
if (m_eventSvc == null) {
|
||||
m_eventSvc = new EventService(this);
|
||||
}
|
||||
return m_eventSvc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
import com.netscape.jndi.ldap.common.ExceptionMapper;
|
||||
|
||||
import netscape.ldap.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Wrapper for the LDAPSearchResult. Convert each LDAPEntry entry into
|
||||
* a JNDI NameClassPair. NameClassPairs are accessed through the NamingEnumeration
|
||||
* interface
|
||||
*/
|
||||
class NameClassPairEnum implements NamingEnumeration {
|
||||
|
||||
LDAPSearchResults m_res;
|
||||
LdapContextImpl m_ctx;
|
||||
Name m_ctxName;
|
||||
|
||||
public NameClassPairEnum(LDAPSearchResults res, LdapContextImpl ctx) throws NamingException{
|
||||
m_res = res;
|
||||
m_ctx = ctx;
|
||||
try {
|
||||
m_ctxName = LdapNameParser.getParser().parse(m_ctx.m_ctxDN);
|
||||
}
|
||||
catch ( NamingException e ) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object next() throws NamingException{
|
||||
try {
|
||||
LDAPEntry entry = m_res.next();
|
||||
String name = LdapNameParser.getRelativeName(m_ctxName, entry.getDN());
|
||||
String className = ObjectMapper.getClassName(entry);
|
||||
return new NameClassPair(name, className, /*isRelative=*/true);
|
||||
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(m_ctx, e);
|
||||
}
|
||||
catch ( LDAPException e ) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
try {
|
||||
return next();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
System.err.println( "Error in NameClassPairEnum.nextElement(): " + e.toString() );
|
||||
e.printStackTrace(System.err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException{
|
||||
return m_res.hasMoreElements();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return m_res.hasMoreElements();
|
||||
}
|
||||
|
||||
public void close() throws NamingException{
|
||||
try {
|
||||
m_ctx.m_ldapSvc.getConnection().abandon(m_res);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,473 @@
|
|||
package com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.spi.*;
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.util.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import com.netscape.jndi.ldap.common.Debug;
|
||||
|
||||
/**
|
||||
* Class used to map Java objects to ldap entries back and forth
|
||||
*/
|
||||
public class ObjectMapper {
|
||||
|
||||
/**
|
||||
* Schema object classes for mapping java objects to ldap entries
|
||||
*/
|
||||
static final String OC_JAVAOBJECT = "javaObject"; // abstract oc
|
||||
static final String OC_SERIALOBJ = "javaSerializedObject";//aux oc
|
||||
static final String OC_REFERENCE = "javaNamingReference"; //aux oc
|
||||
static final String OC_REMOTEOBJ = "javaRemoteObject"; //aux oc
|
||||
static final String OC_CONTAINER = "javaContainer"; //structural oc
|
||||
|
||||
/**
|
||||
* Schema attributes for mapping java objects to ldap entries
|
||||
*/
|
||||
static final String AT_CLASSNAME = "javaClassName"; //required
|
||||
static final String AT_CODEBASE = "javaCodeBase"; //optional
|
||||
static final String AT_SERIALDATA = "javaSerializedData"; //required
|
||||
static final String AT_REFADDR = "javaReferenceAddress"; //optional
|
||||
static final String AT_OBJFACTORY = "javaFactory"; //optional
|
||||
static final String AT_REMOTELOC = "javaRemoteLocation"; //required
|
||||
|
||||
//Default Object class for NameClassPair
|
||||
static final String DEFAULT_OBJCLASS = "javax.naming.directory.DirContext";
|
||||
|
||||
static Object entryToObject(LDAPEntry entry, LdapContextImpl ctx) throws NamingException {
|
||||
Object obj = entryToObject(entry);
|
||||
if (obj == null) {
|
||||
obj = new LdapContextImpl(entry.getDN(), ctx);
|
||||
}
|
||||
|
||||
// SP is required to contact the NamingManager first to obtain an object
|
||||
try {
|
||||
String relName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN());
|
||||
Name nameObj = LdapNameParser.getParser().parse(relName);
|
||||
obj = NamingManager.getObjectInstance(obj, nameObj, ctx, ctx.getEnvironment());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (ex instanceof NamingException) {
|
||||
throw (NamingException)ex;
|
||||
}
|
||||
NamingException nameEx = new NamingException("NamingManager.getObjectInstance failed");
|
||||
nameEx.setRootCause(ex);
|
||||
throw nameEx;
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Ldap entry into a java object
|
||||
*/
|
||||
static Object entryToObject(LDAPEntry entry) throws NamingException {
|
||||
|
||||
try {
|
||||
LDAPAttributeSet attrs = entry.getAttributeSet();
|
||||
|
||||
// TODO javaCodeBase to be processed
|
||||
|
||||
LDAPAttribute attr = null;
|
||||
if ((attr = attrs.getAttribute(AT_SERIALDATA)) != null) {
|
||||
byte[] serdata = (byte[])attr.getByteValues().nextElement();
|
||||
return deserializeObject(serdata);
|
||||
}
|
||||
|
||||
// Reference
|
||||
else if ((attr = attrs.getAttribute(AT_REFADDR)) != null) {
|
||||
return decodeRefObj(attrs);
|
||||
}
|
||||
|
||||
// RMI Object
|
||||
else if ((attr = attrs.getAttribute(AT_REMOTELOC)) != null) {
|
||||
String rmiURL = (String)attr.getByteValues().nextElement();
|
||||
return java.rmi.Naming.lookup(rmiURL);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (ex instanceof NamingException) {
|
||||
throw (NamingException)ex;
|
||||
}
|
||||
NamingException nameEx = new NamingException("NamingManager.getStateToStore failed");
|
||||
nameEx.setRootCause(ex);
|
||||
throw nameEx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the className for NameClassPair from an entry
|
||||
*/
|
||||
static String getClassName(LDAPEntry entry) {
|
||||
LDAPAttributeSet attrs = entry.getAttributeSet();
|
||||
LDAPAttribute attrClass = attrs.getAttribute(AT_CLASSNAME);
|
||||
if (attrClass != null) {
|
||||
String className = (String)attrClass.getStringValues().nextElement();
|
||||
return className;
|
||||
}
|
||||
return DEFAULT_OBJCLASS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a java object with an optional set of attributes into a LDAP entry
|
||||
*/
|
||||
static LDAPAttributeSet objectToAttrSet(Object obj, String name, LdapContextImpl ctx, Attributes attrs) throws NamingException {
|
||||
|
||||
// SP is required to contact the NamingManager first to obtain a state object
|
||||
try {
|
||||
Name nameObj = LdapNameParser.getParser().parse(name);
|
||||
obj = NamingManager.getStateToBind(obj, nameObj, ctx, ctx.getEnvironment());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (ex instanceof NamingException) {
|
||||
throw (NamingException)ex;
|
||||
}
|
||||
NamingException nameEx = new NamingException("NamingManager.getStateToStore failed");
|
||||
nameEx.setRootCause(ex);
|
||||
throw nameEx;
|
||||
}
|
||||
|
||||
if (attrs == null) {
|
||||
attrs = new BasicAttributes(/*ignoreCase=*/true);
|
||||
}
|
||||
|
||||
Attribute objectclass = attrs.get("objectClass");
|
||||
if (objectclass == null) {
|
||||
objectclass = new BasicAttribute("objectClass", "top");
|
||||
attrs.put(objectclass);
|
||||
}
|
||||
|
||||
// Root object class
|
||||
objectclass.add(OC_JAVAOBJECT);
|
||||
|
||||
if (obj instanceof Reference) {
|
||||
objectclass.add(OC_REFERENCE);
|
||||
char delimChar = ctx.m_ctxEnv.getRefSeparator();
|
||||
attrs = encodeRefObj(delimChar, (Reference)obj, attrs);
|
||||
}
|
||||
|
||||
else if (obj instanceof Referenceable) {
|
||||
objectclass.add(OC_REFERENCE);
|
||||
char delimChar = ctx.m_ctxEnv.getRefSeparator();
|
||||
attrs = encodeRefObj(delimChar, ((Referenceable)obj).getReference(), attrs);
|
||||
}
|
||||
|
||||
else if (obj instanceof java.rmi.Remote) {
|
||||
objectclass.add(OC_REMOTEOBJ);
|
||||
attrs = encodeRMIObj((java.rmi.Remote)obj, attrs);
|
||||
}
|
||||
|
||||
else if (obj instanceof Serializable) {
|
||||
objectclass.add(OC_SERIALOBJ);
|
||||
attrs = encodeSerialObj((Serializable)obj , attrs);
|
||||
}
|
||||
|
||||
else if (obj instanceof DirContext) {
|
||||
attrs = encodeDirCtxObj((DirContext)obj , attrs);
|
||||
}
|
||||
|
||||
else {
|
||||
throw new NamingException("Can not bind object of type " +
|
||||
obj.getClass().getName());
|
||||
}
|
||||
|
||||
return AttributesImpl.jndiAttrsToLdapAttrSet(attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialized object, create object from a stream of bytes
|
||||
*/
|
||||
private static Object deserializeObject(byte[] byteBuf) throws NamingException {
|
||||
|
||||
ByteArrayInputStream bis = null;
|
||||
ObjectInputStream objis = null;
|
||||
|
||||
try {
|
||||
bis = new ByteArrayInputStream(byteBuf);
|
||||
objis = new ObjectInputStream(bis);
|
||||
return objis.readObject();
|
||||
}
|
||||
catch(Exception ex) {
|
||||
NamingException nameEx = new NamingException("Failed to deserialize object");
|
||||
nameEx.setRootCause(ex);
|
||||
throw nameEx;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (objis != null) {
|
||||
objis.close();
|
||||
}
|
||||
if (bis != null) {
|
||||
bis.close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serialize object, convert object to a stream of bytes
|
||||
*/
|
||||
private static byte[] serializeObject(Object obj) throws NamingException {
|
||||
|
||||
ByteArrayOutputStream bos = null;
|
||||
ObjectOutputStream objos = null;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
objos = new ObjectOutputStream(bos);
|
||||
objos.writeObject(obj);
|
||||
objos.flush();
|
||||
return bos.toByteArray();
|
||||
}
|
||||
catch(Exception ex) {
|
||||
NamingException nameEx = new NamingException("Failed to serialize object");
|
||||
nameEx.setRootCause(ex);
|
||||
throw nameEx;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (objos != null) {
|
||||
objos.close();
|
||||
}
|
||||
if (bos != null) {
|
||||
bos.close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode Jndi Reference Object
|
||||
*/
|
||||
private static Reference decodeRefObj(LDAPAttributeSet attrs) throws NamingException {
|
||||
try {
|
||||
|
||||
LDAPAttribute attr = null;
|
||||
String className=null, factory = null, factoryLoc = null;
|
||||
if ((attr = attrs.getAttribute(AT_CLASSNAME)) == null ) {
|
||||
throw new NamingException("Bad Reference encoding, no attribute " + AT_CLASSNAME);
|
||||
}
|
||||
className = (String)attr.getStringValues().nextElement();
|
||||
|
||||
if ((attr = attrs.getAttribute(AT_OBJFACTORY)) != null ) {
|
||||
factory = (String)attr.getStringValues().nextElement();
|
||||
}
|
||||
if ((attr = attrs.getAttribute(AT_CODEBASE)) != null ) {
|
||||
factoryLoc = (String)attr.getStringValues().nextElement();
|
||||
}
|
||||
|
||||
Reference ref = new Reference(className, factory, factoryLoc);
|
||||
|
||||
if ((attr = attrs.getAttribute(AT_REFADDR)) == null ) {
|
||||
return ref; // no refAddr
|
||||
}
|
||||
|
||||
for (Enumeration e = attr.getStringValues(); e.hasMoreElements();) {
|
||||
decodeRefAddr((String)e.nextElement(), ref);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (ex instanceof NamingException) {
|
||||
throw (NamingException)ex;
|
||||
}
|
||||
NamingException nameEx = new NamingException("NamingManager.getStateToStore failed");
|
||||
nameEx.setRootCause(ex);
|
||||
throw nameEx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode RefAddr according to the <draft-ryan-java-schema-01.rev.txt>
|
||||
* StringRefAddr are encoded as #posNo#refType#refValue where posNo is the
|
||||
* refAddr position (index) inside a rerference. BynaryRefAddr is encoded
|
||||
* as #posNo#refType##data where data is the base64 encoding of the serialized
|
||||
* form of the entire BinaryRefAddr instance.
|
||||
*/
|
||||
private static void decodeRefAddr(String enc, Reference ref) throws NamingException{
|
||||
|
||||
if (enc.length() == 0) {
|
||||
throw new NamingException("Bad Reference encoding, empty refAddr");
|
||||
}
|
||||
|
||||
String delimChar = enc.substring(0,1);
|
||||
|
||||
StringTokenizer tok = new StringTokenizer(enc, delimChar);
|
||||
|
||||
int tokCount = tok.countTokens();
|
||||
if (tokCount != 3 && tokCount != 4) {
|
||||
Debug.println(3, "enc=" + enc + " delimChar="+delimChar + " tokCount="+tokCount);
|
||||
throw new NamingException("Bad Reference encoding");
|
||||
}
|
||||
|
||||
String type = null;
|
||||
int posn = -1;
|
||||
for (int i = 0; i < tokCount; i++) {
|
||||
String s = tok.nextToken();
|
||||
|
||||
if (i == 0) { // position
|
||||
try {
|
||||
posn = Integer.parseInt(s);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new NamingException("Bad Reference encoding, refAddr position not an initger");
|
||||
}
|
||||
}
|
||||
|
||||
else if (i == 1) { // type
|
||||
if (s.length() == 0) {
|
||||
throw new NamingException("Bad Reference encoding, empty refAddr type");
|
||||
}
|
||||
type = s;
|
||||
}
|
||||
|
||||
else if (i == 2) { // value for StringRefAddr, empty for BinaryRefAddr
|
||||
if (s.length() == 0 && tokCount != 4) { // should be empty for binary refs
|
||||
throw new NamingException("Bad Reference encoding, empty refAddr string value");
|
||||
}
|
||||
ref.add(posn, new StringRefAddr(type, s));
|
||||
}
|
||||
|
||||
else { // base64 encoding of the serialized BinaryRefAddr
|
||||
if (s.length() == 0) {
|
||||
throw new NamingException("Bad Reference encoding, empty refAddr binary value");
|
||||
}
|
||||
MimeBase64Decoder base64Dec = new MimeBase64Decoder();
|
||||
ByteBuf in = new ByteBuf(s), out = new ByteBuf();
|
||||
base64Dec.translate(in, out);
|
||||
base64Dec.eof(out);
|
||||
ref.add(posn, (RefAddr) deserializeObject(out.toBytes()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode Jndi Reference Object
|
||||
*/
|
||||
private static Attributes encodeRefObj(char delimChar, Reference ref, Attributes attrs) throws NamingException {
|
||||
|
||||
if (ref.getClassName() != null) {
|
||||
attrs.put(new BasicAttribute(AT_CLASSNAME, ref.getClassName()));
|
||||
}
|
||||
if (ref.getFactoryClassName() != null) {
|
||||
attrs.put(new BasicAttribute(AT_OBJFACTORY, ref.getFactoryClassName()));
|
||||
}
|
||||
if (ref.getFactoryClassLocation() != null) {
|
||||
attrs.put(new BasicAttribute(AT_CODEBASE, ref.getFactoryClassLocation()));
|
||||
}
|
||||
|
||||
if(ref.size() > 0) {
|
||||
BasicAttribute refAttr = new BasicAttribute(AT_REFADDR);
|
||||
for(int i = 0; i < ref.size(); i++) {
|
||||
refAttr.add(encodeRefAddr(delimChar, i, ref.get(i)));
|
||||
}
|
||||
attrs.put(refAttr);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode RefAddr according to the <draft-ryan-java-schema-01.rev.txt>
|
||||
* StringRefAddr are encoded as #posNo#refType#refValue where posNo is the
|
||||
* refAddr position (index) inside a rerference. BynaryRefAddr is encoded
|
||||
* as #posNo#refType##data where data is the base64 encoding of the serialized
|
||||
* form of the entire BinaryRefAddr instance.
|
||||
|
||||
*/
|
||||
private static String encodeRefAddr(char delimChar, int idx, RefAddr refAddr) throws NamingException{
|
||||
|
||||
if(refAddr instanceof StringRefAddr) {
|
||||
|
||||
String content = (String) refAddr.getContent();
|
||||
if (content != null && content.length() > 0 && content.charAt(0) == delimChar) {
|
||||
throw new NamingException(
|
||||
"Can not encode StringRefAddr, value starts with the delimiter character " + delimChar);
|
||||
}
|
||||
return delimChar + idx +
|
||||
delimChar + refAddr.getType() +
|
||||
delimChar + content;
|
||||
}
|
||||
|
||||
else { // BinaryRefAdd
|
||||
|
||||
byte[] serialRefAddr = serializeObject(refAddr);
|
||||
MimeBase64Encoder base64 = new MimeBase64Encoder();
|
||||
ByteBuf in = new ByteBuf(), out = new ByteBuf();
|
||||
in.append(serialRefAddr);
|
||||
base64.translate(in, out);
|
||||
base64.eof(out);
|
||||
return delimChar + idx +
|
||||
delimChar + refAddr.getType() +
|
||||
delimChar + delimChar + out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode Serializable object
|
||||
*/
|
||||
|
||||
static Attributes encodeSerialObj(Serializable obj, Attributes attrs) throws NamingException{
|
||||
if (attrs.get(AT_CLASSNAME) == null) {
|
||||
attrs.put(new BasicAttribute(AT_CLASSNAME, obj.getClass().getName()));
|
||||
}
|
||||
attrs.put(new BasicAttribute(AT_SERIALDATA, serializeObject(obj)));
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode RMI Object
|
||||
*/
|
||||
static Attributes encodeRMIObj(java.rmi.Remote obj, Attributes attrs) throws NamingException{
|
||||
if (attrs.get(AT_REMOTELOC) == null) {
|
||||
throw new NamingException(
|
||||
"Can not bind Remote object, " + AT_REMOTELOC + " not specified");
|
||||
}
|
||||
if (attrs.get(AT_CLASSNAME) == null) {
|
||||
attrs.put(new BasicAttribute(AT_CLASSNAME, obj.getClass().getName()));
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode DirContext object (merege attributes)
|
||||
*/
|
||||
static Attributes encodeDirCtxObj(DirContext obj, Attributes attrs) throws NamingException{
|
||||
Attributes ctxAttrs = obj.getAttributes("");
|
||||
for (NamingEnumeration enum = ctxAttrs.getAll(); enum.hasMore();) {
|
||||
attrs.put((Attribute)enum.next());
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
byte[] serialRefAddr = { 'a', '0', 'A', (byte)0x10, (byte)0x7f, (byte)0xaa };
|
||||
MimeBase64Encoder base64 = new MimeBase64Encoder();
|
||||
MimeBase64Decoder base64Dec = new MimeBase64Decoder();
|
||||
ByteBuf in = new ByteBuf(), out = new ByteBuf();
|
||||
in.append(serialRefAddr);
|
||||
base64.translate(in, out);
|
||||
base64.eof(out);
|
||||
System.err.println("in="+in);
|
||||
System.err.println("out="+out);
|
||||
in = new ByteBuf(out.toString());
|
||||
out = new ByteBuf();
|
||||
base64Dec.translate(in, out);
|
||||
base64Dec.eof(out);
|
||||
System.err.println("in="+in);
|
||||
System.err.println("out="+out);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Common utility methods
|
||||
*
|
||||
*/
|
||||
class ProviderUtils {
|
||||
|
||||
public static final String DEFAULT_FILTER = "(objectclass=*)";
|
||||
|
||||
static int jndiSearchScopeToLdap(int jndiScope) throws NamingException {
|
||||
int scope = -1;
|
||||
if (jndiScope == SearchControls.SUBTREE_SCOPE) {
|
||||
scope = LDAPConnection.SCOPE_SUB;
|
||||
}
|
||||
else if (jndiScope == SearchControls.ONELEVEL_SCOPE) {
|
||||
scope = LDAPConnection.SCOPE_ONE;
|
||||
}
|
||||
else if (jndiScope == SearchControls.OBJECT_SCOPE) {
|
||||
scope = LDAPConnection.SCOPE_BASE;
|
||||
}
|
||||
else {
|
||||
throw new InvalidSearchControlsException("Illegal value for the search scope");
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert Attribute List to a LDAP filter
|
||||
*
|
||||
* @return LDAP Filter
|
||||
* @throw NamingException
|
||||
* @param attrs An Attribute List
|
||||
*/
|
||||
static String attributesToFilter(Attributes attrs) throws NamingException{
|
||||
|
||||
if (attrs == null || attrs.size() == 0) {
|
||||
return DEFAULT_FILTER;
|
||||
}
|
||||
|
||||
String filter = "";
|
||||
|
||||
for (NamingEnumeration attrEnum = attrs.getAll(); attrEnum.hasMore();) {
|
||||
Attribute attrib = (Attribute) attrEnum.next();
|
||||
|
||||
//Has attributes any values
|
||||
if ( attrib.size() == 0) {
|
||||
// test only for presence of the attribute
|
||||
filter += "(" + attrib.getID() + "=*)";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add attribute values to the filter, ecsaping if necessary
|
||||
String attrValues = "";
|
||||
for (NamingEnumeration valEnum = attrib.getAll(); valEnum.hasMore();) {
|
||||
Object val = valEnum.next();
|
||||
if (val instanceof String) {
|
||||
attrValues += "(" + attrib.getID() + "=" + escapeString((String)val) +")";
|
||||
}
|
||||
else if (val instanceof byte[]) {
|
||||
attrValues += "(" + attrib.getID() + "=" + escapeBytes((byte[])val) +")";
|
||||
}
|
||||
else if (val == null) {
|
||||
//null is allowed value in Attribute.add(Object), accept it just in case
|
||||
attrValues += "(" + attrib.getID() + "=*)";
|
||||
}
|
||||
else {
|
||||
throw new NamingException(
|
||||
"Wrong Attribute value, expecting String or byte[]");
|
||||
}
|
||||
}
|
||||
filter += (attrib.size() > 1) ? ("(|" + attrValues + ")") : attrValues;
|
||||
}
|
||||
|
||||
return (attrs.size() > 1) ? ("(&" + filter + ")") : filter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expand filterExpr. Each occurrence of a variable "{n}", where n is a non-negative
|
||||
* integer, is replaced with a variable from the filterArgs array indexed by the 'n'.
|
||||
* FilterArgs can be Strings or byte[] and they are escaped according to the RFC2254
|
||||
*/
|
||||
static String expandFilterExpr(String filterExpr, Object[] filterArgs) throws InvalidSearchFilterException{
|
||||
StringTokenizer tok = new StringTokenizer(filterExpr, "{}", /*returnTokens=*/true);
|
||||
|
||||
if (tok.countTokens() == 1) {
|
||||
return filterExpr; // No escape characters
|
||||
}
|
||||
|
||||
StringBuffer out= new StringBuffer();
|
||||
boolean expectVarIdx = false, expectVarOff = false;
|
||||
Object arg= null;
|
||||
while (tok.hasMoreTokens()) {
|
||||
String s = tok.nextToken();
|
||||
|
||||
if (expectVarIdx) {
|
||||
expectVarIdx = false;
|
||||
try {
|
||||
int idx = Integer.parseInt(s);
|
||||
arg = filterArgs[idx];
|
||||
expectVarOff = true;
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
throw new InvalidSearchFilterException("Filter expression variable index out of bounds");
|
||||
}
|
||||
|
||||
catch (Exception e) {
|
||||
throw new InvalidSearchFilterException("Invalid filter expression");
|
||||
}
|
||||
}
|
||||
|
||||
else if (expectVarOff) {
|
||||
expectVarOff = false;
|
||||
if (!s.equals("}")) {
|
||||
throw new InvalidSearchFilterException("Invalid filter expression");
|
||||
}
|
||||
if (arg instanceof String) {
|
||||
out.append(escapeString((String)arg));
|
||||
}
|
||||
else if (arg instanceof byte[]) {
|
||||
out.append(escapeBytes((byte[])arg));
|
||||
}
|
||||
else {
|
||||
throw new InvalidSearchFilterException("Invalid filter argument type");
|
||||
}
|
||||
arg = null;
|
||||
}
|
||||
|
||||
else if (s.equals("{")) {
|
||||
expectVarIdx = true;
|
||||
}
|
||||
else {
|
||||
out.append(s);
|
||||
}
|
||||
}
|
||||
if (expectVarIdx || expectVarOff) {
|
||||
throw new InvalidSearchFilterException("Invalid filter expression");
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escape a string according to the RFC 2254
|
||||
*/
|
||||
static String escapeString(String str) {
|
||||
String charToEscape = "\\*()\000";
|
||||
StringTokenizer tok = new StringTokenizer(str, charToEscape, /*returnTokens=*/true);
|
||||
|
||||
if (tok.countTokens() == 1) {
|
||||
return str; // No escape characters
|
||||
}
|
||||
|
||||
StringBuffer out= new StringBuffer();
|
||||
while (tok.hasMoreTokens()) {
|
||||
String s = tok.nextToken();
|
||||
|
||||
if (s.equals("*")) {
|
||||
out.append("\\2a");
|
||||
}
|
||||
else if (s.equals("(")) {
|
||||
out.append("\\28");
|
||||
}
|
||||
else if (s.equals(")")) {
|
||||
out.append("\\29");
|
||||
}
|
||||
else if (s.equals("\\")) {
|
||||
out.append("\\5c");
|
||||
}
|
||||
else if (s.equals("\000")) {
|
||||
out.append("\\00");
|
||||
}
|
||||
else {
|
||||
out.append(s);
|
||||
}
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escape a byte array according to the RFC 2254
|
||||
*/
|
||||
static final String hexDigits="0123456789abcdef";
|
||||
|
||||
static String escapeBytes(byte[] bytes) {
|
||||
StringBuffer out = new StringBuffer("");
|
||||
for (int i=0; i < bytes.length; i++) {
|
||||
|
||||
int low = bytes[i] & 0x0f;
|
||||
int high = (bytes[i] & 0xf0) >> 4;
|
||||
out.append("\\");
|
||||
out.append(hexDigits.charAt(high));
|
||||
out.append(hexDigits.charAt(low));
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A method used only for testing
|
||||
*/
|
||||
private static void testAttributesToFilter() {
|
||||
try {
|
||||
System.out.println(attributesToFilter(null));
|
||||
|
||||
BasicAttributes attrs = new BasicAttributes(true);
|
||||
|
||||
System.out.println(attrs + " = " + attributesToFilter(attrs));
|
||||
|
||||
attrs.put (new BasicAttribute("attr1", "val1"));
|
||||
attrs.put (new BasicAttribute("attr2", "(val2)\\*x"));
|
||||
attrs.put (new BasicAttribute("attr3"));
|
||||
BasicAttribute attr4 = new BasicAttribute("attr4", "val41");
|
||||
attr4.add("val42");
|
||||
attrs.put(attr4);
|
||||
attrs.put("attr5", new byte[] { (byte)0x23, (byte)0x3, (byte)0x0, (byte)0xab, (byte)0xff});
|
||||
System.out.println(attrs + " = " +attributesToFilter(attrs));
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A method used only for testing
|
||||
*/
|
||||
private static void testFilterExpr() {
|
||||
try {
|
||||
String filterExpr = "(&(attr0={0})(attr1={1}))";
|
||||
Object [] args = new Object[] { "val*0", new byte[] { (byte)0xf0, (byte) 0x3a}};
|
||||
String filter = null;
|
||||
filter = expandFilterExpr(filterExpr, args);
|
||||
System.out.println(filterExpr + " -> " + filter);
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
/*testAttributesToFilter();
|
||||
String x = "012\0003";
|
||||
byte[] b = x.getBytes();
|
||||
for (int i=0; i < b.length; i++) {
|
||||
System.out.println(i+"="+b[i]);
|
||||
}*/
|
||||
testFilterExpr();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
import com.netscape.jndi.ldap.controls.NetscapeControlFactory;
|
||||
import com.netscape.jndi.ldap.common.ExceptionMapper;
|
||||
import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A wrapper for the LDAPSeatchResults. Convert a LDAPSearchResults enumeration
|
||||
* of LDAPEntries into a JNDI NamingEnumeration of JNDI SearchResults.
|
||||
*/
|
||||
class SearchResultEnum implements NamingEnumeration {
|
||||
|
||||
LDAPSearchResults m_res;
|
||||
boolean m_returnObjs; // ReturningObjFlag in SearchControls
|
||||
LdapContextImpl m_ctx;
|
||||
Name m_ctxName;
|
||||
String[] m_userBinaryAttrs;
|
||||
LDAPConnection m_ld;
|
||||
|
||||
public SearchResultEnum(LDAPSearchResults res, boolean returnObjs, LdapContextImpl ctx) throws NamingException{
|
||||
m_res = res;
|
||||
m_returnObjs = returnObjs;
|
||||
m_ctx = ctx;
|
||||
m_userBinaryAttrs = ctx.m_ctxEnv.getUserDefBinaryAttrs();
|
||||
|
||||
m_ld = m_ctx.m_ldapSvc.getConnection();
|
||||
try {
|
||||
m_ctxName = LdapNameParser.getParser().parse(m_ctx.m_ctxDN);
|
||||
}
|
||||
catch ( NamingException e ) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object next() throws NamingException{
|
||||
try {
|
||||
LDAPEntry entry = m_res.next();
|
||||
String name = LdapNameParser.getRelativeName(m_ctxName, entry.getDN());
|
||||
Object obj = (m_returnObjs) ? ObjectMapper.entryToObject(entry, m_ctx) : null;
|
||||
Attributes attrs = new AttributesImpl(entry.getAttributeSet(), m_userBinaryAttrs);
|
||||
|
||||
// check for response controls
|
||||
LDAPControl[] ldapCtls = m_ld.getResponseControls();
|
||||
if (ldapCtls != null) {
|
||||
// Parse raw controls
|
||||
Control[] ctls = new Control[ldapCtls.length];
|
||||
for (int i=0; i < ldapCtls.length; i++) {
|
||||
ctls[i] = NetscapeControlFactory.getControlInstance(ldapCtls[i]);
|
||||
if (ctls[i] == null) {
|
||||
throw new NamingException("Unsupported control " + ldapCtls[i].getID());
|
||||
}
|
||||
}
|
||||
|
||||
SearchResultWithControls searchRes =
|
||||
new SearchResultWithControls(name, obj, attrs);
|
||||
searchRes.setControls(ctls);
|
||||
|
||||
return searchRes;
|
||||
}
|
||||
else { // no controls
|
||||
return new SearchResult(name, obj, attrs);
|
||||
}
|
||||
|
||||
}
|
||||
catch (LDAPReferralException e) {
|
||||
throw new LdapReferralException(m_ctx, e);
|
||||
}
|
||||
catch ( LDAPException e ) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
try {
|
||||
return next();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
System.err.println( "Error in SearchResultEnum.nextElement(): " + e.toString() );
|
||||
e.printStackTrace(System.err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException {
|
||||
return m_res.hasMoreElements();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return m_res.hasMoreElements();
|
||||
}
|
||||
|
||||
public void close() throws NamingException{
|
||||
try {
|
||||
m_ld.abandon(m_res);
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap;
|
||||
|
||||
import javax.naming.ldap.*;
|
||||
import javax.naming.directory.*;
|
||||
|
||||
/**
|
||||
* An extension of SearchResult that allows access to controls sent
|
||||
* back with the results of a search
|
||||
*/
|
||||
class SearchResultWithControls extends SearchResult implements HasControls {
|
||||
|
||||
Control[] m_ctrls;
|
||||
|
||||
/**
|
||||
* Enable constructors
|
||||
*/
|
||||
public SearchResultWithControls(String name, Object obj, Attributes attrs) {
|
||||
super(name, obj, attrs);
|
||||
}
|
||||
|
||||
public SearchResultWithControls(String name, Object obj, Attributes attrs, boolean isRelative) {
|
||||
super(name, obj, attrs, isRelative);
|
||||
}
|
||||
|
||||
public SearchResultWithControls(String name, String className, Object obj, Attributes attrs) {
|
||||
super(name, className, obj, attrs);
|
||||
}
|
||||
|
||||
public SearchResultWithControls(String name, String className, Object obj, Attributes attrs, boolean isRelative) {
|
||||
super(name, className, obj, attrs, isRelative);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements HasControls interface
|
||||
*/
|
||||
public Control[] getControls() {
|
||||
return m_ctrls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set controls array
|
||||
*/
|
||||
public void setControls(Control[] ctrls) {
|
||||
m_ctrls = ctrls;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.common;
|
||||
|
||||
|
||||
/**
|
||||
* Class used to selectivly enable debug statements
|
||||
*/
|
||||
public class Debug {
|
||||
|
||||
// lower number is a higher priority message. Level 0 is the
|
||||
// highest priority to be used ONLY for errors
|
||||
private static int m_level = 0;
|
||||
|
||||
static {
|
||||
try {
|
||||
String level = System.getProperty("jndi.netscape.debug");
|
||||
if (level != null) {
|
||||
m_level = Integer.parseInt(level);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the debug level. To disable debugging set the level to -1
|
||||
*/
|
||||
public static void setDebugLevel(int level) {
|
||||
m_level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the debug level. If -1 is returned, then debugging is disabled
|
||||
*/
|
||||
public static int getDebugLevel() {
|
||||
return m_level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the message if its debug level is enabled
|
||||
*/
|
||||
public static void println(int level, String msg) {
|
||||
if (m_level >= 0 && level <= m_level) {
|
||||
System.err.println(msg);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.common;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class DirContextAdapter implements DirContext {
|
||||
|
||||
/* Context Methods */
|
||||
|
||||
public Object addToEnvironment(String propName, Object propValue) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void bind(String name, Object obj) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void close() throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public String composeName(String name, String prefix) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Name composeName(Name name, Name prefix) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Context createSubcontext(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Context createSubcontext(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void destroySubcontext(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void destroySubcontext(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Hashtable getEnvironment() throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public String getNameInNamespace() throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NameParser getNameParser(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NameParser getNameParser(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration list(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration list(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Object lookup(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Object lookup(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Object lookupLink(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Object lookupLink(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Object removeFromEnvironment(String propName) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rename(String oldName, String newName) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rename(Name oldName, Name newName) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void unbind(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void unbind(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
|
||||
/* DirContext Methods */
|
||||
|
||||
public void bind(String name, Object obj, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(String name, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext getSchema(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext getSchema(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration search(String name, String filter, SearchControls cons) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration search(String name, Attributes matchingAttributes) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration search(String name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration search(Name name, String filter, SearchControls cons) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration search(Name name, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public NamingEnumeration search(Name name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.common;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* Class used to map ldapjdk exceptions to JNDI NamingException
|
||||
*/
|
||||
public class ExceptionMapper {
|
||||
|
||||
public static NamingException getNamingException(Exception origException) {
|
||||
|
||||
if (origException instanceof NamingException) {
|
||||
return (NamingException)origException;
|
||||
}
|
||||
|
||||
/**
|
||||
* LdapJDK exceptions
|
||||
*/
|
||||
else if (origException instanceof LDAPReferralException) {
|
||||
// Should never get here. The ldapjdk referral exceptions
|
||||
// should be explicitly captured by the ecode and converted
|
||||
// into jndi LdapReferralException instances.
|
||||
return new NamingException("Provider internal error, LDAPReferralException not captured");
|
||||
}
|
||||
|
||||
else if (origException instanceof LDAPException) {
|
||||
LDAPException ldapException = (LDAPException) origException;
|
||||
int resCode = ldapException.getLDAPResultCode();
|
||||
|
||||
if (resCode == LDAPException.OPERATION_ERROR) {
|
||||
NamingException nameEx = new NamingException(ldapException.toString());
|
||||
nameEx.setRootCause(ldapException);
|
||||
return nameEx;
|
||||
}
|
||||
else if (resCode == LDAPException.PROTOCOL_ERROR) {
|
||||
return new CommunicationException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.TIME_LIMIT_EXCEEDED) {
|
||||
return new TimeLimitExceededException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.SIZE_LIMIT_EXCEEDED) {
|
||||
return new SizeLimitExceededException(ldapException.toString());
|
||||
}
|
||||
// COMPARE_FALSE should never happen, but is included here for completeness
|
||||
else if (resCode == LDAPException.COMPARE_FALSE) {
|
||||
NamingException nameEx = new NamingException(ldapException.toString());
|
||||
nameEx.setRootCause(ldapException);
|
||||
return nameEx;
|
||||
}
|
||||
// COMPARE_TRUE should never happen, but is included here for completeness
|
||||
else if (resCode == LDAPException.COMPARE_TRUE) {
|
||||
NamingException nameEx = new NamingException(ldapException.toString());
|
||||
nameEx.setRootCause(ldapException);
|
||||
return nameEx;
|
||||
}
|
||||
else if (resCode == LDAPException.AUTH_METHOD_NOT_SUPPORTED) {
|
||||
return new AuthenticationNotSupportedException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.STRONG_AUTH_REQUIRED) {
|
||||
return new AuthenticationNotSupportedException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.LDAP_PARTIAL_RESULTS) {
|
||||
return new PartialResultException(ldapException.toString());
|
||||
}
|
||||
// REFERRAL code should be in LDAPReferralException
|
||||
else if (resCode == LDAPException.REFERRAL) {
|
||||
LDAPReferralException referralEx = (LDAPReferralException)ldapException;
|
||||
// TODO create jndi LdapReferralException
|
||||
}
|
||||
else if (resCode == LDAPException.ADMIN_LIMIT_EXCEEDED) {
|
||||
return new LimitExceededException(ldapException.toString());
|
||||
}
|
||||
else if(resCode == LDAPException.UNAVAILABLE_CRITICAL_EXTENSION) {
|
||||
return new OperationNotSupportedException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.CONFIDENTIALITY_REQUIRED) {
|
||||
return new AuthenticationNotSupportedException(
|
||||
"A secure connection is required for this operation");
|
||||
}
|
||||
// This shoud never propagate to the caller
|
||||
else if (resCode == LDAPException.SASL_BIND_IN_PROGRESS) {
|
||||
NamingException nameEx = new NamingException(ldapException.toString());
|
||||
nameEx.setRootCause(ldapException);
|
||||
return nameEx;
|
||||
}
|
||||
else if (resCode == LDAPException.NO_SUCH_ATTRIBUTE) {
|
||||
return new NoSuchAttributeException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.UNDEFINED_ATTRIBUTE_TYPE) {
|
||||
return new InvalidAttributeIdentifierException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.INAPPROPRIATE_MATCHING) {
|
||||
return new InvalidSearchFilterException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.CONSTRAINT_VIOLATION) {
|
||||
return new InvalidSearchControlsException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.ATTRIBUTE_OR_VALUE_EXISTS) {
|
||||
return new AttributeInUseException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.INVALID_ATTRIBUTE_SYNTAX) {
|
||||
return new InvalidAttributeValueException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.NO_SUCH_OBJECT) {
|
||||
return new NameNotFoundException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.ALIAS_PROBLEM) {
|
||||
return new NamingException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.INVALID_DN_SYNTAX) {
|
||||
return new InvalidNameException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.IS_LEAF) {
|
||||
NamingException nameEx = new NamingException(ldapException.toString());
|
||||
nameEx.setRootCause(ldapException);
|
||||
return nameEx;
|
||||
}
|
||||
else if (resCode == LDAPException.ALIAS_DEREFERENCING_PROBLEM) {
|
||||
NamingException nameEx = new NamingException(ldapException.toString());
|
||||
nameEx.setRootCause(ldapException);
|
||||
return nameEx;
|
||||
}
|
||||
else if (resCode == LDAPException.INAPPROPRIATE_AUTHENTICATION) {
|
||||
//return new AuthenticationNotSupportedException(ldapException.toString());
|
||||
return new AuthenticationException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.INVALID_CREDENTIALS) {
|
||||
return new AuthenticationException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.INSUFFICIENT_ACCESS_RIGHTS) {
|
||||
return new NoPermissionException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.BUSY) {
|
||||
return new ServiceUnavailableException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.UNAVAILABLE) {
|
||||
return new ServiceUnavailableException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.UNWILLING_TO_PERFORM) {
|
||||
return new OperationNotSupportedException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.LOOP_DETECT) {
|
||||
NamingException nameEx = new NamingException(ldapException.toString());
|
||||
nameEx.setRootCause(ldapException);
|
||||
return nameEx;
|
||||
}
|
||||
else if (resCode == LDAPException.NAMING_VIOLATION) {
|
||||
return new InvalidNameException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.OBJECT_CLASS_VIOLATION) {
|
||||
return new SchemaViolationException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.NOT_ALLOWED_ON_NONLEAF) {
|
||||
return new ContextNotEmptyException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.NOT_ALLOWED_ON_RDN) {
|
||||
return new SchemaViolationException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.ENTRY_ALREADY_EXISTS) {
|
||||
return new NameAlreadyBoundException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.OBJECT_CLASS_MODS_PROHIBITED) {
|
||||
return new SchemaViolationException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.SERVER_DOWN) {
|
||||
return new CommunicationException(ldapException.toString());
|
||||
}
|
||||
else if (resCode == LDAPException.CONNECT_ERROR) {
|
||||
return new CommunicationException(ldapException.toString());
|
||||
}
|
||||
|
||||
else {
|
||||
// All other result codes
|
||||
// 71 AFFECTS_MULTIPLE_DSAS
|
||||
// 80 OTHER
|
||||
// 89 PARAM_ERROR
|
||||
// 92 LDAP_NOT_SUPPORTED
|
||||
// 93 CONTROL_NOT_FOUND
|
||||
// 94 NO_RESULTS_RETURNED
|
||||
// 95 MORE_RESULTS_TO_RETURN
|
||||
// 96 CLIENT_LOOP referral
|
||||
// 97 REFERRAL_LIMIT_EXCEEDED referral
|
||||
|
||||
NamingException nameEx = new NamingException(ldapException.toString());
|
||||
nameEx.setRootCause(ldapException);
|
||||
return nameEx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All other Exceptions
|
||||
*/
|
||||
NamingException nameEx = new NamingException(origException.toString());
|
||||
nameEx.setRootCause(origException);
|
||||
return nameEx;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.common;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
import javax.naming.event.*;
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class LdapContextAdapter extends DirContextAdapter implements EventDirContext, LdapContext {
|
||||
|
||||
/* LdapContext methods */
|
||||
public ExtendedResponse extendedOperation(ExtendedRequest req)throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Control[] getRequestControls() throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Control[] getResponseControls() throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public LdapContext newInstance(Control[] reqCtls) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void reconnect() throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void setRequestControls(Control[] reqCtls) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
/**
|
||||
* Naming Event methods
|
||||
*/
|
||||
public void addNamingListener(String target, int scope, NamingListener l) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void addNamingListener(Name target, int scope, NamingListener l) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void addNamingListener(String target, String filter, SearchControls ctls, NamingListener l)throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void addNamingListener(Name target, String filter, SearchControls ctls, NamingListener l)throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void addNamingListener(String target, String filter, Object[] filtrArgs, SearchControls ctls, NamingListener l)throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void addNamingListener(Name target, String filter, Object[] filtrArgs, SearchControls ctls, NamingListener l)throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void removeNamingListener(NamingListener l) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public boolean targetMustExist() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,404 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.common;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* ShareableEnv manages a set of environment properties. The class enables a memory
|
||||
* efficient sharing of the environment between multiple contexts, while preserving
|
||||
* the semantics that each context has its own environment. If the environment for a
|
||||
* context is changed, the change is not visible to other contexts.
|
||||
*
|
||||
* The efficiency is achieved by implementing inheritance and override of environment
|
||||
* properties ("subclass-on-write"). A read-only table of properties
|
||||
* is shared among multiple contexts (<code>_sharedEnv</code>. If a context wants to
|
||||
* modified a shared property, it will create a separate table (<code>_privateEnv</code>)
|
||||
* to make the modifications. This table overrides the values in the shared table.
|
||||
*
|
||||
* Note1: The class is not thread safe, it requires external synchronization
|
||||
* Note2: The class does not provide enumaration. Call getAllProperties() and then
|
||||
* use the standard Hashtable enumaration techniques.
|
||||
*/
|
||||
public class ShareableEnv implements Cloneable{
|
||||
|
||||
/**
|
||||
* A special value that denotes a removed propety. Because shared property tables
|
||||
* are read-only, a shared property is deleted in the curent context by assigning
|
||||
* the REMOVED_PROPERTY value in the _modEnv table.
|
||||
*/
|
||||
private static final Object REMOVED_PROPERTY = new Object();
|
||||
|
||||
/**
|
||||
* A table of most recent environment modifications. These modifications are not
|
||||
* shared until the current context is cloned, which moves _privateEnv to
|
||||
* _sharedEnv
|
||||
*/
|
||||
protected Hashtable m_privateEnv;
|
||||
|
||||
/**
|
||||
* A set of environment propeties that have been changed in this Context and are
|
||||
* shared with one or more child contexts. Read-only access.
|
||||
*/
|
||||
protected Vector m_sharedEnv; // A vector of Hashtables
|
||||
|
||||
/**
|
||||
* Shared environment inherited from the parent context
|
||||
*/
|
||||
protected ShareableEnv m_parentEnv;
|
||||
|
||||
/**
|
||||
* Index into parent _sharedEnv list. Designates all environment chnages
|
||||
* in the parent context that are visible to this child context
|
||||
*/
|
||||
protected int m_parentSharedEnvIdx = -1;
|
||||
|
||||
/**
|
||||
* No-arg constructor is private
|
||||
*/
|
||||
private ShareableEnv() {}
|
||||
|
||||
/**
|
||||
* Constructor for non root Contexts
|
||||
*
|
||||
* @param parent A reference to the parent context environment
|
||||
* @param parentSharedEnvIdx index into parent's shared environemnt list
|
||||
*/
|
||||
public ShareableEnv(ShareableEnv parent, int parentSharedEnvIdx) {
|
||||
m_parentEnv = parent;
|
||||
m_parentSharedEnvIdx = parentSharedEnvIdx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the root context
|
||||
*
|
||||
* @param initialEnv a hashtable with environemnt properties
|
||||
*/
|
||||
public ShareableEnv(Hashtable initialEnv) {
|
||||
m_privateEnv = initialEnv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the property value.
|
||||
*
|
||||
* @return the previous value of the specified property,
|
||||
* or <code>null</code> if it did not exist before.
|
||||
* @param prop property name
|
||||
* @param val property value
|
||||
*/
|
||||
public Object setProperty(String prop, Object val) {
|
||||
|
||||
// Need the current value to be returned
|
||||
Object oldVal = getProperty(prop);
|
||||
|
||||
// Lazy create _privateEnv table
|
||||
if (m_privateEnv == null) {
|
||||
m_privateEnv = new Hashtable(5);
|
||||
}
|
||||
|
||||
// Add/Modify property
|
||||
m_privateEnv.put(prop, val);
|
||||
|
||||
return oldVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property value.
|
||||
*
|
||||
* @return the object associated with the property name
|
||||
* or <code>null</code> if property is not found
|
||||
* @param prop property name
|
||||
*/
|
||||
public Object getProperty(String prop) {
|
||||
|
||||
// First check most recent modifications
|
||||
if (m_privateEnv != null) {
|
||||
Object val = m_privateEnv.get(prop);
|
||||
if (val != null) {
|
||||
return (val == REMOVED_PROPERTY) ? null : val;
|
||||
}
|
||||
}
|
||||
|
||||
// Then try shared properties
|
||||
if (m_sharedEnv != null) {
|
||||
return getSharedProperty(m_sharedEnv.size()-1, prop);
|
||||
}
|
||||
else {
|
||||
return getSharedProperty(-1, prop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property value for the specified _sharedEnv index
|
||||
*
|
||||
* @return the object associated with the property name
|
||||
* @param envIdx start index in the shared environment list
|
||||
* @param prop property name
|
||||
*/
|
||||
private Object getSharedProperty(int envIdx, String prop) {
|
||||
|
||||
// Check first the frozen updtates list
|
||||
if (envIdx >= 0) {
|
||||
for (int i= envIdx; i >= 0; i--) {
|
||||
Hashtable tab = (Hashtable) m_sharedEnv.elementAt(i);
|
||||
Object val = tab.get(prop);
|
||||
if (val != null) {
|
||||
return (val == REMOVED_PROPERTY) ? null : val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the parent env context
|
||||
if (m_parentSharedEnvIdx >= 0) {
|
||||
return m_parentEnv.getSharedProperty(m_parentSharedEnvIdx, prop);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove property
|
||||
*
|
||||
* @return the previous value of the specified property,
|
||||
* or <code>null</code> if it did not exist before.
|
||||
* @param prop property name
|
||||
*/
|
||||
public Object removeProperty(String prop) {
|
||||
|
||||
Object val = null;
|
||||
// Is this a shared property ?
|
||||
if (m_sharedEnv != null) {
|
||||
val = getSharedProperty(m_sharedEnv.size()-1, prop);
|
||||
}
|
||||
else {
|
||||
val = getSharedProperty(-1, prop);
|
||||
}
|
||||
|
||||
if (val == null) { // Not a shared property, remove if physically
|
||||
if (m_privateEnv != null) {
|
||||
return m_privateEnv.remove(prop);
|
||||
}
|
||||
}
|
||||
else { //A shared property, hide it
|
||||
setProperty(prop, REMOVED_PROPERTY);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a table of all properties. First read all properties from the parent env,
|
||||
* then merge the local updates. Notice that the data is processed in reverse order
|
||||
* than in the getProperty method.
|
||||
*
|
||||
* @return a hashtable containing all properties visible in this context
|
||||
*/
|
||||
public Hashtable getAllProperties() {
|
||||
Hashtable res = null;
|
||||
|
||||
// First copy shared properties
|
||||
if (m_sharedEnv != null) {
|
||||
res = getAllSharedProperties(m_sharedEnv.size()-1);
|
||||
}
|
||||
else {
|
||||
res = getAllSharedProperties(-1);
|
||||
}
|
||||
|
||||
if (res == null) {
|
||||
res = new Hashtable(51);
|
||||
}
|
||||
|
||||
// Then apply private env
|
||||
if (m_privateEnv != null) {
|
||||
Hashtable tab = m_privateEnv;
|
||||
for (Enumeration e = tab.keys(); e.hasMoreElements();) {
|
||||
Object key = e.nextElement();
|
||||
Object val = tab.get(key);
|
||||
if (val != REMOVED_PROPERTY) {
|
||||
res.put(key, val);
|
||||
}
|
||||
else {
|
||||
res.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a table of all shared properties for the given envIdx. First read all
|
||||
* properties from the parent env, then merge the local environment.
|
||||
*
|
||||
* @return a hashtable containing all properties visible for the shared environment index
|
||||
* @param envIdx start index in the shared environment list
|
||||
*/
|
||||
private Hashtable getAllSharedProperties(int envIdx) {
|
||||
Hashtable res = null;
|
||||
|
||||
// First copy parent env
|
||||
if (m_parentEnv != null) {
|
||||
res = m_parentEnv.getAllSharedProperties(m_parentSharedEnvIdx);
|
||||
}
|
||||
|
||||
if (res == null) {
|
||||
res = new Hashtable(51);
|
||||
}
|
||||
|
||||
// Then copy _sharedEnv (older entries are processed before newer ones)
|
||||
if (envIdx >= 0) {
|
||||
for (int i= 0; i <= envIdx; i++) {
|
||||
Hashtable tab = (Hashtable) m_sharedEnv.elementAt(i);
|
||||
for (Enumeration e = tab.keys(); e.hasMoreElements();) {
|
||||
Object key = e.nextElement();
|
||||
Object val = tab.get(key);
|
||||
if (val != REMOVED_PROPERTY) {
|
||||
res.put(key, val);
|
||||
}
|
||||
else {
|
||||
res.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Freeze all environment changes changes in the current context. The "Freeze" is
|
||||
* done by moving the _privateEnv table to _sharedEnv vector.
|
||||
*/
|
||||
protected void freezeUpdates() {
|
||||
if (m_privateEnv != null) {
|
||||
// Lazy create _sharedEnv vector
|
||||
if (m_sharedEnv == null) {
|
||||
m_sharedEnv = new Vector();
|
||||
}
|
||||
m_sharedEnv.addElement(m_privateEnv);
|
||||
m_privateEnv = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone ShareableEnv
|
||||
*
|
||||
* @return A "clone" of the current context environment
|
||||
*/
|
||||
public Object clone() {
|
||||
|
||||
// First freeze updates for this context
|
||||
freezeUpdates();
|
||||
|
||||
// If the context has been modified, then it is the parent of the clone
|
||||
if (m_sharedEnv != null) {
|
||||
return new ShareableEnv(this, m_sharedEnv.size()-1);
|
||||
}
|
||||
|
||||
// No changes has been done to the inherited parent context. Pass the parent
|
||||
// context to the clone
|
||||
else {
|
||||
return new ShareableEnv(m_parentEnv, m_parentSharedEnvIdx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string representation of the object
|
||||
*
|
||||
* @return a string representation of the object
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("ShareableEnv private=");
|
||||
if (m_privateEnv != null) {
|
||||
buf.append("(");
|
||||
buf.append(m_privateEnv.size());
|
||||
buf.append(")");
|
||||
}
|
||||
buf.append(" shared=");
|
||||
if (m_sharedEnv != null) {
|
||||
for (int i=0; i < m_sharedEnv.size(); i++) {
|
||||
Hashtable tab = (Hashtable) m_sharedEnv.elementAt(i);
|
||||
buf.append("(");
|
||||
buf.append(tab.size());
|
||||
buf.append(")");
|
||||
}
|
||||
}
|
||||
buf.append(" parentIdx=");
|
||||
buf.append(m_parentSharedEnvIdx);
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test program
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
ShareableEnv c0 = new ShareableEnv(null, -1); // c=context 0=level 0=index
|
||||
System.err.println("c0.getProperty(p1)=" + c0.getProperty("p1"));
|
||||
System.err.println("c0.getAllProperties()=" + c0.getAllProperties());
|
||||
System.err.println("c0.setProperty(p1,vxxx)=" + c0.setProperty("p1", "vxxx"));
|
||||
System.err.println("c0.setProperty(p2,v2)=" + c0.setProperty("p2", "v2"));
|
||||
System.err.println("c0.setProperty(p3,v3)=" + c0.setProperty("p3", "v3"));
|
||||
System.err.println("c0.setProperty(p1,v1)=" + c0.setProperty("p1", "v1"));
|
||||
System.err.println("c0.getAllProperties()=" + c0.getAllProperties());
|
||||
|
||||
System.err.println("---");
|
||||
ShareableEnv c01 = (ShareableEnv)c0.clone();
|
||||
System.err.println("c01.getProperty(p1)=" + c01.getProperty("p1"));
|
||||
System.err.println("c01.getAllProperties()=" + c01.getAllProperties());
|
||||
System.err.println("c01.setProperty(p1,v1a)=" + c01.setProperty("p1", "v1a"));
|
||||
System.err.println("c01.getProperty(p1)=" + c01.getProperty("p1"));
|
||||
System.err.println("c01.removeProperty(p2)=" + c01.removeProperty("p2"));
|
||||
System.err.println("c01.getProperty(p2)=" + c01.getProperty("p2"));
|
||||
System.err.println("c01.setProperty(p11,v11a)=" + c01.setProperty("p11", "v11a"));
|
||||
System.err.println("c01.getAllProperties()=" + c01.getAllProperties());
|
||||
|
||||
System.err.println("---");
|
||||
ShareableEnv c02 = (ShareableEnv)c0.clone();
|
||||
System.err.println("c02.getProperty(p1)=" + c02.getProperty("p1"));
|
||||
System.err.println("c02.getAllProperties()=" + c02.getAllProperties());
|
||||
|
||||
System.err.println("---");
|
||||
ShareableEnv c011 = (ShareableEnv)c01.clone();
|
||||
System.err.println("c011.getProperty(p1)=" + c011.getProperty("p1"));
|
||||
System.err.println("c011.getAllProperties()=" + c011.getAllProperties());
|
||||
System.err.println("c011.setProperty(p1,v11b)=" + c011.setProperty("p1", "v11b"));
|
||||
System.err.println("c011.getProperty(p1)=" + c011.getProperty("p1"));
|
||||
System.err.println("c011.getAllProperties()=" + c011.getAllProperties());
|
||||
|
||||
System.err.println("---");
|
||||
System.err.println("c01.getAllProperties()=" + c01.getAllProperties());
|
||||
System.err.println("c01.removeProperty(p11)=" + c01.removeProperty("p11"));
|
||||
System.err.println("c01.getAllProperties()=" + c01.getAllProperties());
|
||||
System.err.println("c011.getAllProperties()=" + c011.getAllProperties());
|
||||
|
||||
System.err.println("---");
|
||||
ShareableEnv c012 = (ShareableEnv)c01.clone();
|
||||
System.err.println("c012.getAllProperties()=" + c012.getAllProperties());
|
||||
System.err.println("c012.getProperty(p1)=" + c012.getProperty("p1"));
|
||||
|
||||
System.err.println("---");
|
||||
System.err.println("c0="+c0);
|
||||
System.err.println("c01="+c01);
|
||||
System.err.println("c02="+c02);
|
||||
System.err.println("c011="+c011);
|
||||
System.err.println("c012="+c012);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.controls;
|
||||
|
||||
/**
|
||||
* Represents an LDAP v3 server control that specifies information
|
||||
* about a change to an entry in the directory. (The OID for this
|
||||
* control is 2.16.840.1.113730.3.4.7.) You need to use this control in
|
||||
* conjunction with a "persistent search" control (represented
|
||||
* by <CODE>LdapPersistentSearchControl</CODE> object.
|
||||
* <P>
|
||||
*
|
||||
* To use persistent searching for change notification, you create a
|
||||
* "persistent search" control that specifies the types of changes that
|
||||
* you want to track. When an entry is changed, the server sends that
|
||||
* entry back to your client and may include an "entry change notification"
|
||||
* control that specifies additional information about the change.
|
||||
* <P>
|
||||
*
|
||||
* Typically, you use the <CODE>getResponseControls</CODE> method of
|
||||
* the <CODE>LDAPConnection</CODE> object and the <CODE>parseResponse</CODE>
|
||||
* method of the <CODE>LdapPersistSearchControl</CODE> object to get
|
||||
* an <CODE>LdapEntryChangeControl</CODE> object.
|
||||
* <P>
|
||||
*
|
||||
* Once you retrieve an <CODE>LdapEntryChangeControl</CODE> object from
|
||||
* the server, you can get the following additional information about
|
||||
* the change made to the entry:
|
||||
* <P>
|
||||
*
|
||||
* <UL>
|
||||
* <LI>The type of change made (add, modify, delete, or modify DN)
|
||||
* <LI>The change number identifying the record of the change in the
|
||||
* change log (if the server supports change logs)
|
||||
* <LI>If the entry was renamed, the old DN of the entry
|
||||
* </UL>
|
||||
* <P>
|
||||
*
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl
|
||||
* @see com.netscape.jndi.ldap.LDAPConnection#getResponseControls
|
||||
*/
|
||||
|
||||
import javax.naming.ldap.Control;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
public class LdapEntryChangeControl extends LDAPEntryChangeControl implements Control {
|
||||
|
||||
/**
|
||||
* Constructs a new <CODE>LdapEntryChangeControl</CODE> object.
|
||||
* This constructor is used by the NetscapeControlFactory
|
||||
*
|
||||
* @see com.netscape.jndi.ldap.LdapControl
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl
|
||||
*/
|
||||
LdapEntryChangeControl(boolean critical, byte[] value) {
|
||||
m_critical = critical;
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the change number (which identifies the record of the change
|
||||
* in the server's change log) in this "entry change notification"
|
||||
* control.
|
||||
* @param num Change number that you want to set.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#getChangeNumber
|
||||
*/
|
||||
public void setChangeNumber(int num) {
|
||||
super.setChangeNumber(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the change type (which identifies the type of change
|
||||
* that occurred) in this "entry change notification" control.
|
||||
* @param num Change type that you want to set. This can be one of
|
||||
* the following values:
|
||||
* <P>
|
||||
*
|
||||
* <UL>
|
||||
* <LI><CODE>LdapPersistSearchControl.ADD</CODE> (a new entry was
|
||||
* added to the directory)
|
||||
* <LI><CODE>LdapPersistSearchControl.DELETE</CODE> (an entry was
|
||||
* removed from the directory)
|
||||
* <LI><CODE>LdapPersistSearchControl.MODIFY</CODE> (an entry was
|
||||
* modified)
|
||||
* <LI><CODE>LdapPersistSearchControl.MODDN</CODE> (an entry was
|
||||
* renamed)
|
||||
* </UL>
|
||||
* <P>
|
||||
*
|
||||
* @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#getChangeType
|
||||
*/
|
||||
public void setChangeType(int num) {
|
||||
super.setChangeType(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the previous DN of the entry (if the entry was renamed)
|
||||
* in the "entry change notification control".
|
||||
* @param dn The previous distinguished name of the entry.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#getPreviousDN
|
||||
*/
|
||||
public void setPreviousDN(String dn) {
|
||||
super.setPreviousDN(dn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the change number, which identifies the record of the change
|
||||
* in the server's change log.
|
||||
* @return Change number identifying the change made.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#setChangeNumber
|
||||
*/
|
||||
public int getChangeNumber() {
|
||||
return super.getChangeNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the change type, which identifies the type of change
|
||||
* that occurred.
|
||||
* @returns Change type identifying the type of change that
|
||||
* occurred. This can be one of the following values:
|
||||
* <P>
|
||||
*
|
||||
* <UL>
|
||||
* <LI><CODE>LdapPersistSearchControl.ADD</CODE> (a new entry was
|
||||
* added to the directory)
|
||||
* <LI><CODE>LdapPersistSearchControl.DELETE</CODE> (an entry was
|
||||
* removed from the directory)
|
||||
* <LI><CODE>LdapPersistSearchControl.MODIFY</CODE> (an entry was
|
||||
* modified)
|
||||
* <LI><CODE>LdapPersistSearchControl.MODDN</CODE> (an entry was
|
||||
* renamed)
|
||||
* </UL>
|
||||
* <P>
|
||||
*
|
||||
* @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#setChangeType
|
||||
*/
|
||||
public int getChangeType() {
|
||||
return super.getChangeType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the previous DN of the entry (if the entry was renamed).
|
||||
* @returns The previous distinguished name of the entry.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#setPreviousDN
|
||||
*/
|
||||
public String getPreviousDN() {
|
||||
return super.getPreviousDN();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Control interface
|
||||
*/
|
||||
public byte[] getEncodedValue() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- 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) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
package com.netscape.jndi.ldap.controls;
|
||||
|
||||
import javax.naming.ldap.Control;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
/**
|
||||
* Represents an LDAP v3 server control that may be returned if a
|
||||
* password has expired, and password policy is enabled on the server.
|
||||
* The OID for this control is 2.16.840.1.113730.3.4.4.
|
||||
* <P>
|
||||
*/
|
||||
|
||||
public class LdapPasswordExpiredControl extends LDAPPasswordExpiredControl implements Control{
|
||||
|
||||
private String m_message;
|
||||
/**
|
||||
* This constractor is used by the NetscapeControlFactory
|
||||
*/
|
||||
LdapPasswordExpiredControl(boolean critical, byte[] value) throws Exception{
|
||||
m_value = value;
|
||||
m_critical = critical;
|
||||
m_message = new String(m_value, "UTF8");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string message passed in the control
|
||||
* TODO what is the information in this string value ?
|
||||
*/
|
||||
public String getMessage() {
|
||||
return m_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Control interface
|
||||
*/
|
||||
public byte[] getEncodedValue() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
package com.netscape.jndi.ldap.controls;
|
||||
|
||||
import javax.naming.ldap.Control;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
/**
|
||||
* Represents an LDAP v3 server control that may be returned if a
|
||||
* password is about to expire, and password policy is enabled on the server.
|
||||
* The OID for this control is 2.16.840.1.113730.3.4.5.
|
||||
* <P>
|
||||
*/
|
||||
public class LdapPasswordExpiringControl extends LDAPPasswordExpiringControl implements Control {
|
||||
|
||||
//number of seconds before password expiration
|
||||
int m_secondsToExpire = -1;
|
||||
|
||||
/**
|
||||
* This constractor is used by the NetscapeControlFactory
|
||||
*/
|
||||
LdapPasswordExpiringControl(boolean critical, byte[] value) throws Exception{
|
||||
m_value = value;
|
||||
m_critical = critical;
|
||||
String msg = new String(m_value, "UTF8");
|
||||
if (msg != null) {
|
||||
m_secondsToExpire = Integer.parseInt(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return parsed number of seconds before password expires
|
||||
*/
|
||||
public int getSecondsToExipre() {
|
||||
return m_secondsToExpire;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Control interface
|
||||
*/
|
||||
public byte[] getEncodedValue() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.controls;
|
||||
|
||||
import javax.naming.ldap.Control;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
/**
|
||||
* Represents an LDAP v3 server control that specifies a persistent
|
||||
* search (an ongoing search operation), which allows your LDAP client
|
||||
* to get notification of changes to the directory. (The OID for this
|
||||
* control is 2.16.840.1.113730.3.4.3.) You can use this control in
|
||||
* conjunction with an "entry change notification" control (represented
|
||||
* by <CODE>LDAPEntryChangeControl</CODE> object.
|
||||
* <P>
|
||||
*
|
||||
* To use persistent searching for change notification, you create a
|
||||
* "persistent search" control that specifies the types of changes that
|
||||
* you want to track. You include the control in a search request.
|
||||
* If an entry in the directory is changed, the server determines if
|
||||
* the entry matches the search criteria in your request and if the
|
||||
* change is the type of change that you are tracking. If both of
|
||||
* these are true, the server sends the entry to your client.
|
||||
* <P>
|
||||
*
|
||||
* The server can also include an "entry change notification" control
|
||||
* with the entry. (The OID for this control is 2.16.840.1.113730.3.4.7.)
|
||||
* This control contains additional information about the
|
||||
* change made to the entry, including the type of change made,
|
||||
* the change number (which corresponds to an item in the server's
|
||||
* change log, if the server supports a change log), and, if the
|
||||
* entry was renamed, the old DN of the entry.
|
||||
* <P>
|
||||
*
|
||||
* When constructing an <CODE>LDAPPersistSearchControl</CODE> object,
|
||||
* you can specify the following information:
|
||||
* <P>
|
||||
*
|
||||
* <UL>
|
||||
* <LI>the type of change you want to track (added, modified, deleted,
|
||||
* or renamed entries)
|
||||
* <LI>a preference indicating whether or not you want the server to
|
||||
* return all entries that initially matched the search criteria
|
||||
* (rather than only the entries that change)
|
||||
* <LI>a preference indicating whether or not you want entry change
|
||||
* notification controls included with every entry returned by the
|
||||
* server
|
||||
* </UL>
|
||||
* <P>
|
||||
* @see com.netscape.jndi.ldap.controls.LDAPEntryChangeControl
|
||||
*/
|
||||
|
||||
public class LdapPersistSearchControl extends LDAPPersistSearchControl implements Control {
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public LdapPersistSearchControl() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <CODE>LdapPersistSearchControl</CODE> object
|
||||
* that specifies a persistent search.
|
||||
*
|
||||
* @param changeTypes The change types to be monitored. You can perform
|
||||
* a bitwise OR on any of the following values and specify the result as
|
||||
* the change types:
|
||||
* <UL>
|
||||
* <LI><CODE>LdapPersistSearchControl.ADD</CODE> (to track new entries
|
||||
* added to the directory)
|
||||
* <LI><CODE>LdapPersistSearchControl.DELETE</CODE> (to track entries
|
||||
* removed from the directory)
|
||||
* <LI><CODE>LdapPersistSearchControl.MODIFY</CODE> (to track entries
|
||||
* that have been modified)
|
||||
* <LI><CODE>LdapPersistSearchControl.MODDN</CODE> (to track entries
|
||||
* that have been renamed)
|
||||
* </UL>
|
||||
* @param changesOnly <code>true</code> if you do not want the server
|
||||
* to return all existing entries in the directory that match the
|
||||
* search criteria. (You just want the changed entries to be returned.)
|
||||
* @param returnControls <code>true</code> you want the server to return
|
||||
* entry change controls with each entry in the search results.
|
||||
* @param isCritical <code>true</code> if this control is critical to
|
||||
* the search operation (for example, if the server does not support
|
||||
* this control, you may not want the server to perform the search
|
||||
* at all.)
|
||||
* @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl
|
||||
*/
|
||||
public LdapPersistSearchControl(int changeTypes, boolean changesOnly,
|
||||
boolean returnControls, boolean isCritical) {
|
||||
super(changeTypes, changesOnly, returnControls, isCritical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the change types monitored by this control.
|
||||
* @return Integer representing the change types that you want monitored.
|
||||
* This value can be the bitwise OR of <code>ADD, DELETE, MODIFY,</code>
|
||||
* and/or <code>MODDN</code>. If the change type is unknown,
|
||||
* this method returns -1.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#setChangeTypes
|
||||
*/
|
||||
public int getChangeTypes() {
|
||||
return super.getChangeTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether you want the server to send any existing
|
||||
* entries that already match the search criteria or only the
|
||||
* entries that have changed.
|
||||
* @return If <code>true</code>, the server returns only the
|
||||
* entries that have changed. If <code>false</code>, the server
|
||||
* also returns any existing entries that match the search criteria
|
||||
* but have not changed.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#setChangesOnly
|
||||
*/
|
||||
public boolean getChangesOnly() {
|
||||
return super.getChangesOnly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether or not the server includes an "entry change
|
||||
* notification" control with each entry it sends back to the client
|
||||
* during the persistent search.
|
||||
* @return <code>true</code> if the server includes "entry change
|
||||
* notification" controls with the entries it sends during the
|
||||
* persistent search.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#setReturnControls
|
||||
*/
|
||||
public boolean getReturnControls() {
|
||||
return super.getReturnControls();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the change types that you want monitored by this control.
|
||||
* @param types Integer representing the change types that you want monitored.
|
||||
* This value can be the bitwise OR of <code>ADD, DELETE, MODIFY,</code>
|
||||
* and/or <code>MODDN</code>.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#getChangeTypes
|
||||
*/
|
||||
public void setChangeTypes(int types) {
|
||||
super.setChangeTypes(types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether you want the server to send any existing
|
||||
* entries that already match the search criteria or only the
|
||||
* entries that have changed.
|
||||
* @param changesOnly If <code>true</code>, the server returns only the
|
||||
* entries that have changed. If <code>false</code>, the server
|
||||
* also returns any existing entries that match the search criteria
|
||||
* but have not changed.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#getChangesOnly
|
||||
*/
|
||||
public void setChangesOnly(boolean changesOnly) {
|
||||
super.setChangesOnly(changesOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether you want the server to include an "entry change
|
||||
* notification" control with each entry it sends back to the client
|
||||
* during the persistent search.
|
||||
* @param returnControls If <code>true</code>, the server includes
|
||||
* "entry change notification" controls with the entries it sends
|
||||
* during the persistent search.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#setReturnControls
|
||||
*/
|
||||
public void setReturnControls(boolean returnControls) {
|
||||
super.setReturnControls(returnControls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Control interface
|
||||
*/
|
||||
public byte[] getEncodedValue() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.controls;
|
||||
|
||||
import javax.naming.ldap.Control;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
/**
|
||||
* Represents an LDAP v3 server control that specifies that you want
|
||||
* the server to use the specified DN's identity for this operation.
|
||||
* (The OID for this control is 2.16.840.1.113730.3.4.12.)
|
||||
* <P>
|
||||
*
|
||||
* You can include the control in any request by constructing
|
||||
* an <CODE>LDAPSearchConstraints</CODE> object and calling the
|
||||
* <CODE>setServerControls</CODE> method. You can then pass this
|
||||
* <CODE>LDAPSearchConstraints</CODE> object to the <CODE>search</CODE>
|
||||
* or other request method of an <CODE>LDAPConnection</CODE> object.
|
||||
* <P>
|
||||
*
|
||||
* For example:
|
||||
* <PRE>
|
||||
* ...
|
||||
* LDAPConnection ld = new LDAPConnection();
|
||||
* try {
|
||||
* // Connect to server.
|
||||
* ld.connect( 3, hostname, portnumber, "", "" );
|
||||
*
|
||||
* // Create a "critical" proxied auth server control using
|
||||
* // the DN "uid=charlie,ou=people,o=acme.com".
|
||||
* LDAPProxiedAuthControl ctrl =
|
||||
* new LDAPProxiedAuthControl( "uid=charlie,ou=people,o=acme.com",
|
||||
* true );
|
||||
*
|
||||
* // Create search constraints to use that control.
|
||||
* LDAPSearchConstraints cons = new LDAPSearchConstraints();
|
||||
* cons.setServerControls( sortCtrl );
|
||||
*
|
||||
* // Send the search request.
|
||||
* LDAPSearchResults res = ld.search( "o=Airius.com",
|
||||
* LDAPv3.SCOPE_SUB, "(cn=Barbara*)", null, false, cons );
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* </PRE>
|
||||
*
|
||||
* <P>
|
||||
* @see com.netscape.jndi.ldap.LdapSearchConstraints
|
||||
* @see com.netscape.jndi.ldap.LdapSearchConstraints#setServerControls(LDAPControl)
|
||||
*/
|
||||
public class LdapProxiedAuthControl extends LDAPProxiedAuthControl implements Control {
|
||||
|
||||
/**
|
||||
* Constructs an <CODE>LdapProxiedAuthControl</CODE> object with a
|
||||
* DN to use as identity.
|
||||
* @param dn DN to use as identity for execution of a request.
|
||||
* @param critical <CODE>true</CODE> if the LDAP operation should be
|
||||
* discarded when the server does not support this control (in other
|
||||
* words, this control is critical to the LDAP operation).
|
||||
*/
|
||||
public LdapProxiedAuthControl( String dn,
|
||||
boolean critical) {
|
||||
super( dn, critical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Control interface
|
||||
*/
|
||||
public byte[] getEncodedValue() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,257 @@
|
|||
/* -*- 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) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
package com.netscape.jndi.ldap.controls;
|
||||
|
||||
import javax.naming.ldap.Control;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
/**
|
||||
* Represents an LDAP v3 server control that specifies that you want
|
||||
* the server to return sorted search results. (The OID for this
|
||||
* control is 1.2.840.113556.1.4.473.)
|
||||
* <P>
|
||||
*
|
||||
* When constructing an <CODE>LDAPSortControl</CODE> object, you can
|
||||
* specify the order in which you want the results sorted.
|
||||
* You can also specify whether or not this control is critical
|
||||
* to the search operation.
|
||||
* <P>
|
||||
*
|
||||
* To specify the sort order, you construct an <CODE>LDAPSortKey</CODE>
|
||||
* object and pass it to the <CODE>LDAPSortControl</CODE> constructor.
|
||||
* The <CODE>LDAPSortKey</CODE> object represents a list of the attribute
|
||||
* types used for sorting (a "sort key list").
|
||||
* <P>
|
||||
*
|
||||
* You can include the control in a search request by constructing
|
||||
* an <CODE>LDAPSearchConstraints</CODE> object and calling the
|
||||
* <CODE>setServerControls</CODE> method. You can then pass this
|
||||
* <CODE>LDAPSearchConstraints</CODE> object to the <CODE>search</CODE>
|
||||
* method of an <CODE>LDAPConnection</CODE> object.
|
||||
* <P>
|
||||
*
|
||||
* For example:
|
||||
* <PRE>
|
||||
* ...
|
||||
* LDAPConnection ld = new LDAPConnection();
|
||||
* try {
|
||||
* // Connect to server.
|
||||
* ld.connect( 3, hostname, portnumber, "", "" );
|
||||
*
|
||||
* // Create a sort key that specifies the sort order.
|
||||
* LDAPSortKey sortOrder = new LDAPSortKey( attrname );
|
||||
*
|
||||
* // Create a "critical" server control using that sort key.
|
||||
* LDAPSortControl sortCtrl = new LDAPSortControl(sortOrder,true);
|
||||
*
|
||||
* // Create search constraints to use that control.
|
||||
* LDAPSearchConstraints cons = new LDAPSearchConstraints();
|
||||
* cons.setServerControls( sortCtrl );
|
||||
*
|
||||
* // Send the search request.
|
||||
* LDAPSearchResults res = ld.search( "o=Airius.com",
|
||||
* LDAPv3.SCOPE_SUB, "(cn=Barbara*)", null, false, cons );
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* </PRE>
|
||||
*
|
||||
* The LDAP server sends back a sort response control to indicate
|
||||
* the result of the sorting operation. (The OID for this control
|
||||
* is 1.2.840.113556.1.4.474.)
|
||||
* <P>
|
||||
*
|
||||
* This control contains:
|
||||
* <P>
|
||||
*
|
||||
* <UL>
|
||||
* <LI>the result code from the sorting operation
|
||||
* <LI>optionally, the first attribute type in the sort key list
|
||||
* that resulted in an error (for example, if the attribute does
|
||||
* not exist)
|
||||
* </UL>
|
||||
* <P>
|
||||
*
|
||||
* To parse this control, use the <CODE>parseResponse</CODE> method.
|
||||
* <P>
|
||||
*
|
||||
* The following table lists what kinds of results to expect from the
|
||||
* LDAP server under different situations:
|
||||
* <P>
|
||||
*
|
||||
* <TABLE BORDER=1 COLS=4>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TH>Does the Server Support the Sorting Control?</TH>
|
||||
* <TH>Is the Sorting Control Marked As Critical?</TH>
|
||||
* <TH>Other Conditions</TH>
|
||||
* <TH>Results from LDAP Server</TH>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD ROWSPAN=2>
|
||||
* No
|
||||
* </TD>
|
||||
* <TD>
|
||||
* Yes
|
||||
* </TD>
|
||||
* <TD>
|
||||
* None
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server does not send back any entries.
|
||||
* <LI>An LDAPException.UNAVAILABLE_CRITICAL_EXTENSION
|
||||
* exception is thrown.
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD>
|
||||
* No
|
||||
* </TD>
|
||||
* <TD>
|
||||
* None
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server ignores the sorting control and
|
||||
* returns the entries unsorted.
|
||||
* </UL>
|
||||
* <P>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD ROWSPAN=4>
|
||||
* Yes
|
||||
* </TD>
|
||||
* <TD>
|
||||
* Yes
|
||||
* </TD>
|
||||
* <TD ROWSPAN=2>
|
||||
* The server cannot sort the results using the specified
|
||||
* sort key list.
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server does not send back any entries.
|
||||
* <LI>An LDAPException.UNAVAILABLE_CRITICAL_EXTENSION
|
||||
* exception is thrown.
|
||||
* <LI>The server sends back the sorting response control, which
|
||||
* specifies the result code of the sort attempt and (optionally)
|
||||
* the attribute type that caused the error.
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD>
|
||||
* No
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server returns the entries unsorted.
|
||||
* <LI>The server sends back the sorting response control, which
|
||||
* specifies the result code of the sort attempt and (optionally)
|
||||
* the attribute type that caused the error.
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD ROWSPAN=2>
|
||||
* N/A (could either be marked as critical or not)
|
||||
* </TD>
|
||||
* <TD>
|
||||
* The server successfully sorted the entries.
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server sends back the sorted entries.
|
||||
* <LI>The server sends back the sorting response control, which
|
||||
* specifies the result code of the sort attempt
|
||||
* (LDAPException.SUCCESS).
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD>
|
||||
* The search itself failed (for any reason).
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server sends back a result code for the search
|
||||
* operation.
|
||||
* <LI>The server does not send back the sorting response control.
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* </TABLE>
|
||||
* <P>
|
||||
* @see com.netscape.jndi.ldap.LdapSortKey
|
||||
* @see com.netscape.jndi.ldap.LdapSearchConstraints
|
||||
* @see com.netscape.jndi.ldap.LdapSearchConstraints#setServerControls(LDAPControl)
|
||||
*/
|
||||
public class LdapSortControl extends LDAPSortControl implements Control{
|
||||
/**
|
||||
* Constructs an <CODE>LDAPSortControl</CODE> object with a single
|
||||
* sorting key.
|
||||
* @param key A single attribute to sort by.
|
||||
* @param critical <CODE>true</CODE> if the LDAP operation should be
|
||||
* discarded when the server does not support this control (in other
|
||||
* words, this control is critical to the LDAP operation).
|
||||
* @see com.netscape.jndi.ldap.LdapSortKey
|
||||
*/
|
||||
public LdapSortControl(LdapSortKey key,
|
||||
boolean critical) {
|
||||
super (key, critical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <CODE>LDAPSortControl</CODE> object with an array of
|
||||
* sorting keys.
|
||||
* @param keys The attributes to sort by.
|
||||
* @param critical <CODE>true</CODE> if the LDAP operation should be
|
||||
* discarded when the server does not support this control (in other
|
||||
* words, this control is critical to the LDAP operation).
|
||||
* @see com.netscape.jndi.ldap.LdapSortKey
|
||||
*/
|
||||
public LdapSortControl(LdapSortKey[] keys,
|
||||
boolean critical) {
|
||||
super(keys, critical);
|
||||
}
|
||||
|
||||
|
||||
static LdapSortKey[] toSortKey(String[] keysIn) {
|
||||
LdapSortKey[] keysOut = new LdapSortKey[keysIn.length];
|
||||
for (int i=0; i < keysIn.length; i++) {
|
||||
keysOut[i] = new LdapSortKey(keysIn[i]);
|
||||
}
|
||||
return keysOut;
|
||||
}
|
||||
|
||||
public LdapSortControl(String[] keys,
|
||||
boolean critical) {
|
||||
super(toSortKey(keys), critical);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements Control interface
|
||||
*/
|
||||
public byte[] getEncodedValue() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.controls;
|
||||
|
||||
import netscape.ldap.LDAPSortKey;
|
||||
|
||||
/**
|
||||
* Represents sorting instructions for a particular attribute.
|
||||
*
|
||||
*/
|
||||
public class LdapSortKey extends LDAPSortKey{
|
||||
|
||||
/**
|
||||
* Constructs a new <CODE>LdapSortKey</CODE> object that will
|
||||
* sort based on the specified instructions.
|
||||
* @param keyDescription A single attribute specification to sort by.
|
||||
* If preceded by a hyphen ("-"), the attribute is sorted in reverse order.
|
||||
* You can also specify the object ID (OID) of a matching rule after
|
||||
* a colon (":"). For example:
|
||||
* <P>
|
||||
* <UL>
|
||||
* <LI><CODE>"cn"</CODE> (sort by the <CODE>cn</CODE> attribute) <P>
|
||||
* <LI><CODE>"-cn"</CODE> (sort by the <CODE>cn</CODE> attribute in
|
||||
* reverse order) <P>
|
||||
* <LI><CODE>"-cn:1.2.3.4"</CODE> (sort by the <CODE>cn</CODE>
|
||||
* attribute in reverse order and use the matching rule identified
|
||||
* by the OID 1.2.3.4) <P>
|
||||
*</UL>
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPagedControl
|
||||
* @see com.netscape.jndi.ldap.controls.LdapSortControl
|
||||
* @see com.netscape.jndi.ldap.controls.LdapVirtualListControl
|
||||
*/
|
||||
public LdapSortKey( String keyDescription ) {
|
||||
super(keyDescription);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <CODE>LdapSortKey</CODE> object that will
|
||||
* sort based on the specified attribute and sort order.
|
||||
* @param key A single attribute to sort by. For example:
|
||||
* <P>
|
||||
* <UL>
|
||||
* <LI><CODE>"cn"</CODE> (sort by the <CODE>cn</CODE> attribute)
|
||||
* <LI><CODE>"givenname"</CODE> (sort by the <CODE>givenname</CODE>
|
||||
* attribute)
|
||||
* </UL>
|
||||
* @param reverse If <CODE>true</CODE>, the sorting is done in
|
||||
* descending order.
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPagedControl
|
||||
* @see com.netscape.jndi.ldap.controls.LdapSortControl
|
||||
* @see com.netscape.jndi.ldap.controls.LdapVirtualListControl
|
||||
*/
|
||||
public LdapSortKey( String key,
|
||||
boolean reverse) {
|
||||
super(key,reverse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <CODE>LdapSortKey</CODE> object that will
|
||||
* sort based on the specified attribute, sort order, and matching
|
||||
* rule.
|
||||
* @param key A single attribute to sort by. For example:
|
||||
* <P>
|
||||
* <UL>
|
||||
* <LI><CODE>"cn"</CODE> (sort by the <CODE>cn</CODE> attribute)
|
||||
* <LI><CODE>"givenname"</CODE> (sort by the <CODE>givenname</CODE>
|
||||
* attribute)
|
||||
* </UL>
|
||||
* @param reverse If <CODE>true</CODE>, the sorting is done in
|
||||
* descending order.
|
||||
* @param matchRule Object ID (OID) of the matching rule for
|
||||
* the attribute (for example, <CODE>1.2.3.4</CODE>).
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPagedControl
|
||||
* @see com.netscape.jndi.ldap.controls.LdapSortControl
|
||||
* @see com.netscape.jndi.ldap.controls.LdapVirtualListControl
|
||||
*/
|
||||
public LdapSortKey( String key,
|
||||
boolean reverse,
|
||||
String matchRule) {
|
||||
super(key, reverse, matchRule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attribute to sort by.
|
||||
* @return A single attribute to sort by.
|
||||
*/
|
||||
public String getKey() {
|
||||
return super.getKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <CODE>true</CODE> if sorting is to be done in descending order.
|
||||
* @return <CODE>true</CODE> if sorting is to be done in descending order.
|
||||
*/
|
||||
public boolean getReverse() {
|
||||
return super.getReverse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object ID (OID) of the matching rule used for sorting.
|
||||
* If no matching rule is specified, <CODE>null</CODE> is returned.
|
||||
* @return The object ID (OID) of the matching rule, or <CODE>null</CODE>
|
||||
* if the sorting instructions specify no matching rule.
|
||||
*/
|
||||
public String getMatchRule() {
|
||||
return super.getMatchRule();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.controls;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.ldap.Control;
|
||||
import netscape.ldap.LDAPControl;
|
||||
import netscape.ldap.LDAPException;
|
||||
import netscape.ldap.controls.*;
|
||||
import com.netscape.jndi.ldap.common.ExceptionMapper;
|
||||
|
||||
/**
|
||||
* The LDAP server sends back a sort response control to indicate
|
||||
* the result of the sorting operation. (The OID for this control
|
||||
* is 1.2.840.113556.1.4.474.)
|
||||
* <P>
|
||||
*
|
||||
* This control contains:
|
||||
* <P>
|
||||
*
|
||||
* <UL>
|
||||
* <LI>the result code from the sorting operation
|
||||
* <LI>optionally, the first attribute type in the sort key list
|
||||
* that resulted in an error (for example, if the attribute does
|
||||
* not exist)
|
||||
* </UL>
|
||||
* <P>
|
||||
*
|
||||
* To parse this control, use the <CODE>parseResponse</CODE> method.
|
||||
* <P>
|
||||
*
|
||||
* The following table lists what kinds of results to expect from the
|
||||
* LDAP server under different situations:
|
||||
* <P>
|
||||
*
|
||||
* <TABLE BORDER=1 COLS=4>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TH>Does the Server Support the Sorting Control?</TH>
|
||||
* <TH>Is the Sorting Control Marked As Critical?</TH>
|
||||
* <TH>Other Conditions</TH>
|
||||
* <TH>Results from LDAP Server</TH>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD ROWSPAN=2>
|
||||
* No
|
||||
* </TD>
|
||||
* <TD>
|
||||
* Yes
|
||||
* </TD>
|
||||
* <TD>
|
||||
* None
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server does not send back any entries.
|
||||
* <LI>An LDAPException.UNAVAILABLE_CRITICAL_EXTENSION
|
||||
* exception is thrown.
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD>
|
||||
* No
|
||||
* </TD>
|
||||
* <TD>
|
||||
* None
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server ignores the sorting control and
|
||||
* returns the entries unsorted.
|
||||
* </UL>
|
||||
* <P>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD ROWSPAN=4>
|
||||
* Yes
|
||||
* </TD>
|
||||
* <TD>
|
||||
* Yes
|
||||
* </TD>
|
||||
* <TD ROWSPAN=2>
|
||||
* The server cannot sort the results using the specified
|
||||
* sort key list.
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server does not send back any entries.
|
||||
* <LI>An LDAPException.UNAVAILABLE_CRITICAL_EXTENSION
|
||||
* exception is thrown.
|
||||
* <LI>The server sends back the sorting response control, which
|
||||
* specifies the result code of the sort attempt and (optionally)
|
||||
* the attribute type that caused the error.
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD>
|
||||
* No
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server returns the entries unsorted.
|
||||
* <LI>The server sends back the sorting response control, which
|
||||
* specifies the result code of the sort attempt and (optionally)
|
||||
* the attribute type that caused the error.
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD ROWSPAN=2>
|
||||
* N/A (could either be marked as critical or not)
|
||||
* </TD>
|
||||
* <TD>
|
||||
* The server successfully sorted the entries.
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server sends back the sorted entries.
|
||||
* <LI>The server sends back the sorting response control, which
|
||||
* specifies the result code of the sort attempt
|
||||
* (LDAPException.SUCCESS).
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* <TR VALIGN=BASELINE>
|
||||
* <TD>
|
||||
* The search itself failed (for any reason).
|
||||
* </TD>
|
||||
* <TD>
|
||||
* <UL>
|
||||
* <LI>The server sends back a result code for the search
|
||||
* operation.
|
||||
* <LI>The server does not send back the sorting response control.
|
||||
* </UL>
|
||||
* </TD>
|
||||
* </TR>
|
||||
* </TABLE>
|
||||
* <P>
|
||||
* @see com.netscape.jndi.ldap.LdapSortKey
|
||||
* @see com.netscape.jndi.ldap.LdapSearchConstraints
|
||||
* @see com.netscape.jndi.ldap.LdapSearchConstraints#setServerControls(LDAPControl)
|
||||
*/
|
||||
public class LdapSortResponseControl extends LDAPControl implements Control {
|
||||
|
||||
String m_failedAttribute;
|
||||
int m_resultCode;
|
||||
/**
|
||||
* Constructs a new <CODE>LdapEntryChangeControl</CODE> object.
|
||||
* This constructor is used by the NetscapeControlFactory
|
||||
*
|
||||
* @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl
|
||||
*/
|
||||
LdapSortResponseControl(boolean critical, byte[] value) {
|
||||
super(LDAPSortControl.SORTRESPONSE, critical, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the first attribute type from the sort key list that
|
||||
* resulted in an error
|
||||
* This method is used by the NetscapeControlFactory
|
||||
*/
|
||||
void setFailedAttribute(String attr) {
|
||||
m_failedAttribute = attr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sort result code
|
||||
* This method is used by the NetscapeControlFactory
|
||||
*/
|
||||
void setResultCode(int code) {
|
||||
m_resultCode = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first attribute type from the sort key list that
|
||||
* resulted in an error
|
||||
*/
|
||||
public String getFailedAttribute() {
|
||||
return m_failedAttribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sort result code
|
||||
*/
|
||||
public int getResultCode() {
|
||||
return m_resultCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return corresponding NamingException for the sort error code
|
||||
*/
|
||||
public NamingException getSortException() {
|
||||
if (m_resultCode == 0) { // success
|
||||
return null;
|
||||
}
|
||||
return ExceptionMapper.getNamingException(
|
||||
new LDAPException("Server Sort Failed", m_resultCode));
|
||||
}
|
||||
/**
|
||||
* Implements Control interface
|
||||
*/
|
||||
public byte[] getEncodedValue() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
/* -*- 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) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
package com.netscape.jndi.ldap.controls;
|
||||
|
||||
import javax.naming.ldap.Control;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
/**
|
||||
* Represents control data for returning paged results from a search.
|
||||
*
|
||||
* <PRE>
|
||||
* VirtualListViewRequest ::= SEQUENCE {
|
||||
* beforeCount INTEGER,
|
||||
* afterCount INTEGER,
|
||||
* CHOICE {
|
||||
* byIndex [0] SEQUENCE {
|
||||
* index INTEGER,
|
||||
* contentCount INTEGER }
|
||||
* byFilter [1] jumpTo Substring }
|
||||
* </PRE>
|
||||
*
|
||||
*/
|
||||
|
||||
public class LdapVirtualListControl extends LDAPVirtualListControl implements Control {
|
||||
|
||||
/**
|
||||
* Constructs a new <CODE>LDAPVirtualListControl</CODE> object. Use this
|
||||
* constructor on an initial search operation, specifying the first
|
||||
* entry to be matched, or the initial part of it.
|
||||
* @param jumpTo An LDAP search expression defining the result set.
|
||||
* @param beforeCount The number of results before the top/center to
|
||||
* return per page.
|
||||
* @param afterCount The number of results after the top/center to
|
||||
* return per page.
|
||||
*/
|
||||
public LdapVirtualListControl( String jumpTo, int beforeCount,
|
||||
int afterCount ) {
|
||||
super( jumpTo, beforeCount, afterCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <CODE>LDAPVirtualListControl</CODE> object. Use this
|
||||
* constructor on a subsquent search operation, after we know the
|
||||
* size of the virtual list, to fetch a subset.
|
||||
* @param startIndex The index into the virtual list of an entry to
|
||||
* return.
|
||||
* @param beforeCount The number of results before the top/center to
|
||||
* return per page.
|
||||
* @param afterCount The number of results after the top/center to
|
||||
* return per page.
|
||||
*/
|
||||
public LdapVirtualListControl( int startIndex, int beforeCount,
|
||||
int afterCount, int contentCount ) {
|
||||
super( startIndex, beforeCount, afterCount, contentCount );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the starting index, and the number of entries before and after
|
||||
* to return. Apply this method to a control returned from a previous
|
||||
* search, to specify what result range to return on the next search.
|
||||
* @param startIndex The index into the virtual list of an entry to
|
||||
* return.
|
||||
* @param beforeCount The number of results before startIndex to
|
||||
* return per page.
|
||||
* @param afterCount The number of results after startIndex to
|
||||
* return per page.
|
||||
*/
|
||||
public void setRange( int startIndex, int beforeCount, int afterCount ) {
|
||||
super.setRange(startIndex, beforeCount, afterCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the search expression, and the number of entries before and after
|
||||
* to return.
|
||||
* @param jumpTo An LDAP search expression defining the result set.
|
||||
* return.
|
||||
* @param beforeCount The number of results before startIndex to
|
||||
* return per page.
|
||||
* @param afterCount The number of results after startIndex to
|
||||
* return per page.
|
||||
*/
|
||||
public void setRange( String jumpTo, int beforeCount, int afterCount ) {
|
||||
super.setRange(jumpTo, beforeCount, afterCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the virtual result set.
|
||||
* @return The size of the virtual result set, or -1 if not known.
|
||||
*/
|
||||
public int getIndex() {
|
||||
return super.getIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the virtual result set.
|
||||
* @return The size of the virtual result set, or -1 if not known.
|
||||
*/
|
||||
public int getListSize() {
|
||||
return super.getListSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of the virtual result set.
|
||||
* @param listSize The virtual result set size.
|
||||
*/
|
||||
public void setListSize( int listSize ) {
|
||||
super.setListSize(listSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of results before the top/center to return per page.
|
||||
* @return The number of results before the top/center to return per page.
|
||||
*/
|
||||
public int getBeforeCount() {
|
||||
return super.getBeforeCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of results after the top/center to return per page.
|
||||
* @return The number of results after the top/center to return per page.
|
||||
*/
|
||||
public int getAfterCount() {
|
||||
return super.getAfterCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Control interface
|
||||
*/
|
||||
public byte[] getEncodedValue() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.controls;
|
||||
|
||||
import javax.naming.ldap.Control;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
|
||||
/**
|
||||
* Represents control data for returning paged results from a search.
|
||||
*
|
||||
*
|
||||
*<PRE>
|
||||
* VirtualListViewResponse ::= SEQUENCE {
|
||||
* firstPosition INTEGER,
|
||||
* contentCount INTEGER,
|
||||
* virtualListViewResult ENUMERATED {
|
||||
* success (0),
|
||||
* unwillingToPerform (53),
|
||||
* insufficientAccessRights (50),
|
||||
* operationsError (1),
|
||||
* busy (51),
|
||||
* timeLimitExceeded (3),
|
||||
* adminLimitExceeded (11),
|
||||
* sortControlMissing (60),
|
||||
* indexRangeError (?),
|
||||
* }
|
||||
* }
|
||||
*</PRE>
|
||||
*/
|
||||
|
||||
public class LdapVirtualListResponseControl extends LDAPVirtualListResponse implements Control{
|
||||
|
||||
/**
|
||||
* Constructs a new <CODE>LDAPVirtualListResponse</CODE> object.
|
||||
* @param value A BER encoded byte array.
|
||||
* This constructor is used by the NetscapeControlFactory
|
||||
*/
|
||||
LdapVirtualListResponseControl( byte[] value ) {
|
||||
// The superclass constractor parses the byte[] value
|
||||
// automatically. No need to call parseResponse
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the virtual result set.
|
||||
* @return The size of the virtual result set, or -1 if not known.
|
||||
*/
|
||||
public int getContentCount() {
|
||||
return super.getContentCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the first entry returned.
|
||||
* @return The index of the first entry returned.
|
||||
*/
|
||||
public int getFirstPosition() {
|
||||
return super.getFirstPosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the result code.
|
||||
* @return The result code.
|
||||
*/
|
||||
public int getResultCode() {
|
||||
return super.getResultCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Control interface
|
||||
*/
|
||||
public byte[] getEncodedValue() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.controls;
|
||||
|
||||
|
||||
/**
|
||||
* Factory for creating controls. Only controls send by the direcory server
|
||||
* are processed.
|
||||
*/
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.ldap.*;
|
||||
import netscape.ldap.LDAPControl;
|
||||
import netscape.ldap.controls.*;
|
||||
import com.netscape.jndi.ldap.common.ExceptionMapper;
|
||||
|
||||
public class NetscapeControlFactory extends ControlFactory {
|
||||
|
||||
// "1.2.840.113556.1.4.473" Sort Control (Request)
|
||||
final static String REQ_SORT = LDAPSortControl.SORTREQUEST;
|
||||
|
||||
// "1.2.840.113556.1.4.474" Sort Control (Response)
|
||||
final static String RSP_SORT = LDAPSortControl.SORTRESPONSE;
|
||||
|
||||
// "2.16.840.1.113730.3.4.2" ManageDSAIT Control
|
||||
final static String REQ_MANAGEDSAIT = LDAPControl.MANAGEDSAIT;
|
||||
|
||||
// "2.16.840.1.113730.3.4.3" PersistentSearch Control
|
||||
final static String REQ_PERSISTENTSEARCH = LDAPPersistSearchControl.PERSISTENTSEARCH;
|
||||
|
||||
// "2.16.840.1.113730.3.4.4" PasswordExpired Control
|
||||
final static String RSP_PWDEXPIRED = LDAPPasswordExpiredControl.EXPIRED;
|
||||
|
||||
// "2.16.840.1.113730.3.4.5" PasswordExpiring Control
|
||||
final static String RSP_PWDEXPIRING = LDAPPasswordExpiringControl.EXPIRING;
|
||||
|
||||
// "2.16.840.1.113730.3.4.7" EntryChanged Controle
|
||||
final static String RSP_ENTRYCHANGED = LDAPEntryChangeControl.ENTRYCHANGED;
|
||||
|
||||
// "2.16.840.1.113730.3.4.9" Virtual List (Request)
|
||||
final static String REQ_VIRTUALLIST = LDAPVirtualListControl.VIRTUALLIST;
|
||||
|
||||
// "2.16.840.1.113730.3.4.10" Virtual List (Response)
|
||||
final static String RSP_VIRTUALLIST = LDAPVirtualListResponse.VIRTUALLISTRESPONSE;
|
||||
|
||||
// "2.16.840.1.113730.3.4.12" Proxed Authentication
|
||||
final static String REQ_PROXIEDAUTH = LDAPProxiedAuthControl.PROXIEDAUTHREQUEST;
|
||||
|
||||
|
||||
/**
|
||||
* Implements abstract getControlInstance() from ConrolFactory
|
||||
*/
|
||||
public Control getControlInstance(Control ctrl) throws NamingException {
|
||||
if (ctrl == null) {
|
||||
return null;
|
||||
}
|
||||
LDAPControl rawCtrl = new LDAPControl(
|
||||
ctrl.getID(), ctrl.isCritical(), ctrl.getEncodedValue());
|
||||
return getControlInstance(rawCtrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create control using parseResponse() methods in ldapjdk controls
|
||||
*/
|
||||
public static Control getControlInstance(LDAPControl rawCtrl) throws NamingException {
|
||||
if (rawCtrl == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String ctrlID = rawCtrl.getID();
|
||||
|
||||
// Entry changed control is parsed by LDAPPersistSearchControl
|
||||
if (ctrlID.equals(RSP_ENTRYCHANGED)) {
|
||||
// First get ldapjdk object
|
||||
LDAPEntryChangeControl ldapjdkCtrl =
|
||||
LDAPPersistSearchControl.parseResponse(new LDAPControl[] {rawCtrl});
|
||||
// then map it to a jndi object
|
||||
if (ldapjdkCtrl != null) {
|
||||
LdapEntryChangeControl ctrl = new LdapEntryChangeControl(
|
||||
rawCtrl.isCritical(), rawCtrl.getValue());
|
||||
ctrl.setChangeNumber(ldapjdkCtrl.getChangeNumber());
|
||||
ctrl.setChangeType(ldapjdkCtrl.getChangeType());
|
||||
ctrl.setPreviousDN(ldapjdkCtrl.getPreviousDN());
|
||||
return ctrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Password Expired control
|
||||
else if(ctrlID.equals(RSP_PWDEXPIRED)) {
|
||||
LdapPasswordExpiredControl ctrl = new LdapPasswordExpiredControl(
|
||||
rawCtrl.isCritical(), rawCtrl.getValue());
|
||||
}
|
||||
|
||||
// Password Expiring control
|
||||
else if(ctrlID.equals(RSP_PWDEXPIRING)) {
|
||||
LdapPasswordExpiringControl ctrl = new LdapPasswordExpiringControl(
|
||||
rawCtrl.isCritical(), rawCtrl.getValue());
|
||||
}
|
||||
|
||||
// Sort Response control
|
||||
else if(ctrlID.equals(RSP_SORT)) {
|
||||
// First parse the control
|
||||
int[] resultCodes = new int[1];
|
||||
String failedAttr = LDAPSortControl.parseResponse(
|
||||
new LDAPControl[] {rawCtrl}, resultCodes);
|
||||
|
||||
LdapSortResponseControl ctrl = new LdapSortResponseControl(
|
||||
rawCtrl.isCritical(), rawCtrl.getValue());
|
||||
ctrl.setResultCode(resultCodes[0]);
|
||||
ctrl.setFailedAttribute(failedAttr);
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
// Virtual List Response control
|
||||
else if(ctrlID.equals(RSP_VIRTUALLIST)) {
|
||||
return new LdapVirtualListResponseControl(rawCtrl.getValue());
|
||||
}
|
||||
|
||||
// No match try another ControlFactory
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw ExceptionMapper.getNamingException(ex);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SchemaAttribute extends SchemaElement {
|
||||
|
||||
LDAPAttributeSchema m_ldapAttribute;
|
||||
|
||||
// Attribute IDs that are exposed through Netscape LdapJDK
|
||||
private static String[] m_allAttrIds = {NUMERICOID, NAME, DESC, SYNTAX, SINGLEVALUE };
|
||||
|
||||
public SchemaAttribute(LDAPAttributeSchema ldapAttribute, SchemaManager schemaManager) {
|
||||
super(schemaManager);
|
||||
m_ldapAttribute = ldapAttribute;
|
||||
m_path = ATTRDEF + "/" + m_ldapAttribute.getName();
|
||||
}
|
||||
|
||||
public SchemaAttribute(Attributes attrs, SchemaManager schemaManager) throws NamingException {
|
||||
super(schemaManager);
|
||||
m_ldapAttribute = parseDefAttributes(attrs);
|
||||
m_path = ATTRDEF + "/" + m_ldapAttribute.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Definition Attributes for a LDAP attribute
|
||||
*/
|
||||
static LDAPAttributeSchema parseDefAttributes(Attributes attrs) throws NamingException {
|
||||
String name="", oid="", desc="";
|
||||
int syntax=-1;
|
||||
boolean singleValued = false;
|
||||
|
||||
for (Enumeration attrEnum = attrs.getAll(); attrEnum.hasMoreElements(); ) {
|
||||
Attribute attr = (Attribute) attrEnum.nextElement();
|
||||
String attrName = attr.getID();
|
||||
if (attrName.equals(NAME)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
name = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(NUMERICOID)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
oid = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(SYNTAX)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
String syntaxString = (String)valEnum.nextElement();
|
||||
syntax = syntaxStringToInt(syntaxString);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(DESC)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
desc = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(SINGLEVALUE)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
String flag = (String)valEnum.nextElement();
|
||||
if (flag.equals("true")) {
|
||||
singleValued = true;
|
||||
}
|
||||
else if (flag.equals("false")) {
|
||||
singleValued = false;
|
||||
}
|
||||
else {
|
||||
throw new InvalidAttributeValueException(attrName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(OBSOLETE) || attrName.equals(SUP) || attrName.equals(USAGE) ||
|
||||
attrName.equals(EQUALITY) || attrName.equals(ORDERING) ||
|
||||
attrName.equals(COLLECTIVE) || attrName.equals(NOUSERMOD)) {
|
||||
; //ignore
|
||||
}
|
||||
else {
|
||||
throw new NamingException("Invalid schema attribute type for attribute definition " + attrName);
|
||||
}
|
||||
}
|
||||
|
||||
if (name.length() == 0 || oid.length() == 0 || syntax == -1) {
|
||||
throw new NamingException("Incomplete schema attribute definition");
|
||||
}
|
||||
|
||||
return new LDAPAttributeSchema(name, oid, desc, syntax, singleValued);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exctract specified attributes from the ldapObjectClass
|
||||
*/
|
||||
Attributes extractAttributeIds(String[] attrIds) throws NamingException{
|
||||
Attributes attrs = new BasicAttributes();
|
||||
for (int i = 0; i < attrIds.length; i++) {
|
||||
if (attrIds[i].equals(NUMERICOID)) {
|
||||
attrs.put(new BasicAttribute(NUMERICOID, m_ldapAttribute.getOID()));
|
||||
}
|
||||
else if (attrIds[i].equals(NAME)) {
|
||||
attrs.put(new BasicAttribute(NAME, m_ldapAttribute.getName()));
|
||||
}
|
||||
else if (attrIds[i].equals(DESC)) {
|
||||
attrs.put(new BasicAttribute(DESC, m_ldapAttribute.getDescription()));
|
||||
}
|
||||
else if (attrIds[i].equals(SYNTAX)) {
|
||||
attrs.put(new BasicAttribute(SYNTAX, syntaxIntToString(m_ldapAttribute.getSyntax())));
|
||||
}
|
||||
else if (attrIds[i].equals(SINGLEVALUE)) {
|
||||
attrs.put(new BasicAttribute(SINGLEVALUE,
|
||||
(m_ldapAttribute.isSingleValued() ? "true" : "false")));
|
||||
}
|
||||
else {
|
||||
// ignore other attrIds as not supported by Netscape LdapJDK APIs
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DirContext Attribute Operations
|
||||
*/
|
||||
|
||||
public Attributes getAttributes(String name) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
return extractAttributeIds(m_allAttrIds);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
return extractAttributeIds(attrIds);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name) throws NamingException {
|
||||
return getAttributes(name.toString());
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
|
||||
return getAttributes(name.toString(), attrIds);
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
Attributes modAttrs = extractAttributeIds(m_allAttrIds);
|
||||
modifySchemaElementAttrs(modAttrs, mod_op, attrs);
|
||||
LDAPAttributeSchema modLdapAttribute = parseDefAttributes(modAttrs);
|
||||
m_schemaMgr.modifyAttribute(m_ldapAttribute, modLdapAttribute);
|
||||
m_ldapAttribute = modLdapAttribute;
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
Attributes modAttrs = extractAttributeIds(m_allAttrIds);
|
||||
modifySchemaElementAttrs(modAttrs, mods);
|
||||
LDAPAttributeSchema modLdapAttribute = parseDefAttributes(modAttrs);
|
||||
m_schemaMgr.modifyAttribute(m_ldapAttribute, modLdapAttribute);
|
||||
m_ldapAttribute = modLdapAttribute;
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
|
||||
modifyAttributes(name.toString(), mod_op, attrs);
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
|
||||
modifyAttributes(name.toString(), mods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search operations are not implemented because of complexity. Ir will require
|
||||
* to implement the full LDAP search filter sematics in the client. (The search
|
||||
* filter sematics is implemented by the Directory server).
|
||||
*/
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SchemaAttributeContainer extends SchemaElementContainer {
|
||||
|
||||
public SchemaAttributeContainer(SchemaManager schemaMgr) throws NamingException{
|
||||
super(schemaMgr, ATTRDEF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ldap entry operations
|
||||
*/
|
||||
|
||||
public DirContext createSchemaElement(String name, Attributes attrs) throws NamingException {
|
||||
if (name.length() == 0) {
|
||||
throw new NamingException("Empty name for schema objectclass");
|
||||
}
|
||||
LDAPAttributeSchema attr = SchemaAttribute.parseDefAttributes(attrs);
|
||||
m_schemaMgr.createAttribute(attr);
|
||||
return new SchemaAttribute(attr, m_schemaMgr);
|
||||
|
||||
}
|
||||
|
||||
public void removeSchemaElement(String name) throws NamingException {
|
||||
if (name.length() == 0) {
|
||||
throw new NamingException("Can not delete schema object container");
|
||||
}
|
||||
m_schemaMgr.removeAttribute(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* List Operations
|
||||
*/
|
||||
|
||||
public NamingEnumeration getNameList(String name) throws NamingException {
|
||||
SchemaDirContext schemaObj = (SchemaDirContext)lookup(name);
|
||||
if (schemaObj == this) {
|
||||
return new SchemaElementNameEnum(m_schemaMgr.getAttributeNames());
|
||||
}
|
||||
else {
|
||||
throw new NotContextException(name);
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration getBindingsList(String name) throws NamingException {
|
||||
SchemaDirContext schemaObj = (SchemaDirContext)lookup(name);
|
||||
if (schemaObj == this) {
|
||||
return new SchemaElementBindingEnum(m_schemaMgr.getAttributes(), m_schemaMgr);
|
||||
}
|
||||
else {
|
||||
throw new NotContextException(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup Operations
|
||||
*/
|
||||
|
||||
public Object lookupSchemaElement(String name) throws NamingException {
|
||||
if (name.length() == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// No caching; Always create a new object
|
||||
LDAPAttributeSchema attr = m_schemaMgr.getAttribute(name);
|
||||
if (attr == null) {
|
||||
throw new NameNotFoundException(name);
|
||||
}
|
||||
return new SchemaAttribute(attr, m_schemaMgr);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
import com.netscape.jndi.ldap.common.DirContextAdapter;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SchemaDirContext extends DirContextAdapter {
|
||||
|
||||
public static final String CLASSDEF = "ClassDefinition";
|
||||
public static final String ATTRDEF = "AttributeDefinition";
|
||||
public static final String MRULEDEF = "MatchingRule";
|
||||
|
||||
|
||||
String m_path;
|
||||
|
||||
public void close() throws NamingException {
|
||||
; //NOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Name operations
|
||||
*/
|
||||
|
||||
public String composeName(String name, String prefix) throws NamingException {
|
||||
return name + "," + prefix;
|
||||
}
|
||||
|
||||
public Name composeName(Name name, Name prefix) throws NamingException {
|
||||
String compoundName = composeName(name.toString(), prefix.toString());
|
||||
return SchemaNameParser.getParser().parse(compoundName);
|
||||
}
|
||||
|
||||
public String getNameInNamespace() throws NamingException {
|
||||
return new String(m_path);
|
||||
}
|
||||
|
||||
public NameParser getNameParser(String name) throws NamingException {
|
||||
return SchemaNameParser.getParser();
|
||||
}
|
||||
|
||||
public NameParser getNameParser(Name name) throws NamingException {
|
||||
return SchemaNameParser.getParser();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Naming Bind operations
|
||||
*/
|
||||
|
||||
public void bind(String name, Object obj) throws NamingException {
|
||||
if (obj instanceof DirContext) {
|
||||
createSubcontext(name, ((DirContext)obj).getAttributes(""));
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Can not bind this type of object");
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj) throws NamingException {
|
||||
bind(name.toString(), obj);
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj) throws NamingException {
|
||||
try {
|
||||
bind(name, obj);
|
||||
}
|
||||
catch (NameAlreadyBoundException ex) {
|
||||
unbind(name);
|
||||
bind(name, obj);
|
||||
}
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj) throws NamingException {
|
||||
rebind(name.toString(), obj);
|
||||
}
|
||||
|
||||
public void rename(String oldName, String newName) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rename(Name oldName, Name newName) throws NamingException {
|
||||
rename(oldName.toString(), newName.toString());
|
||||
}
|
||||
|
||||
public void unbind(String name) throws NamingException {
|
||||
// In ldap every entry is naming context
|
||||
destroySubcontext(name);
|
||||
}
|
||||
|
||||
public void unbind(Name name) throws NamingException {
|
||||
// In ldap every entry is naming context
|
||||
destroySubcontext(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty enumeration for list operations
|
||||
*/
|
||||
class EmptyNamingEnumeration implements NamingEnumeration {
|
||||
|
||||
public Object next() throws NamingException{
|
||||
throw new NoSuchElementException("EmptyNamingEnumeration");
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
throw new NoSuchElementException("EmptyNamingEnumeration");
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void close() {}
|
||||
}
|
||||
|
||||
static class SchemaObjectSubordinateNamePair {
|
||||
SchemaDirContext schemaObj;
|
||||
String subordinateName;
|
||||
|
||||
public SchemaObjectSubordinateNamePair(SchemaDirContext object, String subordinateName) {
|
||||
this.schemaObj = object;
|
||||
this.subordinateName = subordinateName;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer str = new StringBuffer("SchemaObjectSubordinateNamePair{obj:");
|
||||
str.append(((schemaObj == null) ? "null" : schemaObj.toString()));
|
||||
str.append(" name:");
|
||||
str.append(subordinateName);
|
||||
str.append("}");
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SchemaElement extends SchemaDirContext {
|
||||
|
||||
SchemaManager m_schemaMgr;
|
||||
|
||||
// Attributes used to define schema elements
|
||||
static final String NUMERICOID = "NUMERICOID";
|
||||
static final String NAME = "NAME";
|
||||
static final String DESC = "DESC";
|
||||
static final String SYNTAX = "SYNTAX";
|
||||
static final String SUP = "SUP";
|
||||
static final String MUST = "MUST";
|
||||
static final String MAY = "MAY";
|
||||
static final String SINGLEVALUE = "SINGLE-VALUE";
|
||||
|
||||
// These attribute definition properties are not supported by LdapJDK and DS
|
||||
// Accept them for the appropriate schema element, but ignore them
|
||||
static final String OBSOLETE = "OBSOLETE";
|
||||
static final String EQUALITY = "EQUALITY";
|
||||
static final String ORDERING = "ORDERING";
|
||||
static final String COLLECTIVE = "COLLECTIVE";
|
||||
static final String NOUSERMOD = "NO-USER-MODIFICATION";
|
||||
static final String USAGE = "USAGE";
|
||||
static final String ABSTRACT = "ABSTRACT";
|
||||
static final String STRUCTURAL = "STRUCTURAL";
|
||||
static final String AUXILIARY = "AUXILIARY";
|
||||
|
||||
|
||||
// Syntax string recognized by Netscape LdapJDK
|
||||
static final String cisString = "1.3.6.1.4.1.1466.115.121.1.15";
|
||||
static final String binaryString = "1.3.6.1.4.1.1466.115.121.1.5";
|
||||
static final String telephoneString = "1.3.6.1.4.1.1466.115.121.1.50";
|
||||
static final String cesString = "1.3.6.1.4.1.1466.115.121.1.26";
|
||||
static final String intString = "1.3.6.1.4.1.1466.115.121.1.27";
|
||||
static final String dnString = "1.3.6.1.4.1.1466.115.121.1.12";
|
||||
|
||||
SchemaElement(SchemaManager schemaMgr) {
|
||||
m_schemaMgr = schemaMgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a syntax oid string to a constant recognized by LdapJDK
|
||||
*/
|
||||
static int syntaxStringToInt(String syntax) throws NamingException{
|
||||
if (syntax.equals(cisString)) {
|
||||
return LDAPSchemaElement.cis;
|
||||
}
|
||||
else if (syntax.equals(cesString)) {
|
||||
return LDAPSchemaElement.ces;
|
||||
}
|
||||
else if (syntax.equals(telephoneString)) {
|
||||
return LDAPSchemaElement.telephone;
|
||||
}
|
||||
else if (syntax.equals(intString)) {
|
||||
return LDAPSchemaElement.integer;
|
||||
}
|
||||
else if (syntax.equals(dnString)) {
|
||||
return LDAPSchemaElement.dn;
|
||||
}
|
||||
else if (syntax.equals(binaryString)) {
|
||||
return LDAPSchemaElement.binary;
|
||||
}
|
||||
else {
|
||||
throw new InvalidAttributeValueException(syntax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a syntax identifier to a oid string
|
||||
*/
|
||||
static String syntaxIntToString(int syntax) throws NamingException{
|
||||
if (syntax == LDAPSchemaElement.cis) {
|
||||
return cisString;
|
||||
}
|
||||
else if (syntax == LDAPSchemaElement.ces) {
|
||||
return cesString;
|
||||
}
|
||||
else if (syntax == LDAPSchemaElement.telephone) {
|
||||
return telephoneString;
|
||||
}
|
||||
else if (syntax == LDAPSchemaElement.integer) {
|
||||
return intString;
|
||||
}
|
||||
else if (syntax == LDAPSchemaElement.dn) {
|
||||
return dnString;
|
||||
}
|
||||
else if (syntax == LDAPSchemaElement.binary) {
|
||||
return binaryString;
|
||||
}
|
||||
else {
|
||||
throw new InvalidAttributeValueException("Interanal error, unexpected syntax value " + syntax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string vector to an array
|
||||
*/
|
||||
static String[] vectorToStringAry(Vector v) {
|
||||
String[] ary = new String[v.size()];
|
||||
for(int i=0; i<v.size(); i++) {
|
||||
ary[i] = (String) v.elementAt(i);
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* List Operations
|
||||
*/
|
||||
|
||||
public NamingEnumeration list(String name) throws NamingException {
|
||||
return new EmptyNamingEnumeration();
|
||||
}
|
||||
|
||||
public NamingEnumeration list(Name name) throws NamingException {
|
||||
return new EmptyNamingEnumeration();
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(String name) throws NamingException {
|
||||
return new EmptyNamingEnumeration();
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(Name name) throws NamingException {
|
||||
return new EmptyNamingEnumeration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the current set of the schema element's attributes
|
||||
*/
|
||||
void modifySchemaElementAttrs (Attributes attrs, ModificationItem[] jndiMods) throws NamingException{
|
||||
LDAPModificationSet mods = new LDAPModificationSet();
|
||||
for (int i=0; i < jndiMods.length; i++) {
|
||||
int modop = jndiMods[i].getModificationOp();
|
||||
Attribute attr = jndiMods[i].getAttribute();
|
||||
Attributes modAttrs = new BasicAttributes(/*ignorecase=*/true);
|
||||
modAttrs.put(attr);
|
||||
modifySchemaElementAttrs(attrs, modop, modAttrs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the current set of the schema element's attributes
|
||||
*/
|
||||
void modifySchemaElementAttrs (Attributes attrs, int modop, Attributes modAttrs) throws NamingException{
|
||||
LDAPModificationSet mods = new LDAPModificationSet();
|
||||
for (NamingEnumeration attrEnum = modAttrs.getAll(); attrEnum.hasMore();) {
|
||||
Attribute attr = (Attribute)attrEnum.next();
|
||||
if (modop == DirContext.ADD_ATTRIBUTE) {
|
||||
Attribute curAttr = attrs.get(attr.getID());
|
||||
if (curAttr == null) {
|
||||
attrs.put(attr);
|
||||
}
|
||||
else {
|
||||
for (NamingEnumeration vals = attr.getAll(); vals.hasMore();) {
|
||||
curAttr.add(vals.nextElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (modop == DirContext.REPLACE_ATTRIBUTE) {
|
||||
attrs.put(attr);
|
||||
}
|
||||
else if (modop == DirContext.REMOVE_ATTRIBUTE) {
|
||||
Attribute curAttr = attrs.get(attr.getID());
|
||||
if (curAttr == null) {
|
||||
throw new NoSuchAttributeException(attr.getID());
|
||||
}
|
||||
else if (attr.size() == 0) { // remove the attr
|
||||
attrs.remove(attr.getID());
|
||||
}
|
||||
else {
|
||||
for (NamingEnumeration vals = attr.getAll(); vals.hasMore();) {
|
||||
String val = (String) vals.nextElement();
|
||||
curAttr.remove(val);
|
||||
// Schema definition Values are case insensitive
|
||||
curAttr.remove(val.toLowerCase());
|
||||
}
|
||||
if (curAttr.size() == 0) { // remove attr if no values left
|
||||
attrs.remove(attr.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Illegal Attribute Modification Operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class SchemaElementBindingEnum implements NamingEnumeration {
|
||||
|
||||
/**
|
||||
* Enumeration of schema name-object bindings packaged into Binding object.
|
||||
*/
|
||||
Enumeration m_schemaElementEnum;
|
||||
|
||||
SchemaManager m_schemaMgr;
|
||||
|
||||
static final String _className = "javax.naming.directory.DirContext"; // for class name is bindings
|
||||
|
||||
public SchemaElementBindingEnum(Enumeration schemaElementEnum, SchemaManager schemaMgr) {
|
||||
m_schemaElementEnum = schemaElementEnum;
|
||||
m_schemaMgr = schemaMgr;
|
||||
}
|
||||
|
||||
public Object next() throws NamingException{
|
||||
return nextElement();
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
DirContext obj = null;
|
||||
LDAPSchemaElement schemaElement = (LDAPSchemaElement) m_schemaElementEnum.nextElement();
|
||||
if (schemaElement instanceof LDAPObjectClassSchema) {
|
||||
obj = new SchemaObjectClass((LDAPObjectClassSchema) schemaElement, m_schemaMgr);
|
||||
}
|
||||
else if (schemaElement instanceof LDAPAttributeSchema) {
|
||||
obj = new SchemaAttribute((LDAPAttributeSchema) schemaElement, m_schemaMgr);
|
||||
}
|
||||
else if (schemaElement instanceof LDAPMatchingRuleSchema) {
|
||||
obj = new SchemaMatchingRule((LDAPMatchingRuleSchema) schemaElement, m_schemaMgr);
|
||||
}
|
||||
return new Binding(schemaElement.getName(), _className, obj, /*isRelative=*/true);
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException{
|
||||
return m_schemaElementEnum.hasMoreElements();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return m_schemaElementEnum.hasMoreElements();
|
||||
}
|
||||
|
||||
public void close() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class SchemaElementContainer extends SchemaDirContext {
|
||||
|
||||
SchemaManager m_schemaMgr;
|
||||
|
||||
public SchemaElementContainer(SchemaManager schemaMgr, String path) throws NamingException{
|
||||
m_schemaMgr = schemaMgr;
|
||||
m_path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SchemaElement. Called by craeteSubcontext
|
||||
*/
|
||||
abstract DirContext createSchemaElement(String name, Attributes attrs) throws NamingException;
|
||||
|
||||
/**
|
||||
* Delete a new SchemaElement. Called by destroySubcontext
|
||||
*/
|
||||
abstract void removeSchemaElement(String name) throws NamingException;
|
||||
|
||||
/**
|
||||
* Return a list of names for subordinate SchemaElement. Called by list()
|
||||
*/
|
||||
abstract NamingEnumeration getNameList(String name) throws NamingException;
|
||||
|
||||
/**
|
||||
* Return a list of bindings for subordinate SchemaElement. Called by
|
||||
* listBindings()
|
||||
*/
|
||||
abstract NamingEnumeration getBindingsList(String name) throws NamingException;
|
||||
|
||||
/**
|
||||
* Get a SchemaElement by name
|
||||
*/
|
||||
abstract Object lookupSchemaElement(String name) throws NamingException;
|
||||
|
||||
|
||||
/**
|
||||
* Attribute Operations
|
||||
*/
|
||||
public Attributes getAttributes(String name) throws NamingException {
|
||||
|
||||
SchemaDirContext schemaElement = (SchemaDirContext)lookup(name);
|
||||
if (schemaElement == this) {
|
||||
throw new OperationNotSupportedException("No Attributes for " + m_path);
|
||||
}
|
||||
else {
|
||||
return schemaElement.getAttributes("");
|
||||
}
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
|
||||
SchemaDirContext schemaElement = (SchemaDirContext)lookup(name);
|
||||
if (schemaElement == this) {
|
||||
throw new OperationNotSupportedException("No Attributes for " + m_path);
|
||||
}
|
||||
else {
|
||||
return schemaElement.getAttributes("", attrIds);
|
||||
}
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name) throws NamingException {
|
||||
return getAttributes(name.toString());
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
|
||||
return getAttributes(name.toString(), attrIds);
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
|
||||
SchemaDirContext schemaElement = (SchemaDirContext)lookup(name);
|
||||
if (schemaElement == this) {
|
||||
throw new OperationNotSupportedException("No Attributes for " + m_path);
|
||||
}
|
||||
else {
|
||||
schemaElement.modifyAttributes("", mod_op, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
|
||||
SchemaDirContext schemaElement = (SchemaDirContext)lookup(name);
|
||||
if (schemaElement == this) {
|
||||
throw new OperationNotSupportedException("No Attributes for " + m_path);
|
||||
}
|
||||
else {
|
||||
schemaElement.modifyAttributes("", mods);
|
||||
}
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
|
||||
modifyAttributes(name.toString(), mod_op, attrs);
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
|
||||
modifyAttributes(name.toString(), mods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ldap entry operations
|
||||
*/
|
||||
|
||||
public Context createSubcontext(String name) throws NamingException {
|
||||
// Directory entry must have attributes
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Context createSubcontext(Name name) throws NamingException {
|
||||
// Directory entry must have attributes
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(String name, Attributes attrs) throws NamingException {
|
||||
return createSchemaElement(name, attrs);
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException {
|
||||
return createSubcontext(name.toString(), attrs);
|
||||
}
|
||||
|
||||
public void destroySubcontext(String name) throws NamingException {
|
||||
removeSchemaElement(name);
|
||||
}
|
||||
|
||||
public void destroySubcontext(Name name) throws NamingException {
|
||||
destroySubcontext(name.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Naming Bind operations
|
||||
*/
|
||||
|
||||
public void bind(String name, Object obj) throws NamingException {
|
||||
if (obj instanceof DirContext) {
|
||||
createSubcontext(name, ((DirContext)obj).getAttributes(""));
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Can not bind this type of object");
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj) throws NamingException {
|
||||
bind(name.toString(), obj);
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rename(String oldName, String newName) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rename(Name oldName, Name newName) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void unbind(String name) throws NamingException {
|
||||
destroySubcontext(name);
|
||||
}
|
||||
|
||||
public void unbind(Name name) throws NamingException {
|
||||
destroySubcontext(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* List Operations
|
||||
*/
|
||||
|
||||
public NamingEnumeration list(String name) throws NamingException {
|
||||
return getNameList(name);
|
||||
}
|
||||
|
||||
public NamingEnumeration list(Name name) throws NamingException {
|
||||
return list(name.toString());
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(String name) throws NamingException {
|
||||
return getBindingsList(name);
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(Name name) throws NamingException {
|
||||
return listBindings(name.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup Operations
|
||||
*/
|
||||
|
||||
public Object lookup(String name) throws NamingException {
|
||||
return lookupSchemaElement(name);
|
||||
}
|
||||
|
||||
public Object lookup(Name name) throws NamingException {
|
||||
return lookup(name.toString());
|
||||
}
|
||||
|
||||
public Object lookupLink(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Object lookupLink(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class SchemaElementNameEnum implements NamingEnumeration {
|
||||
|
||||
/**
|
||||
* Enumeration of schema object names packaged into NameClassPair.
|
||||
* The class in NameClassPair is DirContext
|
||||
*/
|
||||
Enumeration m_nameEnum;
|
||||
|
||||
static final String _className = "javax.naming.directory.DirContext"; // for class name is bindings";
|
||||
|
||||
public SchemaElementNameEnum(Enumeration nameEnum) {
|
||||
m_nameEnum = nameEnum;
|
||||
}
|
||||
|
||||
public Object next() throws NamingException{
|
||||
return nextElement();
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
String name = (String) m_nameEnum.nextElement();
|
||||
return new NameClassPair(name, _className, /*isRelative=*/true);
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException{
|
||||
return m_nameEnum.hasMoreElements();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return m_nameEnum.hasMoreElements();
|
||||
}
|
||||
|
||||
public void close() {}
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
import com.netscape.jndi.ldap.common.*;
|
||||
|
||||
/**
|
||||
* A wrapper calss for LDAPSchema. It main purpose is to manage loading of schema
|
||||
* on demand. The schema is loaded when accessed for the first time, or after changes
|
||||
* to the schema have been made.
|
||||
*/
|
||||
class SchemaManager {
|
||||
|
||||
/**
|
||||
* LdapJDK main schema object
|
||||
*/
|
||||
private LDAPSchema m_schema;
|
||||
|
||||
/**
|
||||
* LDAP Connection object
|
||||
*/
|
||||
private LDAPConnection m_ld;
|
||||
|
||||
/**
|
||||
* Flag whether schema needs to be loaded by calling fetchSchema()
|
||||
*/
|
||||
private boolean m_isLoaded;
|
||||
|
||||
/**
|
||||
* Flag whether schema objects have been modified in the Directory (add, remove)
|
||||
* but the change has not been propagated to the cached m_schema object
|
||||
*/
|
||||
private boolean m_isObjectClassDirty, m_isAttributeDirty, m_isMatchingRuleDirty;
|
||||
|
||||
/**
|
||||
* Must constract with LDAP Connection
|
||||
*/
|
||||
private SchemaManager() {}
|
||||
|
||||
/**
|
||||
* Connstructor
|
||||
*/
|
||||
public SchemaManager(LDAPConnection ld) {
|
||||
m_ld = ld;
|
||||
m_isLoaded = false;
|
||||
m_isObjectClassDirty = m_isAttributeDirty = m_isMatchingRuleDirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the schema
|
||||
*/
|
||||
void load() throws NamingException {
|
||||
try {
|
||||
m_schema = new LDAPSchema();
|
||||
m_schema.fetchSchema(m_ld);
|
||||
m_isLoaded = true;
|
||||
m_isObjectClassDirty = m_isAttributeDirty = m_isMatchingRuleDirty = false;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
LDAPObjectClassSchema getObjectClass(String name) throws NamingException {
|
||||
if (!m_isLoaded || m_isObjectClassDirty) {
|
||||
load();
|
||||
}
|
||||
return m_schema.getObjectClass(name);
|
||||
}
|
||||
|
||||
LDAPAttributeSchema getAttribute(String name) throws NamingException {
|
||||
if (!m_isLoaded || m_isAttributeDirty) {
|
||||
load();
|
||||
}
|
||||
return m_schema.getAttribute(name);
|
||||
}
|
||||
|
||||
LDAPMatchingRuleSchema getMatchingRule(String name) throws NamingException {
|
||||
if (!m_isLoaded || m_isMatchingRuleDirty) {
|
||||
load();
|
||||
}
|
||||
return m_schema.getMatchingRule(name);
|
||||
}
|
||||
|
||||
|
||||
Enumeration getObjectClassNames() throws NamingException {
|
||||
if (!m_isLoaded || m_isObjectClassDirty) {
|
||||
load();
|
||||
}
|
||||
return m_schema.getObjectClassNames();
|
||||
}
|
||||
|
||||
Enumeration getAttributeNames() throws NamingException {
|
||||
if (!m_isLoaded || m_isAttributeDirty) {
|
||||
load();
|
||||
}
|
||||
return m_schema.getAttributeNames();
|
||||
}
|
||||
|
||||
Enumeration getMatchingRuleNames() throws NamingException {
|
||||
if (!m_isLoaded || m_isMatchingRuleDirty) {
|
||||
load();
|
||||
}
|
||||
return m_schema.getMatchingRuleNames();
|
||||
}
|
||||
|
||||
Enumeration getObjectClasses() throws NamingException {
|
||||
if (!m_isLoaded || m_isObjectClassDirty) {
|
||||
load();
|
||||
}
|
||||
return m_schema.getObjectClasses();
|
||||
}
|
||||
|
||||
Enumeration getAttributes() throws NamingException {
|
||||
if (!m_isLoaded || m_isAttributeDirty) {
|
||||
load();
|
||||
}
|
||||
return m_schema.getAttributes();
|
||||
}
|
||||
|
||||
Enumeration getMatchingRules() throws NamingException {
|
||||
if (!m_isLoaded || m_isMatchingRuleDirty) {
|
||||
load();
|
||||
}
|
||||
return m_schema.getMatchingRules();
|
||||
}
|
||||
|
||||
void createObjectClass(LDAPObjectClassSchema objclass) throws NamingException {
|
||||
try {
|
||||
objclass.add(m_ld);
|
||||
m_isObjectClassDirty = true;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void createAttribute(LDAPAttributeSchema attr) throws NamingException {
|
||||
try {
|
||||
attr.add(m_ld);
|
||||
m_isAttributeDirty = true;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void createMatchingRule(LDAPMatchingRuleSchema mrule) throws NamingException {
|
||||
try {
|
||||
mrule.add(m_ld);
|
||||
m_isMatchingRuleDirty = true;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void removeObjectClass(String name) throws NamingException {
|
||||
LDAPObjectClassSchema objclass = getObjectClass(name);
|
||||
|
||||
if (objclass == null) {
|
||||
throw new NameNotFoundException(name);
|
||||
}
|
||||
|
||||
try {
|
||||
objclass.remove(m_ld);
|
||||
m_isObjectClassDirty = true;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void removeAttribute(String name) throws NamingException {
|
||||
LDAPAttributeSchema attr = getAttribute(name);
|
||||
|
||||
if (attr == null) {
|
||||
throw new NameNotFoundException(name);
|
||||
}
|
||||
|
||||
try {
|
||||
attr.remove(m_ld);
|
||||
m_isAttributeDirty = true;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void removeMatchingRule(String name) throws NamingException {
|
||||
LDAPMatchingRuleSchema mrule = getMatchingRule(name);
|
||||
|
||||
if (mrule == null) {
|
||||
throw new NameNotFoundException(name);
|
||||
}
|
||||
|
||||
try {
|
||||
mrule.remove(m_ld);
|
||||
m_isMatchingRuleDirty = true;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void modifyObjectClass(LDAPObjectClassSchema objclass, LDAPObjectClassSchema modObjClass) throws NamingException {
|
||||
try {
|
||||
objclass.modify(m_ld, modObjClass);
|
||||
m_isObjectClassDirty = true;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void modifyAttribute(LDAPAttributeSchema attr, LDAPAttributeSchema modAttr) throws NamingException {
|
||||
try {
|
||||
attr.modify(m_ld, modAttr);
|
||||
m_isAttributeDirty = true;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void modifyMatchingRule(LDAPMatchingRuleSchema mrule, LDAPMatchingRuleSchema modMRule) throws NamingException {
|
||||
try {
|
||||
mrule.modify(m_ld, modMRule);
|
||||
m_isMatchingRuleDirty = true;
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw ExceptionMapper.getNamingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SchemaMatchingRule extends SchemaElement {
|
||||
|
||||
|
||||
private static final String APPLIES = "APPLIES";
|
||||
|
||||
LDAPMatchingRuleSchema m_ldapMatchingRule;
|
||||
|
||||
// Attribute IDs that are exposed through Netscape LdapJDK
|
||||
private static String[] m_allAttrIds = {NUMERICOID, NAME, DESC, SYNTAX, APPLIES };
|
||||
|
||||
LDAPConnection m_ld;
|
||||
|
||||
public SchemaMatchingRule(LDAPMatchingRuleSchema ldapMatchingRule, SchemaManager schemaManager) {
|
||||
super(schemaManager);
|
||||
m_ldapMatchingRule = ldapMatchingRule;
|
||||
m_path = ATTRDEF + "/" + m_ldapMatchingRule.getName();
|
||||
}
|
||||
|
||||
public SchemaMatchingRule(Attributes attrs, SchemaManager schemaManager) throws NamingException {
|
||||
super(schemaManager);
|
||||
m_ldapMatchingRule = parseDefAttributes(attrs);
|
||||
m_path = ATTRDEF + "/" + m_ldapMatchingRule.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Definition Attributes for a LDAP matching rule
|
||||
*/
|
||||
static LDAPMatchingRuleSchema parseDefAttributes(Attributes attrs) throws NamingException {
|
||||
String name="", oid="", desc="";
|
||||
int syntax=-1;
|
||||
Vector applies = new Vector();
|
||||
|
||||
for (Enumeration attrEnum = attrs.getAll(); attrEnum.hasMoreElements(); ) {
|
||||
Attribute attr = (Attribute) attrEnum.nextElement();
|
||||
String attrName = attr.getID();
|
||||
if (attrName.equals(NAME)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
name = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(NUMERICOID)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
oid = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(SYNTAX)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
String syntaxString = (String)valEnum.nextElement();
|
||||
syntax = syntaxStringToInt(syntaxString);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(DESC)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
desc = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(APPLIES)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
applies.addElement((String)valEnum.nextElement());
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(OBSOLETE)) {
|
||||
; //ignore
|
||||
}
|
||||
else {
|
||||
throw new NamingException("Invalid schema attribute type for attribute definition " + attrName);
|
||||
}
|
||||
}
|
||||
|
||||
if (name.length() == 0 || oid.length() == 0 || syntax == -1) {
|
||||
throw new NamingException("Incomplete schema attribute definition");
|
||||
}
|
||||
|
||||
return new LDAPMatchingRuleSchema(name, oid, desc, vectorToStringAry(applies), syntax);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exctract specified attributes from the ldapMatchingRule
|
||||
*/
|
||||
Attributes extractAttributeIds(String[] attrIds) throws NamingException{
|
||||
Attributes attrs = new BasicAttributes();
|
||||
for (int i = 0; i < attrIds.length; i++) {
|
||||
if (attrIds[i].equals(NUMERICOID)) {
|
||||
attrs.put(new BasicAttribute(NUMERICOID, m_ldapMatchingRule.getOID()));
|
||||
}
|
||||
else if (attrIds[i].equals(NAME)) {
|
||||
attrs.put(new BasicAttribute(NAME, m_ldapMatchingRule.getName()));
|
||||
}
|
||||
else if (attrIds[i].equals(DESC)) {
|
||||
attrs.put(new BasicAttribute(DESC, m_ldapMatchingRule.getDescription()));
|
||||
}
|
||||
else if (attrIds[i].equals(SYNTAX)) {
|
||||
attrs.put(new BasicAttribute(SYNTAX, syntaxIntToString(m_ldapMatchingRule.getSyntax())));
|
||||
}
|
||||
else if (attrIds[i].equals(APPLIES)) {
|
||||
String[] appliesToAttrs = m_ldapMatchingRule.getAttributes();
|
||||
if (appliesToAttrs != null && appliesToAttrs.length > 0) {
|
||||
BasicAttribute applies = new BasicAttribute(APPLIES);
|
||||
for (int a=0; a < appliesToAttrs.length; a++) {
|
||||
applies.add(appliesToAttrs[a]);
|
||||
}
|
||||
attrs.put(applies);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ignore other attrIds as not supported by Netscape LdapJDK APIs
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DirContext Attribute Operations
|
||||
*/
|
||||
|
||||
public Attributes getAttributes(String name) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
return extractAttributeIds(m_allAttrIds);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
return extractAttributeIds(attrIds);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name) throws NamingException {
|
||||
return getAttributes(name.toString());
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
|
||||
return getAttributes(name.toString(), attrIds);
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
Attributes modAttrs = extractAttributeIds(m_allAttrIds);
|
||||
modifySchemaElementAttrs(modAttrs, mod_op, attrs);
|
||||
LDAPMatchingRuleSchema modLdapMatchingRule = parseDefAttributes(modAttrs);
|
||||
m_schemaMgr.modifyMatchingRule(m_ldapMatchingRule, modLdapMatchingRule);
|
||||
m_ldapMatchingRule = modLdapMatchingRule;
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
Attributes modAttrs = extractAttributeIds(m_allAttrIds);
|
||||
modifySchemaElementAttrs(modAttrs, mods);
|
||||
LDAPMatchingRuleSchema modLdapMatchingRule = parseDefAttributes(modAttrs);
|
||||
m_schemaMgr.modifyMatchingRule(m_ldapMatchingRule, modLdapMatchingRule);
|
||||
m_ldapMatchingRule = modLdapMatchingRule;
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
|
||||
modifyAttributes(name.toString(), mod_op, attrs);
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
|
||||
modifyAttributes(name.toString(), mods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search operations are not implemented because of complexity. Ir will require
|
||||
* to implement the full LDAP search filter sematics in the client. (The search
|
||||
* filter sematics is implemented by the Directory server).
|
||||
*/
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SchemaMatchingRuleContainer extends SchemaElementContainer {
|
||||
|
||||
public SchemaMatchingRuleContainer(SchemaManager schemaMgr) throws NamingException{
|
||||
super(schemaMgr, MRULEDEF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ldap entry operations
|
||||
*/
|
||||
|
||||
public DirContext createSchemaElement(String name, Attributes attrs) throws NamingException {
|
||||
if (name.length() == 0) {
|
||||
throw new NamingException("Empty name for schema objectclass");
|
||||
}
|
||||
LDAPMatchingRuleSchema mrule = SchemaMatchingRule.parseDefAttributes(attrs);
|
||||
m_schemaMgr.createMatchingRule(mrule);
|
||||
return new SchemaMatchingRule(mrule, m_schemaMgr);
|
||||
|
||||
}
|
||||
|
||||
public void removeSchemaElement(String name) throws NamingException {
|
||||
if (name.length() == 0) {
|
||||
throw new NamingException("Can not delete schema object container");
|
||||
}
|
||||
m_schemaMgr.removeMatchingRule(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* List Operations
|
||||
*/
|
||||
|
||||
public NamingEnumeration getNameList(String name) throws NamingException {
|
||||
SchemaDirContext schemaObj = (SchemaDirContext)lookup(name);
|
||||
if (schemaObj == this) {
|
||||
return new SchemaElementNameEnum(m_schemaMgr.getMatchingRuleNames());
|
||||
}
|
||||
else {
|
||||
throw new NotContextException(name);
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration getBindingsList(String name) throws NamingException {
|
||||
SchemaDirContext schemaObj = (SchemaDirContext)lookup(name);
|
||||
if (schemaObj == this) {
|
||||
return new SchemaElementBindingEnum(m_schemaMgr.getMatchingRules(), m_schemaMgr);
|
||||
}
|
||||
else {
|
||||
throw new NotContextException(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup Operations
|
||||
*/
|
||||
|
||||
public Object lookupSchemaElement(String name) throws NamingException {
|
||||
if (name.length() == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// No caching; Always create a new object
|
||||
LDAPAttributeSchema mrule = m_schemaMgr.getMatchingRule(name);
|
||||
if (mrule == null) {
|
||||
throw new NameNotFoundException(name);
|
||||
}
|
||||
return new SchemaAttribute(mrule, m_schemaMgr);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Properties;
|
||||
import javax.naming.*;
|
||||
|
||||
class SchemaNameParser implements NameParser {
|
||||
|
||||
private static SchemaNameParser m_parser;
|
||||
|
||||
// A table with compound name syntax properties
|
||||
static Properties nameSyntax;
|
||||
static {
|
||||
nameSyntax = new Properties();
|
||||
nameSyntax.put("jndi.syntax.direction", "left_to_right");
|
||||
nameSyntax.put("jndi.syntax.separator", "/");
|
||||
nameSyntax.put("jndi.syntax.ignorecase", "true");
|
||||
}
|
||||
|
||||
// Can not be constructed
|
||||
private SchemaNameParser() {}
|
||||
|
||||
// Shared instance must be used
|
||||
public static SchemaNameParser getParser() {
|
||||
if (m_parser == null) {
|
||||
m_parser = new SchemaNameParser();
|
||||
}
|
||||
return m_parser;
|
||||
}
|
||||
|
||||
// implements parse
|
||||
public Name parse(String name) throws NamingException {
|
||||
return new CompoundName(name, nameSyntax);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SchemaObjectClass extends SchemaElement {
|
||||
|
||||
LDAPObjectClassSchema m_ldapObjectClass;
|
||||
|
||||
// Attribute IDs that are exposed through Netscape LdapJDK
|
||||
private static String[] m_allAttrIds = {NUMERICOID, NAME, DESC, SUP, MUST, MAY };
|
||||
|
||||
public SchemaObjectClass(LDAPObjectClassSchema ldapObjectClass, SchemaManager schemaManager) {
|
||||
super(schemaManager);
|
||||
m_ldapObjectClass = ldapObjectClass;
|
||||
m_path = CLASSDEF + "/" + m_ldapObjectClass.getName();
|
||||
}
|
||||
|
||||
public SchemaObjectClass(Attributes attrs, SchemaManager schemaManager) throws NamingException {
|
||||
super(schemaManager);
|
||||
m_ldapObjectClass = parseDefAttributes(attrs);
|
||||
m_path = CLASSDEF + "/" + m_ldapObjectClass.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Definition Attributes for a LDAP objectcalss
|
||||
*/
|
||||
static LDAPObjectClassSchema parseDefAttributes(Attributes attrs) throws NamingException {
|
||||
String name="", oid="", desc="", sup="";
|
||||
Vector must=new Vector(), may=new Vector();
|
||||
|
||||
for (Enumeration attrEnum = attrs.getAll(); attrEnum.hasMoreElements(); ) {
|
||||
Attribute attr = (Attribute) attrEnum.nextElement();
|
||||
String attrName = attr.getID();
|
||||
if (attrName.equals(NAME)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
name = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(NUMERICOID)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
oid = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(SUP)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
sup = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(DESC)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
desc = (String)valEnum.nextElement();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(MAY)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
may.addElement((String)valEnum.nextElement());
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(MUST)) {
|
||||
for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) {
|
||||
must.addElement((String)valEnum.nextElement());
|
||||
}
|
||||
}
|
||||
else if (attrName.equals(OBSOLETE) || attrName.equals(ABSTRACT) ||
|
||||
attrName.equals(STRUCTURAL) || attrName.equals(AUXILIARY)) {
|
||||
; //ignore
|
||||
}
|
||||
else {
|
||||
throw new NamingException("Invalid schema attribute type for object class definition " + attrName);
|
||||
}
|
||||
}
|
||||
|
||||
if (name.length() == 0 || oid.length() == 0 || sup.length() == 0 ||
|
||||
(must.size() == 0 && may.size() == 0)) {
|
||||
|
||||
throw new NamingException("Incomplete schema object class definition");
|
||||
}
|
||||
|
||||
return new LDAPObjectClassSchema(name, oid, sup, desc,
|
||||
vectorToStringAry(must),
|
||||
vectorToStringAry(may));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exctract specified attributes from the ldapObjectClass
|
||||
*/
|
||||
Attributes extractAttributeIds(String[] attrIds) {
|
||||
Attributes attrs = new BasicAttributes();
|
||||
for (int i = 0; i < attrIds.length; i++) {
|
||||
if (attrIds[i].equals(NUMERICOID)) {
|
||||
attrs.put(new BasicAttribute(NUMERICOID, m_ldapObjectClass.getOID()));
|
||||
}
|
||||
else if (attrIds[i].equals(NAME)) {
|
||||
attrs.put(new BasicAttribute(NAME, m_ldapObjectClass.getName()));
|
||||
}
|
||||
else if (attrIds[i].equals(DESC)) {
|
||||
attrs.put(new BasicAttribute(DESC, m_ldapObjectClass.getDescription()));
|
||||
}
|
||||
else if (attrIds[i].equals(SUP)) {
|
||||
attrs.put(new BasicAttribute(SUP, m_ldapObjectClass.getSuperior()));
|
||||
}
|
||||
else if (attrIds[i].equals(MAY)) {
|
||||
BasicAttribute optional = new BasicAttribute(MAY);
|
||||
for (Enumeration e = m_ldapObjectClass.getOptionalAttributes(); e.hasMoreElements();) {
|
||||
optional.add(e.nextElement());
|
||||
}
|
||||
attrs.put(optional);
|
||||
}
|
||||
else if (attrIds[i].equals(MUST)) {
|
||||
BasicAttribute required = new BasicAttribute(MUST);
|
||||
for (Enumeration e = m_ldapObjectClass.getRequiredAttributes(); e.hasMoreElements();) {
|
||||
required.add(e.nextElement());
|
||||
}
|
||||
attrs.put(required);
|
||||
}
|
||||
else {
|
||||
// ignore other attrIds as not supported by Netscape LdapJDK APIs
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DirContext Attribute Operations
|
||||
*/
|
||||
|
||||
public Attributes getAttributes(String name) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
return extractAttributeIds(m_allAttrIds);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
return extractAttributeIds(attrIds);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name) throws NamingException {
|
||||
return getAttributes(name.toString());
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
|
||||
return getAttributes(name.toString(), attrIds);
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
Attributes modAttrs = extractAttributeIds(m_allAttrIds);
|
||||
modifySchemaElementAttrs(modAttrs, mod_op, attrs);
|
||||
LDAPObjectClassSchema modLdapObjectClass = parseDefAttributes(modAttrs);
|
||||
m_schemaMgr.modifyObjectClass(m_ldapObjectClass, modLdapObjectClass);
|
||||
m_ldapObjectClass = modLdapObjectClass;
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
|
||||
if (name.length() != 0) { // no subcontexts
|
||||
throw new NameNotFoundException(name); // no such object
|
||||
}
|
||||
Attributes modAttrs = extractAttributeIds(m_allAttrIds);
|
||||
modifySchemaElementAttrs(modAttrs, mods);
|
||||
LDAPObjectClassSchema modLdapObjectClass = parseDefAttributes(modAttrs);
|
||||
m_schemaMgr.modifyObjectClass(m_ldapObjectClass, modLdapObjectClass);
|
||||
m_ldapObjectClass = modLdapObjectClass;
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
|
||||
modifyAttributes(name.toString(), mod_op, attrs);
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
|
||||
modifyAttributes(name.toString(), mods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search operations are not implemented because of complexity. Ir will require
|
||||
* to implement the full LDAP search filter sematics in the client. (The search
|
||||
* filter sematics is implemented by the Directory server).
|
||||
*/
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SchemaObjectClassContainer extends SchemaElementContainer {
|
||||
|
||||
public SchemaObjectClassContainer(SchemaManager schemaMgr) throws NamingException{
|
||||
super(schemaMgr, CLASSDEF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ldap entry operations
|
||||
*/
|
||||
|
||||
public DirContext createSchemaElement(String name, Attributes attrs) throws NamingException {
|
||||
if (name.length() == 0) {
|
||||
throw new NamingException("Empty name for schema objectclass");
|
||||
}
|
||||
LDAPObjectClassSchema objclass = SchemaObjectClass.parseDefAttributes(attrs);
|
||||
m_schemaMgr.createObjectClass(objclass);
|
||||
return new SchemaObjectClass(objclass, m_schemaMgr);
|
||||
|
||||
}
|
||||
|
||||
public void removeSchemaElement(String name) throws NamingException {
|
||||
if (name.length() == 0) {
|
||||
throw new NamingException("Can not delete schema object container");
|
||||
}
|
||||
m_schemaMgr.removeObjectClass(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* List Operations
|
||||
*/
|
||||
|
||||
public NamingEnumeration getNameList(String name) throws NamingException {
|
||||
SchemaDirContext schemaObj = (SchemaDirContext)lookup(name);
|
||||
if (schemaObj == this) {
|
||||
return new SchemaElementNameEnum(m_schemaMgr.getObjectClassNames());
|
||||
}
|
||||
else {
|
||||
throw new NotContextException(name);
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration getBindingsList(String name) throws NamingException {
|
||||
SchemaDirContext schemaObj = (SchemaDirContext)lookup(name);
|
||||
if (schemaObj == this) {
|
||||
return new SchemaElementBindingEnum(m_schemaMgr.getObjectClasses(), m_schemaMgr);
|
||||
}
|
||||
else {
|
||||
throw new NotContextException(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup Operations
|
||||
*/
|
||||
|
||||
public Object lookupSchemaElement(String name) throws NamingException {
|
||||
if (name.length() == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// No caching; Always create a new object
|
||||
LDAPObjectClassSchema objclass = m_schemaMgr.getObjectClass(name);
|
||||
if (objclass == null) {
|
||||
throw new NameNotFoundException(name);
|
||||
}
|
||||
return new SchemaObjectClass(objclass, m_schemaMgr);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,360 @@
|
|||
/* -*- 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 com.netscape.jndi.ldap.schema;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.ldap.*;
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SchemaRoot extends SchemaDirContext {
|
||||
|
||||
static final String m_className = "javax.naming.directory.DirContext"; // for class name is bindings
|
||||
|
||||
SchemaDirContext m_classContainer, m_attrContainer, m_matchRuleContainer;
|
||||
|
||||
SchemaManager m_schemaMgr;
|
||||
|
||||
public SchemaRoot(LDAPConnection ld) throws NamingException{
|
||||
m_path = "";
|
||||
m_schemaMgr = new SchemaManager(ld);
|
||||
m_classContainer = new SchemaObjectClassContainer(m_schemaMgr);
|
||||
m_attrContainer = new SchemaAttributeContainer(m_schemaMgr);
|
||||
m_matchRuleContainer = new SchemaMatchingRuleContainer(m_schemaMgr);
|
||||
}
|
||||
|
||||
SchemaObjectSubordinateNamePair resolveSchemaObject(String name) throws NamingException{
|
||||
|
||||
SchemaDirContext obj = null;
|
||||
|
||||
if (name.length() == 0) {
|
||||
obj = this;
|
||||
}
|
||||
else if (name.startsWith(CLASSDEF) || name.startsWith(CLASSDEF.toLowerCase())) {
|
||||
name = name.substring(CLASSDEF.length());
|
||||
obj = m_classContainer;
|
||||
}
|
||||
else if (name.startsWith(ATTRDEF) || name.startsWith(ATTRDEF.toLowerCase())) {
|
||||
name = name.substring(ATTRDEF.length());
|
||||
obj = m_attrContainer;
|
||||
}
|
||||
else if (name.startsWith(MRULEDEF) || name.startsWith(MRULEDEF.toLowerCase())) {
|
||||
name = name.substring(MRULEDEF.length());
|
||||
obj = m_matchRuleContainer;
|
||||
|
||||
}
|
||||
else {
|
||||
throw new NameNotFoundException(name);
|
||||
}
|
||||
|
||||
if (name.length() > 1 && name.startsWith("/")) {
|
||||
name = name.substring(1);
|
||||
}
|
||||
return new SchemaObjectSubordinateNamePair(obj, name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attribute Operations
|
||||
*/
|
||||
|
||||
public Attributes getAttributes(String name) throws NamingException {
|
||||
SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name);
|
||||
if (objNamePair.schemaObj == this) {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
else {
|
||||
return objNamePair.schemaObj.getAttributes(objNamePair.subordinateName);
|
||||
}
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
|
||||
SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name);
|
||||
if (objNamePair.schemaObj == this) {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
else {
|
||||
return objNamePair.schemaObj.getAttributes(objNamePair.subordinateName, attrIds);
|
||||
}
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name) throws NamingException {
|
||||
return getAttributes(name.toString());
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
|
||||
return getAttributes(name.toString(), attrIds);
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ldap entry operations
|
||||
*/
|
||||
|
||||
public Context createSubcontext(String name) throws NamingException {
|
||||
// Directory entry must have attributes
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Context createSubcontext(Name name) throws NamingException {
|
||||
// Directory entry must have attributes
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(String name, Attributes attrs) throws NamingException {
|
||||
SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name);
|
||||
if (objNamePair.schemaObj == this) {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
else {
|
||||
return objNamePair.schemaObj.createSubcontext(objNamePair.subordinateName, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException {
|
||||
return createSubcontext(name.toString(), attrs);
|
||||
}
|
||||
|
||||
public void destroySubcontext(String name) throws NamingException {
|
||||
SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name);
|
||||
if (objNamePair.schemaObj == this) {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
else {
|
||||
objNamePair.schemaObj.destroySubcontext(objNamePair.subordinateName);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroySubcontext(Name name) throws NamingException {
|
||||
destroySubcontext(name.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Naming Bind operations
|
||||
*/
|
||||
|
||||
public void bind(String name, Object obj) throws NamingException {
|
||||
if (obj instanceof DirContext) {
|
||||
createSubcontext(name, ((DirContext)obj).getAttributes(""));
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Can not bind this type of object");
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj) throws NamingException {
|
||||
bind(name.toString(), obj);
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj) throws NamingException {
|
||||
unbind(name);
|
||||
bind(name, obj);
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj) throws NamingException {
|
||||
rebind(name.toString(), obj);
|
||||
}
|
||||
|
||||
public void rename(String oldName, String newName) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public void rename(Name oldName, Name newName) throws NamingException {
|
||||
rename(oldName.toString(), newName.toString());
|
||||
}
|
||||
|
||||
public void unbind(String name) throws NamingException {
|
||||
// In ldap every entry is naming context
|
||||
destroySubcontext(name);
|
||||
}
|
||||
|
||||
public void unbind(Name name) throws NamingException {
|
||||
// In ldap every entry is naming context
|
||||
destroySubcontext(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* List Operations
|
||||
*/
|
||||
|
||||
public NamingEnumeration list(String name) throws NamingException {
|
||||
SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name);
|
||||
if (objNamePair.schemaObj == this) {
|
||||
return new SchemaRootNameClassPairEnum();
|
||||
}
|
||||
else {
|
||||
return objNamePair.schemaObj.list(objNamePair.subordinateName);
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration list(Name name) throws NamingException {
|
||||
return list(name.toString());
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(String name) throws NamingException {
|
||||
SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name);
|
||||
if (objNamePair.schemaObj == this) {
|
||||
return new SchemaRootBindingEnum();
|
||||
}
|
||||
else {
|
||||
return objNamePair.schemaObj.listBindings(objNamePair.subordinateName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(Name name) throws NamingException {
|
||||
return listBindings(name.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup Operations
|
||||
*/
|
||||
|
||||
public Object lookup(String name) throws NamingException {
|
||||
SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name);
|
||||
if (objNamePair.schemaObj == this) {
|
||||
return this;
|
||||
}
|
||||
else {
|
||||
return objNamePair.schemaObj.lookup(objNamePair.subordinateName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Object lookup(Name name) throws NamingException {
|
||||
return lookup(name.toString());
|
||||
}
|
||||
|
||||
public Object lookupLink(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public Object lookupLink(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test program
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
try {
|
||||
String name = args[0];
|
||||
System.out.println((new SchemaRoot(null)).resolveSchemaObject(name));
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NamigEnumeration of NameClassPairs
|
||||
*/
|
||||
class SchemaRootNameClassPairEnum implements NamingEnumeration {
|
||||
|
||||
private int m_idx = -1;
|
||||
|
||||
public Object next() {
|
||||
return nextElement();
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
m_idx++;
|
||||
if (m_idx == 0 ) {
|
||||
return new NameClassPair(CLASSDEF, m_className);
|
||||
}
|
||||
else if (m_idx == 1) {
|
||||
return new NameClassPair(ATTRDEF, m_className);
|
||||
}
|
||||
else if (m_idx == 2) {
|
||||
return new NameClassPair(MRULEDEF, m_className);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchElementException("SchemaRootEnumerator");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean hasMore() {
|
||||
return hasMoreElements();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return m_idx < 2;
|
||||
}
|
||||
|
||||
public void close() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* NamingEnumeration of Bindings
|
||||
*/
|
||||
class SchemaRootBindingEnum implements NamingEnumeration {
|
||||
|
||||
private int m_idx = -1;
|
||||
|
||||
public Object next() {
|
||||
return nextElement();
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
m_idx++;
|
||||
if (m_idx == 0 ) {
|
||||
return new Binding(CLASSDEF, m_className, m_classContainer);
|
||||
}
|
||||
else if (m_idx == 1) {
|
||||
return new Binding(ATTRDEF, m_className, m_attrContainer);
|
||||
}
|
||||
else if (m_idx == 2) {
|
||||
return new Binding(MRULEDEF, m_className, m_matchRuleContainer);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchElementException("SchemaRootEnumerator");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean hasMore() {
|
||||
return hasMoreElements();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return m_idx < 2;
|
||||
}
|
||||
|
||||
public void close() {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
#
|
||||
# -- Attribute types --
|
||||
#
|
||||
attribute javaClassName 1.3.6.1.4.1.42.2.27.4.1.6 ces single
|
||||
attribute javaCodebase 1.3.6.1.4.1.42.2.27.4.1.7 ces
|
||||
attribute javaSerializedData 1.3.6.1.4.1.42.2.27.4.1.8 bin single
|
||||
attribute javaRemoteLocation 1.3.6.1.4.1.42.2.27.4.1.9 ces single
|
||||
attribute javaFactory 1.3.6.1.4.1.42.2.27.4.1.10 ces single
|
||||
attribute javaReferenceAddress 1.3.6.1.4.1.42.2.27.4.1.11 ces
|
||||
|
||||
#
|
||||
# -- Object classes --
|
||||
#
|
||||
objectclass javaContainer
|
||||
oid 1.3.6.1.4.1.42.2.27.4.2.1
|
||||
superior top
|
||||
requires
|
||||
cn
|
||||
|
||||
objectclass javaObject
|
||||
oid 1.3.6.1.4.1.42.2.27.4.2.4
|
||||
superior top
|
||||
requires
|
||||
javaClassName
|
||||
allows
|
||||
javaCodebase
|
||||
|
||||
objectclass javaSerializedObject
|
||||
oid 1.3.6.1.4.1.42.2.27.4.2.5
|
||||
superior javaObject
|
||||
requires
|
||||
javaSerializedData
|
||||
|
||||
|
||||
objectclass javaRemoteObject
|
||||
oid 1.3.6.1.4.1.42.2.27.4.2.6
|
||||
superior javaObject
|
||||
requires
|
||||
javaRemoteLocation
|
||||
|
||||
objectclass javaNamingReference
|
||||
oid 1.3.6.1.4.1.42.2.27.4.2.7
|
||||
superior javaObject
|
||||
allows
|
||||
javaReferenceAddress,
|
||||
javaFactory
|
||||
|
Двоичный файл не отображается.
|
@ -0,0 +1,104 @@
|
|||
Name: com/netscape/jndi/ldap/AttributeEnum.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/AttributeIDEnum.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/AttributesImpl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/BindingEnum.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/ContextEnv$ReferralRebindProc.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/ContextEnv.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/EventService$EventThread.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/EventService.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/LdapContextFactory.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/LdapContextImpl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/LdapNameParser.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/LdapReferralException.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/LdapService.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/NameClassPairEnum.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/ObjectMapper.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/ProviderUtils.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/SearchResultEnum.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/SearchResultWithControls.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/common/Debug.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/common/DirContextAdapter.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/common/ExceptionMapper.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/common/LdapContextAdapter.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/common/ShareableEnv.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaAttribute.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaAttributeContainer.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaDirContext$EmptyNamingEnumeration.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaDirContext$SchemaObjectSubordinateNamePair.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaDirContext.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaElement.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaElementBindingEnum.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaElementContainer.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaElementNameEnum.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaManager.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaMatchingRule.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaMatchingRuleContainer.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaNameParser.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaObjectClass.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaObjectClassContainer.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaRoot$SchemaRootBindingEnum.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaRoot$SchemaRootNameClassPairEnum.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/schema/SchemaRoot.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapEntryChangeControl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapPasswordExpiredControl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapPasswordExpiringControl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapPersistSearchControl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapProxiedAuthControl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapSortControl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapSortKey.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapSortResponseControl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapVirtualListControl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/LdapVirtualListResponseControl.class
|
||||
|
||||
Name: com/netscape/jndi/ldap/controls/NetscapeControlFactory.class
|
||||
|
Загрузка…
Ссылка в новой задаче