You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2004/10/27 18:04:17 UTC
svn commit: rev 55711 - in incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve: . db jndi/ibs
Author: akarasulu
Date: Wed Oct 27 09:04:14 2004
New Revision: 55711
Added:
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ResultFilter.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ResultFilteringEnumeration.java
Modified:
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/AbstractContextPartition.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/BackingStore.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/PartitionNexus.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/RootNexus.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java
Log:
Changes ...
o moved the lookup(Name,String[]) overload back into the BackingStore; this
was done because some stores might optimize the values returned instead
of returning all values; plus this is really a backing store operation
o implemented lookup(Name,String[]) since it was throwing a NotImpl except.
o added the concept of a database search result filter for filtering and
transforming result attributes and values on the way back to the caller
o added a decorator which applies result filters to enumerations over
database search reasults
o used this new filtering enumeration decorator within the OpAttr interceptor
service to wrap the search NamingEnumeration return value; this way the
OpAttr interceptor service can filter operational attributes in the result
being returned to the caller
Todos ...
o we still need to thoroughly test this code
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/AbstractContextPartition.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/AbstractContextPartition.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/AbstractContextPartition.java Wed Oct 27 09:04:14 2004
@@ -28,9 +28,11 @@
import javax.naming.directory.SearchControls;
import javax.naming.ContextNotEmptyException;
import javax.naming.directory.ModificationItem;
+import javax.naming.directory.Attribute;
import org.apache.ldap.common.filter.ExprNode;
import org.apache.ldap.common.schema.AttributeType;
+import org.apache.ldap.common.message.LockableAttributesImpl;
import org.apache.eve.db.Database;
import org.apache.eve.db.SearchEngine;
@@ -298,6 +300,33 @@
public Attributes lookup( Name dn ) throws NamingException
{
return db.lookup( db.getEntryId( dn.toString() ) );
+ }
+
+
+ /**
+ * @see BackingStore#lookup(Name,String[])
+ */
+ public Attributes lookup( Name dn, String [] attrIds ) throws NamingException
+ {
+ if ( attrIds == null || attrIds.length == 0 )
+ {
+ return lookup( dn );
+ }
+
+ Attributes entry = lookup( dn );
+ Attributes retval = new LockableAttributesImpl();
+
+ for ( int ii = 0; ii < attrIds.length; ii++ )
+ {
+ Attribute attr = entry.get( attrIds[0] );
+
+ if ( attr != null )
+ {
+ retval.put( attr );
+ }
+ }
+
+ return retval;
}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/BackingStore.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/BackingStore.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/BackingStore.java Wed Oct 27 09:04:14 2004
@@ -137,6 +137,19 @@
Attributes lookup( Name name ) throws NamingException;
/**
+ * Looks up an entry by distinguished name. This is a simplified version
+ * of the search operation used to point read an entry used for convenience
+ * with a set of attributes to return. If the attributes are null or emty
+ * this defaults to the lookup opertion without the attributes.
+ *
+ * @param dn the normalized distinguished name of the object to lookup
+ * @param attrIds the set of attributes to return
+ * @return an Attributes object representing the entry
+ * @throws NamingException if there are any problems
+ */
+ Attributes lookup( Name dn, String [] attrIds ) throws NamingException;
+
+ /**
* Fast operation to check and see if a particular entry exists.
*
* @param name the normalized distinguished/absolute name of the object to
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/PartitionNexus.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/PartitionNexus.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/PartitionNexus.java Wed Oct 27 09:04:14 2004
@@ -22,7 +22,6 @@
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.ldap.LdapContext;
-import javax.naming.directory.Attributes;
/**
@@ -94,25 +93,6 @@
* @throws NamingException if there are any problems
*/
Iterator listSuffixes( boolean normalized ) throws NamingException;
-
- /**
- * Looks up an entry by distinguished name. This is a simplified version
- * of the search operation used to point read an entry used for convenience
- * with a set of attributes to return. If the attributes are null or emty
- * this defaults to the lookup opertion without the attributes.
- *
- * NOTE: This method is here in the nexus and not within the Backend
- * interface. This is due to the fact that attribute selection by name
- * using the second parameter attrIds will be implemented after the call
- * to a backend. Hence selection of the correct set of attributes to return
- * is not a responsibility of a Backend module.
- *
- * @param dn the normalized distinguished name of the object to lookup
- * @param attrIds the set of attributes to return
- * @return an Attributes object representing the entry
- * @throws NamingException if there are any problems
- */
- Attributes lookup( Name dn, String [] attrIds ) throws NamingException;
/**
* Registers an ContextPartition with this BackendManager. Called by each
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/RootNexus.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/RootNexus.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/RootNexus.java Wed Oct 27 09:04:14 2004
@@ -220,21 +220,22 @@
/**
- * @see BackingStore#lookup(Name)
+ * @see BackingStore#lookup(javax.naming.Name)
*/
- public Attributes lookup( Name dn, String [] attrIds ) throws NamingException
+ public Attributes lookup( Name dn ) throws NamingException
{
- throw new NotImplementedException();
+ ContextPartition backend = getBackend( dn );
+ return backend.lookup( dn );
}
/**
- * @see BackingStore#lookup(javax.naming.Name)
+ * @see BackingStore#lookup(javax.naming.Name, String[])
*/
- public Attributes lookup( Name dn ) throws NamingException
+ public Attributes lookup( Name dn, String[] attrIds ) throws NamingException
{
ContextPartition backend = getBackend( dn );
- return backend.lookup( dn );
+ return backend.lookup( dn, attrIds );
}
Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ResultFilter.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ResultFilter.java Wed Oct 27 09:04:14 2004
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.eve.db;
+
+
+import javax.naming.NamingException;
+
+
+/**
+ * A filter is used to modify search results while they are being returned from
+ * naming enumerations containing DbSearchResults. These filters are used in
+ * conjunction with a {@link ResultFilteringEnumeration}. Multiple filters can
+ * be applied one after the other and hence they are stackable.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public interface ResultFilter
+{
+ /**
+ * Filters the contents of search results on the way out the door to client
+ * callers. These filters can and do produce side-effects on the results if
+ * if need be the attributes or names within the result should be cloned.
+ *
+ * @return true if the result is to be returned, false if it is to be
+ * discarded from the result set
+ */
+ boolean accept( DbSearchResult result ) throws NamingException;
+}
Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ResultFilteringEnumeration.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ResultFilteringEnumeration.java Wed Oct 27 09:04:14 2004
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.eve.db;
+
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+
+
+/**
+ * A enumeration decorator which filters database search results as they are
+ * being enumerated back to the client caller.
+ *
+ * @see ResultFilter
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class ResultFilteringEnumeration implements NamingEnumeration
+{
+ /** the list of filters to be applied */
+ private final ArrayList filters;
+ /** the underlying decorated enumeration */
+ private final NamingEnumeration decorated;
+
+ /** the first accepted search result that is prefetched */
+ private DbSearchResult prefetched;
+ /** flag storing closed state of this naming enumeration */
+ private boolean isClosed = false;
+
+
+ // ------------------------------------------------------------------------
+ // C O N S T R U C T O R S
+ // ------------------------------------------------------------------------
+
+
+ /**
+ * Creates a new database result filtering enumeration to decorate an
+ * underlying enumeration.
+ *
+ * @param decorated the underlying decorated enumeration
+ */
+ public ResultFilteringEnumeration( NamingEnumeration decorated )
+ throws NamingException
+ {
+ this.filters = new ArrayList();
+ this.decorated = decorated;
+
+ if ( ! decorated.hasMore() )
+ {
+ close();
+ return;
+ }
+
+ prefetch();
+ }
+
+
+ // ------------------------------------------------------------------------
+ // New ResultFilter management methods
+ // ------------------------------------------------------------------------
+
+
+ /**
+ * Adds a database search result filter to this filtering enumeration at
+ * the very end of the filter list. Filters are applied in the order of
+ * addition.
+ *
+ * @param filter a filter to apply to the results
+ * @return the result of {@link List#add(Object)}
+ */
+ public boolean addResultFilter( ResultFilter filter )
+ {
+ return filters.add( filter );
+ }
+
+
+ /**
+ * Removes a database search result filter from the filter list of this
+ * filtering enumeration.
+ *
+ * @param filter a filter to remove from the filter list
+ * @return the result of {@link List#remove(Object)}
+ */
+ public boolean removeResultFilter( ResultFilter filter )
+ {
+ return filters.remove( filter );
+ }
+
+
+ /**
+ * Gets an unmodifiable list of filters.
+ *
+ * @return the result of {@link Collections#unmodifiableList(List)}
+ */
+ public List getFilters()
+ {
+ return Collections.unmodifiableList( filters );
+ }
+
+
+ // ------------------------------------------------------------------------
+ // NamingEnumeration Methods
+ // ------------------------------------------------------------------------
+
+
+ public void close() throws NamingException
+ {
+ isClosed = true;
+ decorated.close();
+ }
+
+
+ public boolean hasMore()
+ {
+ return !isClosed;
+ }
+
+
+ public Object next() throws NamingException
+ {
+ DbSearchResult retVal = this.prefetched;
+ prefetch();
+ return retVal;
+ }
+
+
+ // ------------------------------------------------------------------------
+ // Enumeration Methods
+ // ------------------------------------------------------------------------
+
+
+ public boolean hasMoreElements()
+ {
+ return !isClosed;
+ }
+
+
+ public Object nextElement()
+ {
+ DbSearchResult retVal = this.prefetched;
+
+ try
+ {
+ prefetch();
+ }
+ catch ( NamingException e )
+ {
+ e.printStackTrace();
+ }
+
+ return retVal;
+ }
+
+
+ // ------------------------------------------------------------------------
+ // Private utility methods
+ // ------------------------------------------------------------------------
+
+
+ /**
+ * Keeps getting results from the underlying decorated filter and applying
+ * the filters until a result is accepted by all and set as the prefetced
+ * result to return on the next() result request. If no prefetched value
+ * can be found before exhausting the decorated enumeration, then this and
+ * the underlying enumeration is closed.
+ *
+ * @throws NamingException if there are problems getting results from the
+ * underlying enumeration
+ */
+ private void prefetch() throws NamingException
+ {
+ DbSearchResult tmp = null;
+
+ while( decorated.hasMore() )
+ {
+ boolean accepted = true;
+ tmp = ( DbSearchResult ) decorated.next();
+
+ // don't waste using a for loop if we got 0 or 1 element
+ if ( filters.isEmpty() )
+ {
+ this.prefetched = tmp;
+ return;
+ }
+ else if ( filters.size() == 1 )
+ {
+ accepted = ( ( ResultFilter ) filters.get( 0 ) ).accept( tmp );
+ this.prefetched = tmp;
+ return;
+ }
+
+ // apply all filters shorting their application on result denials
+ for ( int ii = 0; ii < filters.size(); ii ++ )
+ {
+ ResultFilter filter = ( ResultFilter ) filters.get( ii );
+ accepted &= filter.accept( tmp );
+
+ if ( ! accepted )
+ {
+ continue;
+ }
+ }
+
+ /*
+ * If we get here then a result has been accepted by all the
+ * filters so we set the result as the prefetched value to return
+ * on the following call to the next() or nextElement() methods
+ */
+ this.prefetched = tmp;
+ return;
+ }
+
+ /*
+ * If we get here then no result was found to be accepted by all
+ * filters before we exhausted the decorated enumeration so we close
+ */
+ close();
+ }
+}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java Wed Oct 27 09:04:14 2004
@@ -17,18 +17,23 @@
package org.apache.eve.jndi.ibs;
+import java.util.Map;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.Context;
import javax.naming.directory.*;
import org.apache.eve.RootNexus;
+import org.apache.eve.db.SearchResultEnumeration;
+import org.apache.eve.db.DbSearchResult;
+import org.apache.eve.db.ResultFilteringEnumeration;
+import org.apache.eve.db.ResultFilter;
import org.apache.eve.jndi.Invocation;
import org.apache.eve.jndi.BaseInterceptor;
import org.apache.eve.jndi.InvocationStateEnum;
-import org.apache.eve.schema.AttributeTypeRegistry;
import org.apache.ldap.common.util.DateUtils;
+import org.apache.ldap.common.filter.ExprNode;
/**
@@ -60,9 +65,6 @@
/**
* Adds extra operational attributes to the entry before it is added.
*
- * @todo add mechanism to find the identity of the caller so we can
- * properly set the owner/modifier of the entry
- *
* @see BaseInterceptor#add(String, Name, Attributes)
*/
protected void add( String upName, Name normName, Attributes entry ) throws NamingException
@@ -171,7 +173,8 @@
}
- protected void move( Name oriChildName, Name newParentName, String newRdn, boolean deleteOldRdn ) throws NamingException
+ protected void move( Name oriChildName, Name newParentName, String newRdn,
+ boolean deleteOldRdn ) throws NamingException
{
Invocation invocation = getInvocation();
@@ -189,6 +192,57 @@
nexus.modify( newParentName, DirContext.REPLACE_ATTRIBUTE, attributes );
}
+ }
+
+
+ protected void lookup( Name dn ) throws NamingException
+ {
+ Invocation invocation = getInvocation();
+
+ if ( invocation.getState() == InvocationStateEnum.POSTINVOCATION )
+ {
+ filter( ( Attributes ) invocation.getReturnValue() );
+ }
+ }
+
+
+ protected void search( Name base, Map env, ExprNode filter,
+ SearchControls searchControls )
+ throws NamingException
+ {
+ Invocation invocation = getInvocation();
+
+ if ( invocation.getState() == InvocationStateEnum.POSTINVOCATION )
+ {
+ SearchResultEnumeration enum ;
+ ResultFilteringEnumeration retval;
+ enum = ( SearchResultEnumeration ) invocation.getReturnValue();
+ retval = new ResultFilteringEnumeration( enum );
+ retval.addResultFilter( new ResultFilter() {
+ public boolean accept( DbSearchResult result )
+ {
+ return filter( result.getAttributes() );
+ }
+ } );
+ invocation.setReturnValue( retval );
+ }
+ }
+
+
+ /**
+ * Filters out the operational attributes within a search results
+ * attributes. The attributes are directly modified.
+ *
+ * @param attributes the resultant attributes to filter
+ * @return true always
+ */
+ private boolean filter( Attributes attributes )
+ {
+ attributes.remove( "creatorsName" );
+ attributes.remove( "modifiersName" );
+ attributes.remove( "createTimestamp" );
+ attributes.remove( "modifyTimestamp" );
+ return true;
}