| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.directory.server.core.jndi; |
| |
| |
| import org.apache.directory.server.core.DirectoryService; |
| import org.apache.directory.server.core.authn.LdapPrincipal; |
| import org.apache.directory.server.core.entry.ServerEntry; |
| import org.apache.directory.server.core.entry.ServerEntryUtils; |
| import org.apache.directory.server.core.interceptor.context.EntryOperationContext; |
| import org.apache.directory.server.core.partition.PartitionNexusProxy; |
| import org.apache.directory.shared.ldap.constants.SchemaConstants; |
| import org.apache.directory.shared.ldap.entry.EntryAttribute; |
| import org.apache.directory.shared.ldap.entry.Modification; |
| import org.apache.directory.shared.ldap.entry.client.ClientBinaryValue; |
| import org.apache.directory.shared.ldap.entry.client.ClientStringValue; |
| import org.apache.directory.shared.ldap.filter.AndNode; |
| import org.apache.directory.shared.ldap.filter.BranchNode; |
| import org.apache.directory.shared.ldap.filter.EqualityNode; |
| import org.apache.directory.shared.ldap.filter.ExprNode; |
| import org.apache.directory.shared.ldap.filter.FilterParser; |
| import org.apache.directory.shared.ldap.filter.PresenceNode; |
| import org.apache.directory.shared.ldap.filter.SimpleNode; |
| import org.apache.directory.shared.ldap.message.AliasDerefMode; |
| import org.apache.directory.shared.ldap.message.ModificationItemImpl; |
| import org.apache.directory.shared.ldap.name.AttributeTypeAndValue; |
| import org.apache.directory.shared.ldap.name.LdapDN; |
| import org.apache.directory.shared.ldap.name.Rdn; |
| import org.apache.directory.shared.ldap.util.AttributeUtils; |
| import org.apache.directory.shared.ldap.util.StringTools; |
| |
| import javax.naming.Name; |
| import javax.naming.NamingEnumeration; |
| import javax.naming.NamingException; |
| import javax.naming.Reference; |
| import javax.naming.Referenceable; |
| import javax.naming.directory.Attribute; |
| import javax.naming.directory.Attributes; |
| import javax.naming.directory.DirContext; |
| import javax.naming.directory.InvalidSearchFilterException; |
| import javax.naming.directory.ModificationItem; |
| import javax.naming.directory.SearchControls; |
| import javax.naming.directory.SearchResult; |
| import javax.naming.event.EventDirContext; |
| import javax.naming.event.NamingListener; |
| import javax.naming.spi.DirStateFactory; |
| import javax.naming.spi.DirectoryManager; |
| import java.io.Serializable; |
| import java.net.InetSocketAddress; |
| import java.text.ParseException; |
| import java.util.ArrayList; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| |
| /** |
| * The DirContext implementation for the Server Side JNDI LDAP provider. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| * @version $Rev$ |
| */ |
| public abstract class ServerDirContext extends ServerContext implements EventDirContext |
| { |
| // ------------------------------------------------------------------------ |
| // Constructors |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Creates a new ServerDirContext by reading the PROVIDER_URL to resolve the |
| * distinguished name for this context. |
| * |
| * @param service the parent service that manages this context |
| * @param env the environment used for this context |
| * @throws NamingException if something goes wrong |
| */ |
| public ServerDirContext( DirectoryService service, Hashtable<String, Object> env ) throws NamingException |
| { |
| super( service, env ); |
| } |
| |
| |
| /** |
| * Creates a new ServerDirContext with a distinguished name which is used to |
| * set the PROVIDER_URL to the distinguished name for this context. |
| * |
| * @param principal the principal which is propagated |
| * @param dn the distinguished name of this context |
| */ |
| public ServerDirContext( DirectoryService service, LdapPrincipal principal, Name dn ) throws NamingException |
| { |
| super( service, principal, dn ); |
| } |
| |
| |
| // ------------------------------------------------------------------------ |
| // DirContext Implementations |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * @see javax.naming.directory.DirContext#getAttributes(java.lang.String) |
| */ |
| public Attributes getAttributes( String name ) throws NamingException |
| { |
| return getAttributes( new LdapDN( name ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name) |
| */ |
| public Attributes getAttributes( Name name ) throws NamingException |
| { |
| return ServerEntryUtils.toAttributesImpl( doLookupOperation( buildTarget( name ) ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#getAttributes(java.lang.String, |
| * java.lang.String[]) |
| */ |
| public Attributes getAttributes( String name, String[] attrIds ) throws NamingException |
| { |
| return getAttributes( new LdapDN( name ), attrIds ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name, |
| * java.lang.String[]) |
| */ |
| public Attributes getAttributes( Name name, String[] attrIds ) throws NamingException |
| { |
| return ServerEntryUtils.toAttributesImpl( doLookupOperation( buildTarget( name ), attrIds ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, |
| * int, javax.naming.directory.Attributes) |
| */ |
| public void modifyAttributes( String name, int modOp, Attributes attrs ) throws NamingException |
| { |
| modifyAttributes( new LdapDN( name ), modOp, AttributeUtils.toCaseInsensitive( attrs ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, |
| * int, javax.naming.directory.Attributes) |
| */ |
| public void modifyAttributes( Name name, int modOp, Attributes attrs ) throws NamingException |
| { |
| List<ModificationItemImpl> modItems = null; |
| |
| if ( attrs != null ) |
| { |
| modItems = new ArrayList<ModificationItemImpl>( attrs.size() ); |
| NamingEnumeration<? extends Attribute> e = ( NamingEnumeration<? extends Attribute> ) attrs.getAll(); |
| |
| while ( e.hasMore() ) |
| { |
| modItems.add( new ModificationItemImpl( modOp, e.next() ) ); |
| } |
| } |
| |
| List<Modification> newMods = ServerEntryUtils.toServerModification( modItems, registries |
| .getAttributeTypeRegistry() ); |
| |
| if ( name instanceof LdapDN ) |
| { |
| doModifyOperation( buildTarget( name ), newMods ); |
| } |
| else |
| { |
| doModifyOperation( buildTarget( new LdapDN( name ) ), newMods ); |
| } |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, |
| * javax.naming.directory.ModificationItem[]) |
| */ |
| public void modifyAttributes( String name, ModificationItem[] mods ) throws NamingException |
| { |
| ModificationItemImpl[] newMods = new ModificationItemImpl[mods.length]; |
| |
| for ( int i = 0; i < mods.length; i++ ) |
| { |
| newMods[i] = new ModificationItemImpl( mods[i] ); |
| } |
| |
| modifyAttributes( new LdapDN( name ), newMods ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, |
| * javax.naming.directory.ModificationItem[]) |
| */ |
| public void modifyAttributes( String name, ModificationItemImpl[] mods ) throws NamingException |
| { |
| modifyAttributes( new LdapDN( name ), mods ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#modifyAttributes( |
| * javax.naming.Name, javax.naming.directory.ModificationItem[]) |
| */ |
| public void modifyAttributes( Name name, ModificationItem[] mods ) throws NamingException |
| { |
| List<Modification> newMods = ServerEntryUtils |
| .toServerModification( mods, registries.getAttributeTypeRegistry() ); |
| doModifyOperation( buildTarget( new LdapDN( name ) ), newMods ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#modifyAttributes( |
| * javax.naming.Name, javax.naming.directory.ModificationItem[]) |
| */ |
| public void modifyAttributes( Name name, List<ModificationItemImpl> mods ) throws NamingException |
| { |
| List<Modification> newMods = ServerEntryUtils |
| .toServerModification( mods, registries.getAttributeTypeRegistry() ); |
| doModifyOperation( buildTarget( new LdapDN( name ) ), newMods ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#bind(java.lang.String, |
| * java.lang.Object, javax.naming.directory.Attributes) |
| */ |
| public void bind( String name, Object obj, Attributes attrs ) throws NamingException |
| { |
| bind( new LdapDN( name ), obj, AttributeUtils.toCaseInsensitive( attrs ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#bind(javax.naming.Name, |
| * java.lang.Object, javax.naming.directory.Attributes) |
| */ |
| public void bind( Name name, Object obj, Attributes attrs ) throws NamingException |
| { |
| if ( ( null == obj ) && ( null == attrs ) ) |
| { |
| throw new NamingException( "Both obj and attrs args are null. " |
| + "At least one of these parameters must not be null." ); |
| } |
| |
| // A null attrs defaults this to the Context.bind() operation |
| if ( null == attrs ) |
| { |
| super.bind( name, obj ); |
| return; |
| } |
| |
| LdapDN target = buildTarget( name ); |
| |
| ServerEntry serverEntry = ServerEntryUtils.toServerEntry( AttributeUtils.toCaseInsensitive( attrs ), target, |
| registries ); |
| |
| // No object binding so we just add the attributes |
| if ( null == obj ) |
| { |
| ServerEntry clone = ( ServerEntry ) serverEntry.clone(); |
| doAddOperation( target, clone ); |
| return; |
| } |
| |
| // First, use state factories to do a transformation |
| DirStateFactory.Result res = DirectoryManager.getStateToBind( obj, name, this, getEnvironment(), attrs ); |
| ServerEntry outServerEntry = ServerEntryUtils.toServerEntry( res.getAttributes(), target, registries ); |
| |
| if ( outServerEntry != serverEntry ) |
| { |
| ServerEntry clone = ( ServerEntry ) serverEntry.clone(); |
| |
| if ( ( outServerEntry != null ) && ( outServerEntry.size() > 0 ) ) |
| { |
| for ( EntryAttribute attribute : outServerEntry ) |
| { |
| clone.put( attribute ); |
| } |
| } |
| |
| doAddOperation( target, clone ); |
| return; |
| } |
| |
| // Check for Referenceable |
| if ( obj instanceof Referenceable ) |
| { |
| throw new NamingException( "Do not know how to store Referenceables yet!" ); |
| } |
| |
| // Store different formats |
| if ( obj instanceof Reference ) |
| { |
| // Store as ref and add outAttrs |
| throw new NamingException( "Do not know how to store References yet!" ); |
| } |
| else if ( obj instanceof Serializable ) |
| { |
| // Serialize and add outAttrs |
| ServerEntry clone = ( ServerEntry ) serverEntry.clone(); |
| |
| if ( outServerEntry != null && outServerEntry.size() > 0 ) |
| { |
| for ( EntryAttribute attribute : outServerEntry ) |
| { |
| clone.put( attribute ); |
| } |
| } |
| |
| // Serialize object into entry attributes and add it. |
| JavaLdapSupport.serialize( serverEntry, obj, registries ); |
| doAddOperation( target, clone ); |
| } |
| else if ( obj instanceof DirContext ) |
| { |
| // Grab attributes and merge with outAttrs |
| ServerEntry entry = ServerEntryUtils.toServerEntry( ( ( DirContext ) obj ).getAttributes( "" ), target, |
| registries ); |
| |
| if ( ( outServerEntry != null ) && ( outServerEntry.size() > 0 ) ) |
| { |
| for ( EntryAttribute attribute : outServerEntry ) |
| { |
| entry.put( attribute ); |
| } |
| } |
| |
| doAddOperation( target, entry ); |
| } |
| else |
| { |
| throw new NamingException( "Can't find a way to bind: " + obj ); |
| } |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#rebind(java.lang.String, |
| * java.lang.Object, javax.naming.directory.Attributes) |
| */ |
| public void rebind( String name, Object obj, Attributes attrs ) throws NamingException |
| { |
| rebind( new LdapDN( name ), obj, AttributeUtils.toCaseInsensitive( attrs ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#rebind(javax.naming.Name, |
| * java.lang.Object, javax.naming.directory.Attributes) |
| */ |
| public void rebind( Name name, Object obj, Attributes attrs ) throws NamingException |
| { |
| LdapDN target = buildTarget( name ); |
| |
| if ( getNexusProxy().hasEntry( new EntryOperationContext( registries, target ) ) ) |
| { |
| doDeleteOperation( target ); |
| } |
| |
| bind( name, obj, AttributeUtils.toCaseInsensitive( attrs ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#createSubcontext(java.lang.String, |
| * javax.naming.directory.Attributes) |
| */ |
| public DirContext createSubcontext( String name, Attributes attrs ) throws NamingException |
| { |
| return createSubcontext( new LdapDN( name ), AttributeUtils.toCaseInsensitive( attrs ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#createSubcontext( |
| * javax.naming.Name, javax.naming.directory.Attributes) |
| */ |
| public DirContext createSubcontext( Name name, Attributes attrs ) throws NamingException |
| { |
| if ( null == attrs ) |
| { |
| return ( DirContext ) super.createSubcontext( name ); |
| } |
| |
| LdapDN target = buildTarget( name ); |
| Rdn rdn = target.getRdn( target.size() - 1 ); |
| |
| attrs = AttributeUtils.toCaseInsensitive( attrs ); |
| Attributes attributes = ( Attributes ) attrs.clone(); |
| |
| if ( rdn.size() == 1 ) |
| { |
| String rdnAttribute = rdn.getUpType(); |
| String rdnValue = ( String ) rdn.getValue(); |
| |
| // Add the Rdn attribute |
| boolean doRdnPut = attributes.get( rdnAttribute ) == null; |
| doRdnPut = doRdnPut || attributes.get( rdnAttribute ).size() == 0; |
| |
| // TODO Fix DIRSERVER-832 |
| doRdnPut = doRdnPut || !attributes.get( rdnAttribute ).contains( rdnValue ); |
| |
| if ( doRdnPut ) |
| { |
| attributes.put( rdnAttribute, rdnValue ); |
| } |
| } |
| else |
| { |
| for ( Iterator<AttributeTypeAndValue> ii = rdn.iterator(); ii.hasNext(); /**/) |
| { |
| AttributeTypeAndValue atav = ii.next(); |
| |
| // Add the Rdn attribute |
| boolean doRdnPut = attributes.get( atav.getNormType() ) == null; |
| doRdnPut = doRdnPut || attributes.get( atav.getNormType() ).size() == 0; |
| |
| // TODO Fix DIRSERVER-832 |
| doRdnPut = doRdnPut || !attributes.get( atav.getNormType() ).contains( atav.getNormValue() ); |
| |
| if ( doRdnPut ) |
| { |
| attributes.put( atav.getNormType(), atav.getNormValue() ); |
| } |
| } |
| } |
| |
| // Add the new context to the server which as a side effect adds |
| doAddOperation( target, ServerEntryUtils.toServerEntry( attributes, target, registries ) ); |
| |
| // Initialize the new context |
| return new ServerLdapContext( getService(), getPrincipal(), target ); |
| } |
| |
| |
| /** |
| * Presently unsupported operation! |
| */ |
| public DirContext getSchema( Name name ) throws NamingException |
| { |
| throw new UnsupportedOperationException(); |
| } |
| |
| |
| /** |
| * Presently unsupported operation! |
| */ |
| public DirContext getSchema( String name ) throws NamingException |
| { |
| throw new UnsupportedOperationException(); |
| } |
| |
| |
| /** |
| * Presently unsupported operation! |
| */ |
| public DirContext getSchemaClassDefinition( Name name ) throws NamingException |
| { |
| throw new UnsupportedOperationException(); |
| } |
| |
| |
| /** |
| * Presently unsupported operation! |
| */ |
| public DirContext getSchemaClassDefinition( String name ) throws NamingException |
| { |
| throw new UnsupportedOperationException(); |
| } |
| |
| |
| // ------------------------------------------------------------------------ |
| // Search Operation Implementations |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * @see javax.naming.directory.DirContext#search(java.lang.String, |
| * javax.naming.directory.Attributes) |
| */ |
| public NamingEnumeration<SearchResult> search( String name, Attributes matchingAttributes ) throws NamingException |
| { |
| return search( new LdapDN( name ), matchingAttributes, null ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#search(javax.naming.Name, |
| * javax.naming.directory.Attributes) |
| */ |
| public NamingEnumeration<SearchResult> search( Name name, Attributes matchingAttributes ) throws NamingException |
| { |
| return search( name, AttributeUtils.toCaseInsensitive( matchingAttributes ), null ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#search(java.lang.String, |
| * javax.naming.directory.Attributes, java.lang.String[]) |
| */ |
| public NamingEnumeration<SearchResult> search( String name, Attributes matchingAttributes, |
| String[] attributesToReturn ) throws NamingException |
| { |
| return search( new LdapDN( name ), AttributeUtils.toCaseInsensitive( matchingAttributes ), attributesToReturn ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#search(javax.naming.Name, |
| * javax.naming.directory.Attributes, java.lang.String[]) |
| */ |
| public NamingEnumeration<SearchResult> search( Name name, Attributes matchingAttributes, String[] attributesToReturn ) |
| throws NamingException |
| { |
| SearchControls ctls = new SearchControls(); |
| LdapDN target = buildTarget( name ); |
| |
| // If we need to return specific attributes add em to the SearchControls |
| if ( null != attributesToReturn ) |
| { |
| ctls.setReturningAttributes( attributesToReturn ); |
| } |
| |
| // If matchingAttributes is null/empty use a match for everything filter |
| matchingAttributes = AttributeUtils.toCaseInsensitive( matchingAttributes ); |
| |
| if ( ( null == matchingAttributes ) || ( matchingAttributes.size() <= 0 ) ) |
| { |
| PresenceNode filter = new PresenceNode( SchemaConstants.OBJECT_CLASS_AT ); |
| AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() ); |
| return ServerEntryUtils.toSearchResultEnum( doSearchOperation( target, aliasDerefMode, filter, ctls ) ); |
| } |
| |
| // Handle simple filter expressions without multiple terms |
| if ( matchingAttributes.size() == 1 ) |
| { |
| NamingEnumeration<? extends Attribute> list = matchingAttributes.getAll(); |
| Attribute attr = list.next(); |
| list.close(); |
| |
| if ( attr.size() == 1 ) |
| { |
| Object value = attr.get(); |
| SimpleNode node; |
| |
| if ( value instanceof byte[] ) |
| { |
| node = new EqualityNode( attr.getID(), new ClientBinaryValue( ( byte[] ) value ) ); |
| } |
| else |
| { |
| node = new EqualityNode( attr.getID(), new ClientStringValue( ( String ) value ) ); |
| } |
| |
| AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() ); |
| return ServerEntryUtils.toSearchResultEnum( doSearchOperation( target, aliasDerefMode, node, ctls ) ); |
| } |
| } |
| |
| /* |
| * Go through the set of attributes using each attribute value pair as |
| * an attribute value assertion within one big AND filter expression. |
| */ |
| Attribute attr; |
| SimpleNode node; |
| BranchNode filter = new AndNode(); |
| NamingEnumeration<? extends Attribute> list = matchingAttributes.getAll(); |
| |
| // Loop through each attribute value pair |
| while ( list.hasMore() ) |
| { |
| attr = list.next(); |
| |
| /* |
| * According to JNDI if an attribute in the matchingAttributes |
| * list does not have any values then we match for just the presence |
| * of the attribute in the entry |
| */ |
| if ( attr.size() == 0 ) |
| { |
| filter.addNode( new PresenceNode( attr.getID() ) ); |
| continue; |
| } |
| |
| /* |
| * With 1 or more value we build a set of simple nodes and add them |
| * to the AND node - each attribute value pair is a simple AVA node. |
| */ |
| for ( int ii = 0; ii < attr.size(); ii++ ) |
| { |
| Object val = attr.get( ii ); |
| |
| // Add simpel AVA node if its value is a String |
| if ( val instanceof String ) |
| { |
| node = new EqualityNode( attr.getID(), new ClientStringValue( ( String ) val ) ); |
| filter.addNode( node ); |
| } |
| } |
| } |
| |
| AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() ); |
| return ServerEntryUtils.toSearchResultEnum( doSearchOperation( target, aliasDerefMode, filter, ctls ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#search(java.lang.String, |
| * java.lang.String, javax.naming.directory.SearchControls) |
| */ |
| public NamingEnumeration<SearchResult> search( String name, String filter, SearchControls cons ) |
| throws NamingException |
| { |
| return search( new LdapDN( name ), filter, cons ); |
| } |
| |
| |
| /** |
| * A search overload that is used for optimizing search handling in the |
| * LDAP protocol provider which deals with an ExprNode instance rather than |
| * a String for the filter. |
| * |
| * @param name the relative name of the object serving as the search base |
| * @param filter the search filter as an expression tree |
| * @param cons the search controls to use |
| * @return an enumeration over the SearchResults |
| * @throws NamingException if there are problems performing the search |
| */ |
| public NamingEnumeration<SearchResult> search( Name name, ExprNode filter, SearchControls cons ) |
| throws NamingException |
| { |
| LdapDN target = buildTarget( name ); |
| AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() ); |
| return ServerEntryUtils.toSearchResultEnum( doSearchOperation( target, aliasDerefMode, filter, cons ) ); |
| } |
| |
| |
| /** |
| * A search overload that is used for optimizing search handling in the |
| * LDAP protocol provider which deals with an ExprNode instance rather than |
| * a String for the filter. |
| * |
| * @param name the relative name of the object serving as the search base |
| * @param filter the search filter as an expression tree |
| * @param cons the search controls to use |
| * @return an enumeration over the SearchResults |
| * @throws NamingException if there are problems performing the search |
| */ |
| public NamingEnumeration<SearchResult> search( Name name, ExprNode filter, SearchControls cons, InetSocketAddress clientAddress ) |
| throws NamingException |
| { |
| LdapDN target = buildTarget( name ); |
| AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() ); |
| return ServerEntryUtils.toSearchResultEnum( doSearchOperation( target, aliasDerefMode, filter, cons, clientAddress ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#search(javax.naming.Name, |
| * java.lang.String, javax.naming.directory.SearchControls) |
| */ |
| public NamingEnumeration<SearchResult> search( Name name, String filter, SearchControls cons ) |
| throws NamingException |
| { |
| ExprNode filterNode; |
| LdapDN target = buildTarget( name ); |
| |
| try |
| { |
| filterNode = FilterParser.parse( filter ); |
| } |
| catch ( ParseException pe ) |
| { |
| InvalidSearchFilterException isfe = new InvalidSearchFilterException( |
| "Encountered parse exception while parsing the filter: '" + filter + "'" ); |
| isfe.setRootCause( pe ); |
| throw isfe; |
| } |
| |
| AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() ); |
| return ServerEntryUtils.toSearchResultEnum( doSearchOperation( target, aliasDerefMode, filterNode, cons ) ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#search(java.lang.String, |
| * java.lang.String, java.lang.Object[], |
| * javax.naming.directory.SearchControls) |
| */ |
| public NamingEnumeration<SearchResult> search( String name, String filterExpr, Object[] filterArgs, |
| SearchControls cons ) throws NamingException |
| { |
| return search( new LdapDN( name ), filterExpr, filterArgs, cons ); |
| } |
| |
| |
| /** |
| * @see javax.naming.directory.DirContext#search(javax.naming.Name, |
| * java.lang.String, java.lang.Object[], |
| * javax.naming.directory.SearchControls) |
| */ |
| public NamingEnumeration<SearchResult> search( Name name, String filterExpr, Object[] filterArgs, |
| SearchControls cons ) throws NamingException |
| { |
| int start; |
| int index; |
| |
| StringBuffer buf = new StringBuffer( filterExpr ); |
| |
| // Scan until we hit the end of the string buffer |
| for ( int ii = 0; ii < buf.length(); ii++ ) |
| { |
| try |
| { |
| // Advance until we hit the start of a variable |
| while ( ii < buf.length() && '{' != buf.charAt( ii ) ) |
| { |
| ii++; |
| } |
| |
| // Record start of variable at '{' |
| start = ii; |
| |
| // Advance to the end of a variable at '}' |
| while ( '}' != buf.charAt( ii ) ) |
| { |
| ii++; |
| } |
| } |
| catch ( IndexOutOfBoundsException e ) |
| { |
| // End of filter so done. |
| break; |
| } |
| |
| // Parse index |
| index = Integer.parseInt( buf.substring( start + 1, ii ) ); |
| |
| if ( filterArgs[index] instanceof String ) |
| { |
| /* |
| * Replace the '{ i }' with the string representation of the value |
| * held in the filterArgs array at index index. |
| */ |
| buf.replace( start, ii + 1, ( String ) filterArgs[index] ); |
| } |
| else if ( filterArgs[index] instanceof byte[] ) |
| { |
| String hexstr = "#" + StringTools.toHexString( ( byte[] ) filterArgs[index] ); |
| buf.replace( start, ii + 1, hexstr ); |
| } |
| else |
| { |
| /* |
| * Replace the '{ i }' with the string representation of the value |
| * held in the filterArgs array at index index. |
| */ |
| buf.replace( start, ii + 1, filterArgs[index].toString() ); |
| } |
| } |
| |
| return search( name, buf.toString(), cons ); |
| } |
| |
| |
| // ------------------------------------------------------------------------ |
| // EventDirContext implementations |
| // ------------------------------------------------------------------------ |
| |
| public void addNamingListener( Name name, String filterStr, SearchControls searchControls, |
| NamingListener namingListener ) throws NamingException |
| { |
| ExprNode filter; |
| |
| try |
| { |
| filter = FilterParser.parse( filterStr ); |
| } |
| catch ( Exception e ) |
| { |
| NamingException e2 = new NamingException( "could not parse filter: " + filterStr ); |
| e2.setRootCause( e ); |
| throw e2; |
| } |
| |
| ( ( PartitionNexusProxy ) getNexusProxy() ).addNamingListener( this, buildTarget( name ), filter, |
| searchControls, namingListener ); |
| getListeners().add( namingListener ); |
| } |
| |
| |
| public void addNamingListener( String name, String filter, SearchControls searchControls, |
| NamingListener namingListener ) throws NamingException |
| { |
| addNamingListener( new LdapDN( name ), filter, searchControls, namingListener ); |
| } |
| |
| |
| public void addNamingListener( Name name, String filterExpr, Object[] filterArgs, SearchControls searchControls, |
| NamingListener namingListener ) throws NamingException |
| { |
| int start; |
| StringBuffer buf = new StringBuffer( filterExpr ); |
| |
| // Scan until we hit the end of the string buffer |
| for ( int ii = 0; ii < buf.length(); ii++ ) |
| { |
| // Advance until we hit the start of a variable |
| while ( '{' != buf.charAt( ii ) ) |
| { |
| ii++; |
| } |
| |
| // Record start of variable at '{' |
| start = ii; |
| |
| // Advance to the end of a variable at '}' |
| while ( '}' != buf.charAt( ii ) ) |
| { |
| ii++; |
| } |
| |
| /* |
| * Replace the '{ i }' with the string representation of the value |
| * held in the filterArgs array at index index. |
| */ |
| buf.replace( start, ii + 1, filterArgs[ii].toString() ); |
| } |
| |
| addNamingListener( name, buf.toString(), searchControls, namingListener ); |
| } |
| |
| |
| public void addNamingListener( String name, String filter, Object[] objects, SearchControls searchControls, |
| NamingListener namingListener ) throws NamingException |
| { |
| addNamingListener( new LdapDN( name ), filter, objects, searchControls, namingListener ); |
| } |
| } |