You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by lu...@apache.org on 2014/05/10 22:04:12 UTC
svn commit: r1593724 [1/2] - in
/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client:
api/ template/ template/exception/
Author: lucastheisen
Date: Sat May 10 20:04:11 2014
New Revision: 1593724
URL: http://svn.apache.org/r1593724
Log:
DIRAPI-163: Added LdapConnectionTemplate initial implementation
Added:
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ConnectionCallback.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/EntryMapper.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionOperations.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionTemplate.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/MemoryClearingBuffer.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactory.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactoryImpl.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyOperation.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponder.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponderImpl.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarning.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarningImpl.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/RequestBuilder.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/exception/
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/exception/LdapRequestUnsuccessfulException.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/exception/LdapRuntimeException.java (with props)
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/exception/PasswordException.java (with props)
Modified:
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/DefaultLdapConnectionFactory.java
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionFactory.java
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionPool.java
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/PoolableLdapConnectionFactory.java
Modified: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/DefaultLdapConnectionFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/DefaultLdapConnectionFactory.java?rev=1593724&r1=1593723&r2=1593724&view=diff
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/DefaultLdapConnectionFactory.java (original)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/DefaultLdapConnectionFactory.java Sat May 10 20:04:11 2014
@@ -92,6 +92,13 @@ public class DefaultLdapConnectionFactor
@Override
+ public LdapApiService getLdapApiService()
+ {
+ return apiService;
+ }
+
+
+ @Override
public LdapConnection newLdapConnection() throws LdapException
{
return bindConnection( newUnboundLdapConnection() );
Modified: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionFactory.java?rev=1593724&r1=1593723&r2=1593724&view=diff
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionFactory.java (original)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionFactory.java Sat May 10 20:04:11 2014
@@ -20,6 +20,7 @@
package org.apache.directory.ldap.client.api;
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
import org.apache.directory.api.ldap.model.exception.LdapException;
@@ -66,6 +67,14 @@ public interface LdapConnectionFactory
/**
+ * Returns the LdapApiService instance used by this factory.
+ *
+ * @return The LdapApiService instance used by this factory
+ */
+ public LdapApiService getLdapApiService();
+
+
+ /**
* Returns a newly created, configured, and authenticated connection. This
* method should be used by a connection pool to manufacture the pooled
* instances.
Modified: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionPool.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionPool.java?rev=1593724&r1=1593723&r2=1593724&view=diff
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionPool.java (original)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapConnectionPool.java Sat May 10 20:04:11 2014
@@ -23,6 +23,9 @@ package org.apache.directory.ldap.client
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.directory.api.ldap.codec.api.LdapApiService;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
@@ -35,6 +38,10 @@ import org.apache.directory.api.ldap.cod
*/
public class LdapConnectionPool extends GenericObjectPool<LdapConnection>
{
+ private static Logger LOG = LoggerFactory.getLogger( LdapConnectionPool.class );
+
+ private PoolableLdapConnectionFactory factory;
+
/**
* Instantiates a new LDAP connection pool.
@@ -58,6 +65,18 @@ public class LdapConnectionPool extends
public LdapConnectionPool( PoolableLdapConnectionFactory factory )
{
super( factory );
+ this.factory = factory;
+ }
+
+
+ /**
+ * Returns the LdapApiService instance used by this connection pool.
+ *
+ * @return The LdapApiService instance used by this connection pool.
+ */
+ public LdapApiService getLdapApiService()
+ {
+ return factory.getLdapApiService();
}
@@ -67,9 +86,30 @@ public class LdapConnectionPool extends
* @return an LdapConnection object from pool
* @throws Exception if an error occurs while obtaining a connection from the factory
*/
- public LdapConnection getConnection() throws Exception
+ public LdapConnection getConnection() throws LdapException
{
- return super.borrowObject();
+ LdapConnection connection;
+ try
+ {
+ connection = super.borrowObject();
+ }
+ catch ( LdapException e )
+ {
+ throw ( e );
+ }
+ catch ( RuntimeException e )
+ {
+ throw ( e );
+ }
+ catch ( Exception e )
+ {
+ // wrap in runtime, but this should NEVER happen per published
+ // contract as it only throws what the makeObject throws and our
+ // PoolableLdapConnectionFactory only throws LdapException
+ LOG.error( "An unexpected exception was thrown: ", e );
+ throw new RuntimeException( e );
+ }
+ return connection;
}
@@ -82,19 +122,19 @@ public class LdapConnectionPool extends
* @throws Exception If an error occurs while obtaining a connection
* from the factory
*/
- public LdapConnection getUnboundConnection() throws Exception
+ public LdapConnection getUnboundConnection() throws LdapException
{
- LdapConnection connection = super.borrowObject();
+ LdapConnection connection = getConnection();
connection.unBind();
return connection;
}
- private static PoolableLdapConnectionFactory newPoolableConnectionFactory(
- LdapConnectionConfig connectionConfig, LdapApiService apiService,
+ private static PoolableLdapConnectionFactory newPoolableConnectionFactory(
+ LdapConnectionConfig connectionConfig, LdapApiService apiService,
long timeout )
{
- DefaultLdapConnectionFactory connectionFactory =
+ DefaultLdapConnectionFactory connectionFactory =
new DefaultLdapConnectionFactory( connectionConfig );
connectionFactory.setLdapApiService( apiService );
connectionFactory.setTimeOut( timeout );
@@ -108,8 +148,27 @@ public class LdapConnectionPool extends
* @param connection the LdapConnection to be released
* @throws Exception if an error occurs while releasing the connection
*/
- public void releaseConnection( LdapConnection connection ) throws Exception
+ public void releaseConnection( LdapConnection connection ) throws LdapException
{
- super.returnObject( connection );
+ try
+ {
+ super.returnObject( connection );
+ }
+ catch ( LdapException e )
+ {
+ throw ( e );
+ }
+ catch ( RuntimeException e )
+ {
+ throw ( e );
+ }
+ catch ( Exception e )
+ {
+ // wrap in runtime, but this should NEVER happen as it only throws
+ // what the passivateObject throws and our
+ // PoolableLdapConnectionFactory only throws LdapException
+ LOG.error( "An unexpected exception was thrown: ", e );
+ throw new RuntimeException( e );
+ }
}
}
Modified: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/PoolableLdapConnectionFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/PoolableLdapConnectionFactory.java?rev=1593724&r1=1593723&r2=1593724&view=diff
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/PoolableLdapConnectionFactory.java (original)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/PoolableLdapConnectionFactory.java Sat May 10 20:04:11 2014
@@ -24,6 +24,7 @@ package org.apache.directory.ldap.client
import java.io.IOException;
import org.apache.commons.pool.PoolableObjectFactory;
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.name.Dn;
@@ -68,7 +69,7 @@ public class PoolableLdapConnectionFacto
/**
* {@inheritDoc}
*/
- public void activateObject( LdapConnection connection ) throws Exception
+ public void activateObject( LdapConnection connection )
{
LOG.debug( "Activating {}", connection );
}
@@ -77,7 +78,7 @@ public class PoolableLdapConnectionFacto
/**
* {@inheritDoc}
*/
- public void destroyObject( LdapConnection connection ) throws Exception
+ public void destroyObject( LdapConnection connection )
{
LOG.debug( "Destroying {}", connection );
try {
@@ -99,9 +100,21 @@ public class PoolableLdapConnectionFacto
/**
+ * Returns the LdapApiService instance used by this factory.
+ *
+ * @return The LdapApiService instance used by this factory
+ */
+ public LdapApiService getLdapApiService()
+ {
+ return connectionFactory.getLdapApiService();
+ }
+
+
+ /**
* {@inheritDoc}
+ * @throws LdapException If unable to connect.
*/
- public LdapConnection makeObject() throws Exception
+ public LdapConnection makeObject() throws LdapException
{
LOG.debug( "Creating a LDAP connection" );
return connectionFactory.newLdapConnection();
@@ -110,8 +123,9 @@ public class PoolableLdapConnectionFacto
/**
* {@inheritDoc}
+ * @throws LdapException If unable to reconfigure and rebind.
*/
- public void passivateObject( LdapConnection connection ) throws Exception
+ public void passivateObject( LdapConnection connection ) throws LdapException
{
LOG.debug( "Passivating {}", connection );
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ConnectionCallback.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ConnectionCallback.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ConnectionCallback.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ConnectionCallback.java Sat May 10 20:04:11 2014
@@ -0,0 +1,41 @@
+/*
+ * 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.ldap.client.template;
+
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+
+/**
+ * A callback for running code against a managed {@link LdapConnection}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface ConnectionCallback<T>
+{
+ /**
+ * Provides a managed connection to the implementation of this method.
+ * The implementation is not responsible for open/close or borrow/return.
+ *
+ * @param connection The connection supplied to the implementation.
+ * @return Anything you want
+ * @throws LdapException If you want to
+ */
+ public T doWithConnection( LdapConnection connection ) throws LdapException;
+}
\ No newline at end of file
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ConnectionCallback.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/EntryMapper.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/EntryMapper.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/EntryMapper.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/EntryMapper.java Sat May 10 20:04:11 2014
@@ -0,0 +1,40 @@
+/*
+ * 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.ldap.client.template;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+
+/**
+ * A callback for processing entries from a search result.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface EntryMapper<T>
+{
+ /**
+ * Will be called once for each entry in the search result.
+ *
+ * @param entry An entry from the search result
+ * @return A object modeling the entry
+ * @throws LdapException If something goes wrong
+ */
+ public T map( Entry entry ) throws LdapException;
+}
\ No newline at end of file
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/EntryMapper.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionOperations.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionOperations.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionOperations.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionOperations.java Sat May 10 20:04:11 2014
@@ -0,0 +1,241 @@
+/*
+ * 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.ldap.client.template;
+
+
+import java.util.List;
+
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.message.AddRequest;
+import org.apache.directory.api.ldap.model.message.AddResponse;
+import org.apache.directory.api.ldap.model.message.DeleteRequest;
+import org.apache.directory.api.ldap.model.message.DeleteResponse;
+import org.apache.directory.api.ldap.model.message.ModifyRequest;
+import org.apache.directory.api.ldap.model.message.ModifyResponse;
+import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
+import org.apache.directory.api.ldap.model.message.ResultResponse;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.template.exception.LdapRequestUnsuccessfulException;
+import org.apache.directory.ldap.client.template.exception.PasswordException;
+
+
+/**
+ * Specifies the set of operations available on
+ * {@link org.apache.directory.ldap.client.template.LdapConnectionTemplate
+ * LdapConnectionTemplate}. This interface can be useful for unit testing
+ * in order to stub out methods.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface LdapConnectionOperations
+{
+
+ /**
+ * Adds an entry specified by an AddRequest to the LDAP server.
+ *
+ * @param addRequest The request
+ * @return An AddResponse
+ */
+ public abstract AddResponse add( AddRequest addRequest );
+
+
+ /**
+ * Adds an entry specified by a Dn and an array of Attribute's to the LDAP
+ * server.
+ *
+ * @param dn The distinguished name of the new entry
+ * @param attributes The attributes of the new entry
+ * @return An AddResponse
+ */
+ public abstract AddResponse add( Dn dn, Attribute... attributes );
+
+
+ /**
+ * Adds an entry specified by a Dn, to be filled out by a RequestBuilder,
+ * to the LDAP server.
+ *
+ * @param dn The distinguished name of the new entry
+ * @param requestBuilder The request builder
+ * @return An AddResponse
+ */
+ public abstract AddResponse add( Dn dn, RequestBuilder<AddRequest> requestBuilder );
+
+
+ /**
+ * Attempts to authenticate the supplied credentials. If authentication
+ * fails, a PasswordException is thrown. If successful, the response is
+ * checked for warnings, and if present, a PasswordWarning is returned.
+ * Otherwise, null is returned.
+ *
+ * @param userDn The distinguished name of the user
+ * @param password The password
+ * @return A PasswordWarning or null
+ * @throws PasswordException If authentication fails
+ */
+ public abstract PasswordWarning authenticate( Dn userDn, char[] password ) throws PasswordException;
+
+
+ /**
+ * Deletes an entry specified by a DeleteRequest from the LDAP server.
+ *
+ * @param deleteRequest The request
+ * @return A DeleteResponse
+ */
+ public abstract DeleteResponse delete( DeleteRequest deleteRequest );
+
+
+ /**
+ * Deletes an entry specified by Dn from the LDAP server.
+ *
+ * @param dn The distinguished name of the entry
+ * @return A DeleteResponse
+ */
+ public abstract DeleteResponse delete( Dn dn );
+
+
+ /**
+ * Deletes an entry specified by Dn, and whose request is configured
+ * by a RequestBuilder, from the LDAP server.
+ *
+ * @param dn The distinguished name of the entry
+ * @param requestBuilder The RequestBuilder
+ * @return A DeleteResponse
+ */
+ public abstract DeleteResponse delete( Dn dn, RequestBuilder<DeleteRequest> requestBuilder );
+
+
+ /**
+ * Executes the <code>connectionCallback</code>, supplying it a managed
+ * connection.
+ *
+ * @param connectionCallback The callback
+ * @return Whatever the callback returns
+ */
+ public abstract <T> T execute( ConnectionCallback<T> connectionCallback );
+
+
+ /**
+ * Performs a lookup, and supplies the matching entry to the
+ * <code>entryMapper</code>.
+ *
+ * @param dn The distinguished name of the entry
+ * @param entryMapper The mapper from entry to model object
+ * @return Whatever the <code>entryMapper</code> returns
+ */
+ public abstract <T> T lookup( Dn dn, EntryMapper<T> entryMapper );
+
+
+ /**
+ * Performs a lookup, requesting <code>attributes</code>, and supplies
+ * the matching entry to the <code>entryMapper</code>.
+ *
+ * @param dn The distinguished name of the entry
+ * @param attributes The attributes to be fetched
+ * @param entryMapper The mapper from entry to model object
+ * @return Whatever the <code>entryMapper</code> returns
+ */
+ public abstract <T> T lookup( Dn dn, String[] attributes, EntryMapper<T> entryMapper );
+
+
+ /**
+ * Modifies the password for <code>userDn</code> from
+ * <code>oldPassword</code> to <code>newPassword</code>, optionally using
+ * an admin account. If <code>asAdmin</code> is true, then the operation
+ * is performed in admin context which means <code>oldPassword</code> is
+ * may be <code>null</code>.
+ *
+ * @param userDn The distinguished name of the user
+ * @param oldPassword The users old password (optional if asAdmin is true)
+ * @param newPassword The users new password
+ * @param asAdmin If true, execute in admin context
+ * @throws PasswordException If the password modification fails
+ */
+ public abstract void modifyPassword( Dn userDn, char[] oldPassword, char[] newPassword,
+ boolean asAdmin ) throws PasswordException;
+
+
+ /**
+ * Modifies an entry specified by a ModifyRequest on the LDAP server.
+ *
+ * @param modifyRequest The request
+ * @return A ModifyResponse
+ */
+ public abstract ModifyResponse modify( ModifyRequest modifyRequest );
+
+
+ /**
+ * Modifies an entry specified by Dn, and whose request is configured
+ * by a RequestBuilder, on the LDAP server.
+ *
+ * @param dn The distinguished name of the entry
+ * @param requestBuilder The RequestBuilder
+ * @return A ModifyResponse
+ */
+ public abstract ModifyResponse modify( Dn dn, RequestBuilder<ModifyRequest> requestBuilder );
+
+
+ /**
+ * Checks the supplied response for its result code, and if not
+ * {@link ResultCodeEnum#SUCCESS}, an exception is thrown. This method is
+ * intened to be used inline:
+ *
+ * <pre>
+ * template.responseOrException( template.delete( dn ) );
+ * </pre>
+ *
+ * @param response The response to check for success
+ * @return The supplied <code>response</code>
+ * @throws LdapRequestUnsuccessfulException If the response is not
+ * {@link ResultCodeEnum#SUCCESS}
+ */
+ public <T extends ResultResponse> T responseOrException( T response );
+
+
+ /**
+ * Searches for the first entry matching the supplied
+ * <code>searchRequest</code>, feeding the result into the
+ * <code>entryMapper</code>. This is basically the same as
+ * {@link #search(SearchRequest, EntryMapper)}, but is optimized by
+ * modifying the <code>searchRequest</code> to set its size limit to 1.
+ * The <code>searchRequest</code> is returned to its original size limit
+ * before this method returns (or throws an exception).
+ *
+ * @param searchRequest The search request
+ * @param entryMapper The mapper
+ * @return The mapped entry
+ */
+ public abstract <T> T searchFirst( SearchRequest searchRequest,
+ EntryMapper<T> entryMapper );
+
+
+ /**
+ * Searches for the entries matching the supplied
+ * <code>searchRequest</code>, feeding the result into the
+ * <code>entryMapper</code>.
+ *
+ * @param searchRequest The search request
+ * @param entryMapper The mapper
+ * @return The mapped entries
+ */
+ public abstract <T> List<T> search( SearchRequest searchRequest,
+ EntryMapper<T> entryMapper );
+
+}
\ No newline at end of file
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionOperations.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionTemplate.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionTemplate.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionTemplate.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionTemplate.java Sat May 10 20:04:11 2014
@@ -0,0 +1,603 @@
+/*
+ * 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.ldap.client.template;
+
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.api.ldap.extras.controls.ppolicy_impl.PasswordPolicyDecorator;
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.AddRequest;
+import org.apache.directory.api.ldap.model.message.AddResponse;
+import org.apache.directory.api.ldap.model.message.BindRequest;
+import org.apache.directory.api.ldap.model.message.BindRequestImpl;
+import org.apache.directory.api.ldap.model.message.DeleteRequest;
+import org.apache.directory.api.ldap.model.message.DeleteResponse;
+import org.apache.directory.api.ldap.model.message.ModifyRequest;
+import org.apache.directory.api.ldap.model.message.ModifyRequestImpl;
+import org.apache.directory.api.ldap.model.message.ModifyResponse;
+import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
+import org.apache.directory.api.ldap.model.message.ResultResponse;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.EntryCursorImpl;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionPool;
+import org.apache.directory.ldap.client.template.exception.LdapRequestUnsuccessfulException;
+import org.apache.directory.ldap.client.template.exception.LdapRuntimeException;
+import org.apache.directory.ldap.client.template.exception.PasswordException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A facade for LDAP operations that handles all of the boiler plate code for
+ * you allowing more concise operations through the use of callbacks.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ *
+ * @see <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template method pattern</a>
+ */
+public class LdapConnectionTemplate implements LdapConnectionOperations, ModelFactory
+{
+ private static Logger logger = LoggerFactory.getLogger( LdapConnectionTemplate.class );
+
+ private LdapConnectionPool connectionPool;
+ private final PasswordPolicyDecorator passwordPolicyRequestControl;
+ private PasswordPolicyResponder passwordPolicyResponder;
+ private ModelFactory modelFactory;
+
+
+ /**
+ * Creates a new instance of LdapConnectionTemplate.
+ *
+ * @param connectionPool The pool to obtain connections from.
+ */
+ public LdapConnectionTemplate( LdapConnectionPool connectionPool )
+ {
+ this.connectionPool = connectionPool;
+ this.passwordPolicyRequestControl = new PasswordPolicyDecorator(
+ connectionPool.getLdapApiService() );
+ this.passwordPolicyResponder = new PasswordPolicyResponderImpl(
+ connectionPool.getLdapApiService() );
+ this.modelFactory = new ModelFactoryImpl();
+ }
+
+
+ @Override
+ public AddResponse add( Dn dn, final Attribute... attributes )
+ {
+ return add( dn,
+ new RequestBuilder<AddRequest>()
+ {
+ @Override
+ public void buildRequest( AddRequest request ) throws LdapException
+ {
+ request.getEntry().add( attributes );
+ }
+ } );
+ }
+
+
+ @Override
+ public AddResponse add( Dn dn, RequestBuilder<AddRequest> requestBuilder )
+ {
+ AddRequest addRequest = newAddRequest( newEntry( dn ) );
+ try
+ {
+ requestBuilder.buildRequest( addRequest );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ return add( addRequest );
+ }
+
+
+ @Override
+ public AddResponse add( AddRequest addRequest )
+ {
+ LdapConnection connection = null;
+ try
+ {
+ connection = connectionPool.getConnection();
+ return connection.add( addRequest );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ finally
+ {
+ returnLdapConnection( connection );
+ }
+ }
+
+
+ @Override
+ public PasswordWarning authenticate( Dn userDn, char[] password ) throws PasswordException
+ {
+ LdapConnection connection = null;
+ try
+ {
+ connection = connectionPool.getUnboundConnection();
+ return authenticateConnection( connection, userDn, password );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ finally
+ {
+ safeCloseLdapConnection( connection );
+ }
+ }
+
+
+ private PasswordWarning authenticateConnection( final LdapConnection connection,
+ final Dn userDn, final char[] password ) throws PasswordException
+ {
+ return passwordPolicyResponder.process(
+ new PasswordPolicyOperation()
+ {
+ @Override
+ public ResultResponse process() throws LdapException
+ {
+ MemoryClearingBuffer passwordBuffer = MemoryClearingBuffer.newInstance( password );
+ try
+ {
+ BindRequest bindRequest = new BindRequestImpl()
+ .setDn( userDn )
+ .setCredentials( passwordBuffer.getBytes() )
+ .addControl( passwordPolicyRequestControl );
+
+ return connection.bind( bindRequest );
+ }
+ finally
+ {
+ passwordBuffer.clear();
+ }
+ }
+ } );
+ }
+
+
+ @Override
+ public DeleteResponse delete( Dn dn )
+ {
+ return delete( dn, null );
+ }
+
+
+ @Override
+ public DeleteResponse delete( Dn dn, RequestBuilder<DeleteRequest> requestBuilder )
+ {
+ DeleteRequest deleteRequest = newDeleteRequest( dn );
+ if ( requestBuilder != null )
+ {
+ try
+ {
+ requestBuilder.buildRequest( deleteRequest );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ }
+ return delete( deleteRequest );
+ }
+
+
+ @Override
+ public DeleteResponse delete( DeleteRequest deleteRequest )
+ {
+ LdapConnection connection = null;
+ try
+ {
+ connection = connectionPool.getConnection();
+ return connection.delete( deleteRequest );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ finally
+ {
+ returnLdapConnection( connection );
+ }
+ }
+
+
+ @Override
+ public <T> T execute( ConnectionCallback<T> connectionCallback )
+ {
+ LdapConnection connection = null;
+ try
+ {
+ connection = connectionPool.getConnection();
+ return connectionCallback.doWithConnection( connection );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ finally
+ {
+ returnLdapConnection( connection );
+ }
+ }
+
+
+ @Override
+ public <T> T lookup( Dn dn, EntryMapper<T> entryMapper )
+ {
+ return lookup( dn, null, entryMapper );
+ }
+
+
+ @Override
+ public <T> T lookup( Dn dn, String[] attributes, EntryMapper<T> entryMapper )
+ {
+ LdapConnection connection = null;
+ try
+ {
+ connection = connectionPool.getConnection();
+ Entry entry = attributes == null
+ ? connection.lookup( dn )
+ : connection.lookup( dn, attributes );
+ return entry == null ? null : entryMapper.map( entry );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ finally
+ {
+ returnLdapConnection( connection );
+ }
+ }
+
+
+ private void modifyPassword( final LdapConnection connection, final Dn userDn,
+ final char[] newPassword ) throws PasswordException
+ {
+ passwordPolicyResponder.process(
+ new PasswordPolicyOperation()
+ {
+ @Override
+ public ResultResponse process() throws PasswordException, LdapException
+ {
+ // Can't use Password Modify:
+ // https://issues.apache.org/jira/browse/DIRSERVER-1935
+ // So revert to regular Modify
+ MemoryClearingBuffer newPasswordBuffer = MemoryClearingBuffer.newInstance( newPassword );
+ try
+ {
+ ModifyRequest modifyRequest = new ModifyRequestImpl()
+ .setName( userDn )
+ .replace( "userPassword", newPasswordBuffer.getComputedBytes() )
+ .addControl( passwordPolicyRequestControl );
+
+ return connection.modify( modifyRequest );
+ }
+ finally
+ {
+ newPasswordBuffer.clear();
+ }
+ }
+ } );
+
+ }
+
+
+ @Override
+ public void modifyPassword( Dn userDn, char[] oldPassword,
+ char[] newPassword, boolean asAdmin ) throws PasswordException
+ {
+ LdapConnection connection = null;
+ try
+ {
+ if ( asAdmin )
+ {
+ connection = connectionPool.getConnection();
+ }
+ else
+ {
+ connection = connectionPool.getUnboundConnection();
+ authenticateConnection( connection, userDn, oldPassword );
+ }
+
+ modifyPassword( connection, userDn, newPassword );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ finally
+ {
+ if ( asAdmin )
+ {
+ returnLdapConnection( connection );
+ }
+ else
+ {
+ safeCloseLdapConnection( connection );
+ }
+ }
+ }
+
+
+ @Override
+ public ModifyResponse modify( Dn dn, RequestBuilder<ModifyRequest> requestBuilder )
+ {
+ ModifyRequest modifyRequest = newModifyRequest( dn );
+ try
+ {
+ requestBuilder.buildRequest( modifyRequest );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ return modify( modifyRequest );
+ }
+
+
+ @Override
+ public ModifyResponse modify( ModifyRequest modifyRequest )
+ {
+ LdapConnection connection = null;
+ try
+ {
+ connection = connectionPool.getConnection();
+ return connection.modify( modifyRequest );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ finally
+ {
+ returnLdapConnection( connection );
+ }
+ }
+
+
+ @Override
+ public AddRequest newAddRequest( Entry entry )
+ {
+ return modelFactory.newAddRequest( entry );
+ }
+
+
+ @Override
+ public Attribute newAttribute( String name, byte[]... values )
+ {
+ return modelFactory.newAttribute( name, values );
+ }
+
+
+ @Override
+ public Attribute newAttribute( String name, String... values )
+ {
+ return modelFactory.newAttribute( name, values );
+ }
+
+
+ @Override
+ public Attribute newAttribute( String name, Value<?>... values )
+ {
+ return modelFactory.newAttribute( name, values );
+ }
+
+
+ @Override
+ public DeleteRequest newDeleteRequest( Dn dn )
+ {
+ return modelFactory.newDeleteRequest( dn );
+ }
+
+
+ @Override
+ public Dn newDn( String dn )
+ {
+ return modelFactory.newDn( dn );
+ }
+
+
+ @Override
+ public Entry newEntry( String dn )
+ {
+ return modelFactory.newEntry( dn );
+ }
+
+
+ @Override
+ public Entry newEntry( Dn dn )
+ {
+ return modelFactory.newEntry( dn );
+ }
+
+
+ @Override
+ public ModifyRequest newModifyRequest( String dn )
+ {
+ return modelFactory.newModifyRequest( dn );
+ }
+
+
+ @Override
+ public ModifyRequest newModifyRequest( Dn dn )
+ {
+ return modelFactory.newModifyRequest( dn );
+ }
+
+
+ @Override
+ public SearchRequest newSearchRequest( String baseDn, String filter, SearchScope scope )
+ {
+ return modelFactory.newSearchRequest( baseDn, filter, scope );
+ }
+
+
+ @Override
+ public SearchRequest newSearchRequest( Dn baseDn, String filter, SearchScope scope )
+ {
+ return modelFactory.newSearchRequest( baseDn, filter, scope );
+ }
+
+
+ @Override
+ public SearchRequest newSearchRequest( String baseDn, String filter, SearchScope scope, String... attributes )
+ {
+ return modelFactory.newSearchRequest( baseDn, filter, scope, attributes );
+ }
+
+
+ @Override
+ public SearchRequest newSearchRequest( Dn baseDn, String filter, SearchScope scope, String... attributes )
+ {
+ return modelFactory.newSearchRequest( baseDn, filter, scope, attributes );
+ }
+
+
+ @Override
+ public <T extends ResultResponse> T responseOrException( T response )
+ {
+ if ( ResultCodeEnum.SUCCESS != response.getLdapResult().getResultCode() )
+ {
+ throw new LdapRequestUnsuccessfulException( response );
+ }
+ return response;
+ }
+
+
+ private void returnLdapConnection( LdapConnection connection )
+ {
+ if ( connection != null )
+ {
+ try
+ {
+ connectionPool.releaseConnection( connection );
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ }
+ }
+
+
+ private void safeCloseLdapConnection( LdapConnection connection )
+ {
+ if ( connection != null )
+ {
+ try
+ {
+ connection.close();
+ }
+ catch ( IOException e )
+ {
+ logger.error( "Unable to close ldap connection, might be leaking connections:", e.getMessage() );
+ logger.debug( "Unable to close ldap connection, might be leaking connections:", e );
+ }
+ }
+ }
+
+
+ @Override
+ public <T> T searchFirst( SearchRequest searchRequest,
+ EntryMapper<T> entryMapper )
+ {
+ // in case the caller did not set size limit, we cache original value,
+ // set to 1, then set back to original value before returning...
+ long originalSizeLimit = searchRequest.getSizeLimit();
+ try
+ {
+ searchRequest.setSizeLimit( 1 );
+ List<T> entries = search( searchRequest, entryMapper );
+ return entries.isEmpty() ? null : entries.get( 0 );
+ }
+ finally
+ {
+ searchRequest.setSizeLimit( originalSizeLimit );
+ }
+ }
+
+
+ @Override
+ public <T> List<T> search( SearchRequest searchRequest,
+ EntryMapper<T> entryMapper )
+ {
+ List<T> entries = new ArrayList<T>();
+
+ LdapConnection connection = null;
+ try
+ {
+ connection = connectionPool.getConnection();
+
+ for ( Entry entry : new EntryCursorImpl( connection.search( searchRequest ) ) )
+ {
+ entries.add( entryMapper.map( entry ) );
+ }
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ finally
+ {
+ returnLdapConnection( connection );
+ }
+
+ return entries;
+ }
+
+
+ /**
+ * Sets the <code>modelFactory</code> implementation for this facade.
+ *
+ * @param modelFactory The model factory implementation
+ */
+ public void setModelFactory( ModelFactory modelFactory )
+ {
+ this.modelFactory = modelFactory;
+ }
+
+
+ /**
+ * Sets the <code>passwordPolicyResponder</code> implementation for this
+ * facade.
+ *
+ * @param passwordPolicyResponder The password policy responder
+ * implementation
+ */
+ public void setPasswordPolicyResponder( PasswordPolicyResponder passwordPolicyResponder )
+ {
+ this.passwordPolicyResponder = passwordPolicyResponder;
+ }
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/LdapConnectionTemplate.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/MemoryClearingBuffer.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/MemoryClearingBuffer.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/MemoryClearingBuffer.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/MemoryClearingBuffer.java Sat May 10 20:04:11 2014
@@ -0,0 +1,245 @@
+/*
+ * 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.ldap.client.template;
+
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+
+/**
+ * A buffer for storing sensitive information like passwords. It provides
+ * useful operations for characters such as character encoding/decoding,
+ * whitespace trimming, and lowercasing. It can be cleared out when operations
+ * are complete.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class MemoryClearingBuffer
+{
+ private static final Charset UTF8 = Charset.forName( "UTF-8" );
+ private byte[] computedBytes;
+ private char[] computedChars;
+ private byte[] originalBytes;
+ private char[] originalChars;
+ private char[] precomputedChars;
+
+
+ private MemoryClearingBuffer( byte[] originalBytes, char[] originalChars, boolean trim, boolean lowerCase )
+ {
+ this.originalBytes = originalBytes;
+ this.originalChars = originalChars;
+
+ if ( trim || lowerCase )
+ {
+ if ( this.originalChars == null )
+ {
+ throw new UnsupportedOperationException( "trim and lowerCase only applicable to char[]" );
+ }
+
+ char[] working = Arrays.copyOf( originalChars, originalChars.length );
+ int startIndex = 0;
+ int endIndex = working.length;
+
+ if ( trim )
+ {
+ // ltrim
+ for ( ; startIndex < working.length; startIndex++ )
+ {
+ if ( !Character.isWhitespace( working[startIndex] ) )
+ break;
+ }
+
+ // rtrim
+ for ( endIndex--; endIndex > startIndex; endIndex-- )
+ {
+ if ( !Character.isWhitespace( working[endIndex] ) )
+ break;
+ }
+ endIndex++;
+ }
+
+ if ( lowerCase )
+ {
+ // lower case
+ for ( int i = startIndex; i < endIndex; i++ )
+ {
+ working[i] = Character.toLowerCase( working[i] );
+ }
+ }
+
+ this.precomputedChars = new char[endIndex - startIndex];
+ System.arraycopy( working, startIndex, this.precomputedChars, 0, endIndex - startIndex );
+ }
+ else
+ {
+ this.precomputedChars = this.originalChars;
+ }
+ }
+
+
+ /**
+ * Creates a new instance of MemoryClearingBuffer from a
+ * <code>byte[]</code>.
+ *
+ * @param bytes A byte[]
+ * @return A buffer
+ */
+ public static MemoryClearingBuffer newInstance( byte[] bytes )
+ {
+ return new MemoryClearingBuffer( bytes, null, false, false );
+ }
+
+
+ /**
+ * Creates a new instance of MemoryClearingBuffer from a
+ * <code>char[]</code>.
+ *
+ * @param chars A char[]
+ * @return A buffer
+ */
+ public static MemoryClearingBuffer newInstance( char[] chars )
+ {
+ return new MemoryClearingBuffer( null, chars, false, false );
+ }
+
+
+ /**
+ * Creates a new instance of MemoryClearingBuffer from a
+ * <code>char[]</code>, optionally performing whitespace trimming and
+ * conversion to lower case.
+ *
+ * @param chars A char[]
+ * @param trim If true, whitespace will be trimmed off of both ends of the
+ * <code>char[]</code>
+ * @param lowerCase If true, the characters will be converted to lower case
+ * @return A buffer
+ */
+ public static MemoryClearingBuffer newInstance( char[] chars, boolean trim, boolean lowerCase )
+ {
+ return new MemoryClearingBuffer( null, chars, trim, lowerCase );
+ }
+
+
+ /**
+ * Clears the buffer out, filling its cells with null.
+ */
+ public void clear()
+ {
+ // clear out computed memory
+ if ( computedBytes != null )
+ {
+ Arrays.fill( computedBytes, ( byte ) 0 );
+ }
+ if ( computedChars != null )
+ {
+ Arrays.fill( computedChars, '0' );
+ }
+ if ( precomputedChars != null )
+ {
+ Arrays.fill( precomputedChars, '0' );
+ }
+
+ computedBytes = null;
+ computedChars = null;
+ originalBytes = null;
+ originalChars = null;
+ precomputedChars = null;
+ }
+
+
+ /**
+ * Returns a UTF8 encoded <code>byte[]</code> representation of the
+ * <code>char[]</code> used to create this buffer.
+ *
+ * @return A byte[]
+ */
+ byte[] getComputedBytes()
+ {
+ if ( computedBytes == null )
+ {
+ ByteBuffer byteBuffer = UTF8.encode(
+ CharBuffer.wrap( precomputedChars, 0, precomputedChars.length ) );
+ computedBytes = new byte[byteBuffer.remaining()];
+ byteBuffer.get( computedBytes );
+
+ // clear out the temporary bytebuffer
+ byteBuffer.flip();
+ byte[] nullifier = new byte[byteBuffer.limit()];
+ Arrays.fill( nullifier, ( byte ) 0 );
+ byteBuffer.put( nullifier );
+ }
+ return computedBytes;
+ }
+
+
+ /**
+ * Returns a UTF8 decoded <code>char[]</code> representation of the
+ * <code>byte[]</code> used to create this buffer.
+ *
+ * @return A char[]
+ */
+ private char[] getComputedChars()
+ {
+ if ( computedChars == null )
+ {
+ CharBuffer charBuffer = UTF8.decode(
+ ByteBuffer.wrap( originalBytes, 0, originalBytes.length ) );
+ computedChars = new char[charBuffer.remaining()];
+ charBuffer.get( computedChars );
+
+ // clear out the temporary bytebuffer
+ charBuffer.flip();
+ char[] nullifier = new char[charBuffer.limit()];
+ Arrays.fill( nullifier, ( char ) 0 );
+ charBuffer.put( nullifier );
+ }
+ return computedChars;
+ }
+
+
+ /**
+ * Returns the <code>byte[]</code> used to create this buffer, or
+ * {@link #getComputedBytes()} if created with a <code>char[]</code>.
+ *
+ * @return A byte[]
+ */
+ public byte[] getBytes()
+ {
+ return originalBytes == null
+ ? getComputedBytes()
+ : originalBytes;
+ }
+
+ /**
+ * Returns the <code>char[]</code> used to create this buffer, or
+ * {@link #getComputedChars()} if created with a <code>byte[]</code>.
+ *
+ * @return A byte[]
+ */
+ public char[] getChars()
+ {
+ return precomputedChars == null
+ ? getComputedChars()
+ : precomputedChars;
+ }
+}
\ No newline at end of file
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/MemoryClearingBuffer.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactory.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactory.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactory.java Sat May 10 20:04:11 2014
@@ -0,0 +1,85 @@
+/*
+ * 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.ldap.client.template;
+
+
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.message.AddRequest;
+import org.apache.directory.api.ldap.model.message.DeleteRequest;
+import org.apache.directory.api.ldap.model.message.ModifyRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+
+
+/**
+ * A factory for creating {@link org.apache.directory.api.ldap.model} objects.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface ModelFactory
+{
+ public AddRequest newAddRequest( Entry entry );
+
+
+ public Attribute newAttribute( String name, byte[]... values );
+
+
+ public Attribute newAttribute( String name, String... values );
+
+
+ public Attribute newAttribute( String name, Value<?>... values );
+
+
+ public DeleteRequest newDeleteRequest( Dn dn );
+
+
+ public Dn newDn( String dn );
+
+
+ public Entry newEntry( String dn );
+
+
+ public Entry newEntry( Dn dn );
+
+
+ public ModifyRequest newModifyRequest( String dn );
+
+
+ public ModifyRequest newModifyRequest( Dn dn );
+
+
+ public SearchRequest newSearchRequest( String baseDn, String filter,
+ SearchScope scope );
+
+
+ public SearchRequest newSearchRequest( Dn baseDn, String filter,
+ SearchScope scope );
+
+
+ public SearchRequest newSearchRequest( String baseDn, String filter,
+ SearchScope scope, String... attributes );
+
+
+ public SearchRequest newSearchRequest( Dn baseDn, String filter,
+ SearchScope scope, String... attributes );
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactory.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactoryImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactoryImpl.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactoryImpl.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactoryImpl.java Sat May 10 20:04:11 2014
@@ -0,0 +1,173 @@
+/*
+ * 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.ldap.client.template;
+
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.api.ldap.model.message.AddRequest;
+import org.apache.directory.api.ldap.model.message.AddRequestImpl;
+import org.apache.directory.api.ldap.model.message.DeleteRequest;
+import org.apache.directory.api.ldap.model.message.DeleteRequestImpl;
+import org.apache.directory.api.ldap.model.message.ModifyRequest;
+import org.apache.directory.api.ldap.model.message.ModifyRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.template.exception.LdapRuntimeException;
+
+
+/**
+ * The default implementation of {@link ModelFactory}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ModelFactoryImpl implements ModelFactory
+{
+ @Override
+ public AddRequest newAddRequest( Entry entry )
+ {
+ return new AddRequestImpl().setEntry( entry );
+ }
+
+
+ @Override
+ public Attribute newAttribute( String name, byte[]... values )
+ {
+ return new DefaultAttribute( name, values );
+ }
+
+
+ @Override
+ public Attribute newAttribute( String name, String... values )
+ {
+ return new DefaultAttribute( name, values );
+ }
+
+
+ @Override
+ public Attribute newAttribute( String name, Value<?>... values )
+ {
+ return new DefaultAttribute( name, values );
+ }
+
+
+ @Override
+ public DeleteRequest newDeleteRequest( Dn dn )
+ {
+ return new DeleteRequestImpl()
+ .setName( dn );
+ }
+
+
+ @Override
+ public Dn newDn( String dn )
+ {
+ try
+ {
+ return new Dn( dn );
+ }
+ catch ( LdapInvalidDnException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ }
+
+
+ @Override
+ public Entry newEntry( String dn )
+ {
+ return newEntry( newDn( dn ) );
+ }
+
+
+ @Override
+ public Entry newEntry( Dn dn )
+ {
+ return new DefaultEntry( dn );
+ }
+
+
+ @Override
+ public ModifyRequest newModifyRequest( String dn )
+ {
+ return newModifyRequest( newDn( dn ) );
+ }
+
+
+ @Override
+ public ModifyRequest newModifyRequest( Dn dn )
+ {
+ return new ModifyRequestImpl().setName( dn );
+ }
+
+
+ @Override
+ public SearchRequest newSearchRequest( String baseDn, String filter,
+ SearchScope scope )
+ {
+ return newSearchRequest( newDn( baseDn ), filter, scope );
+ }
+
+
+ @Override
+ public SearchRequest newSearchRequest( Dn baseDn, String filter,
+ SearchScope scope )
+ {
+ return newSearchRequest( baseDn, filter, scope, ( String[] ) null );
+ }
+
+
+ @Override
+ public SearchRequest newSearchRequest( String baseDn, String filter,
+ SearchScope scope, String... attributes )
+ {
+ return newSearchRequest( newDn( baseDn ), filter, scope, attributes );
+ }
+
+
+ @Override
+ public SearchRequest newSearchRequest( Dn baseDn, String filter,
+ SearchScope scope, String... attributes )
+ {
+ SearchRequest searchRequest = null;
+ try
+ {
+ searchRequest = new SearchRequestImpl()
+ .setBase( baseDn )
+ .setFilter( filter )
+ .setScope( scope == null ? SearchScope.OBJECT : scope );
+ if ( attributes != null && attributes.length > 0 )
+ {
+ searchRequest.addAttributes( attributes );
+ }
+ }
+ catch ( LdapException e )
+ {
+ throw new LdapRuntimeException( e );
+ }
+ return searchRequest;
+ }
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/ModelFactoryImpl.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyOperation.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyOperation.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyOperation.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyOperation.java Sat May 10 20:04:11 2014
@@ -0,0 +1,46 @@
+/*
+ * 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.ldap.client.template;
+
+
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.ResultResponse;
+import org.apache.directory.ldap.client.template.exception.PasswordException;
+
+
+/**
+ * An callback for processing requests whose success/failure imply some sort
+ * of password policy information.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface PasswordPolicyOperation
+{
+ /**
+ * Execute operations whose results imply somme sort of password policy
+ * information.
+ *
+ * @return The final response of the operation
+ * @throws PasswordException If there was a failure for a password policy
+ * reason
+ * @throws LdapException If there was an general ldap failure
+ */
+ public ResultResponse process() throws PasswordException, LdapException;
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyOperation.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponder.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponder.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponder.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponder.java Sat May 10 20:04:11 2014
@@ -0,0 +1,49 @@
+/*
+ * 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.ldap.client.template;
+
+
+import org.apache.directory.ldap.client.template.exception.PasswordException;
+
+
+/**
+ * A class for translating the outcome of a {@link PasswordPolicyOperation}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface PasswordPolicyResponder
+{
+ /**
+ * Execute the <code>operation</code> and translate the outcome as follows:
+ *
+ * <ul>
+ * <li>SUCCESS: return null</li>
+ * <li>WARNING: return {@link PasswordWarning}</li>
+ * <li>FAILURE: throw {@link PasswordException}</li>
+ * </ul>
+ *
+ * @param operation An operation whose outcome implies password policy
+ * information
+ * @return A <code>PasswordWarning</code> if warnings are present, or null
+ * if completely successful.
+ * @throws PasswordException If the <code>operation</code> was a failure.
+ */
+ public PasswordWarning process( PasswordPolicyOperation operation ) throws PasswordException;
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponder.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponderImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponderImpl.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponderImpl.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponderImpl.java Sat May 10 20:04:11 2014
@@ -0,0 +1,96 @@
+/*
+ * 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.ldap.client.template;
+
+
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
+import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicy;
+import org.apache.directory.api.ldap.extras.controls.ppolicy_impl.PasswordPolicyDecorator;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.Control;
+import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
+import org.apache.directory.api.ldap.model.message.ResultResponse;
+import org.apache.directory.ldap.client.template.exception.PasswordException;
+
+
+/**
+ * The default implementation of {@link PasswordPolicyResponder}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class PasswordPolicyResponderImpl implements PasswordPolicyResponder
+{
+ private final PasswordPolicyDecorator passwordPolicyRequestControl;
+
+
+ public PasswordPolicyResponderImpl( LdapApiService ldapApiService )
+ {
+ this.passwordPolicyRequestControl = new PasswordPolicyDecorator(
+ ldapApiService );
+ }
+
+
+ private PasswordPolicy getPasswordPolicy( Response response )
+ {
+ Control control = response.getControls().get( passwordPolicyRequestControl.getOid() );
+ return control == null
+ ? null
+ : ( ( PasswordPolicyDecorator ) control ).getDecorated();
+ }
+
+
+ @Override
+ public PasswordWarning process( PasswordPolicyOperation operation )
+ throws PasswordException
+ {
+ try
+ {
+ ResultResponse response = operation.process();
+ PasswordPolicy passwordPolicy = getPasswordPolicy( response );
+
+ ResultCodeEnum resultCode = response.getLdapResult().getResultCode();
+ if ( resultCode == ResultCodeEnum.SUCCESS )
+ {
+ if ( passwordPolicy != null )
+ {
+ return PasswordWarningImpl.newWarning( passwordPolicy );
+ }
+ return null;
+ }
+ else
+ {
+ PasswordException exception = new PasswordException();
+ exception.setResultCode( resultCode );
+ if ( passwordPolicy != null
+ && passwordPolicy.getResponse() != null
+ && passwordPolicy.getResponse().getPasswordPolicyError() != null )
+ {
+ exception.setPasswordPolicyError( passwordPolicy.getResponse().getPasswordPolicyError() );
+ }
+ throw exception;
+ }
+ }
+ catch ( LdapException e )
+ {
+ throw new PasswordException().setLdapException( e );
+ }
+ }
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordPolicyResponderImpl.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarning.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarning.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarning.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarning.java Sat May 10 20:04:11 2014
@@ -0,0 +1,56 @@
+/*
+ * 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.ldap.client.template;
+
+
+import java.io.Serializable;
+
+
+/**
+ * A container for password warning information.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface PasswordWarning extends Serializable
+{
+ /**
+ * Returns the number of seconds before the password will expire.
+ *
+ * @return The number of seconds before the password will expire
+ */
+ public int getTimeBeforeExpiration();
+
+
+ /**
+ * Returns the number of remaining authentications before the account will
+ * be locked.
+ *
+ * @return The number of authentications before lockout
+ */
+ public int getGraceAuthNsRemaining();
+
+
+ /**
+ * Returns true, if a password reset is required.
+ *
+ * @return True, if a password reset is required
+ */
+ public boolean isChangeAfterReset();
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarning.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarningImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarningImpl.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarningImpl.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarningImpl.java Sat May 10 20:04:11 2014
@@ -0,0 +1,89 @@
+/*
+ * 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.ldap.client.template;
+
+
+import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicy;
+import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyErrorEnum;
+import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyResponse;
+
+
+/**
+ * The default implementation of {@link PasswordWarning}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+class PasswordWarningImpl implements PasswordWarning
+{
+ private static final long serialVersionUID = -8952246313604352357L;
+
+ private int timeBeforeExpiration = -1;
+ private int graceAuthNsRemaining = -1;
+ private boolean changeAfterReset = false;
+
+
+ private PasswordWarningImpl()
+ {
+ }
+
+
+ public static PasswordWarning newWarning( PasswordPolicy policy )
+ {
+ PasswordPolicyResponse response = policy.getResponse();
+ if ( response != null )
+ {
+ PasswordWarningImpl policyWarning = new PasswordWarningImpl();
+ policyWarning.timeBeforeExpiration = response.getTimeBeforeExpiration();
+ policyWarning.graceAuthNsRemaining = response.getGraceAuthNRemaining();
+ policyWarning.changeAfterReset = response.getPasswordPolicyError() ==
+ PasswordPolicyErrorEnum.CHANGE_AFTER_RESET;
+
+ if ( policyWarning.timeBeforeExpiration >= 0 || policyWarning.graceAuthNsRemaining >= 0
+ || policyWarning.changeAfterReset )
+ {
+ // it actually is a warning!
+ return policyWarning;
+ }
+ }
+ return null;
+ }
+
+
+ @Override
+ public int getTimeBeforeExpiration()
+ {
+ return timeBeforeExpiration;
+ }
+
+
+ @Override
+ public int getGraceAuthNsRemaining()
+ {
+ return graceAuthNsRemaining;
+ }
+
+
+ @Override
+ public boolean isChangeAfterReset()
+ {
+ return changeAfterReset;
+ }
+}
\ No newline at end of file
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/PasswordWarningImpl.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/RequestBuilder.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/RequestBuilder.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/RequestBuilder.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/RequestBuilder.java Sat May 10 20:04:11 2014
@@ -0,0 +1,44 @@
+/*
+ * 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.ldap.client.template;
+
+
+import org.apache.directory.api.ldap.model.exception.LdapException;
+
+
+/**
+ * Edits a supplied request adding specifics.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface RequestBuilder<T>
+{
+ /**
+ * Modifies the provided request adding specific information to it.
+ * The supplied request is typically a factory built request with just
+ * its Dn set. It is the responsibility of this method to fill in all
+ * of the details. The request will be sent to the LDAP server upon
+ * upon returning from this method.
+ *
+ * @param request The request to be modified
+ * @throws LdapException If something goes wrong
+ */
+ public void buildRequest( T request ) throws LdapException;
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/RequestBuilder.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/exception/LdapRequestUnsuccessfulException.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/exception/LdapRequestUnsuccessfulException.java?rev=1593724&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/exception/LdapRequestUnsuccessfulException.java (added)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/exception/LdapRequestUnsuccessfulException.java Sat May 10 20:04:11 2014
@@ -0,0 +1,51 @@
+/*
+ * 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.ldap.client.template.exception;
+
+
+import org.apache.directory.api.ldap.model.message.ResultResponse;
+
+
+/**
+ * An RuntimeException wrapper class that allows the user to choose to have
+ * unsuccessful responses thrown as exceptions rather than checking the
+ * response itself for process flow.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class LdapRequestUnsuccessfulException extends RuntimeException
+{
+ private static final long serialVersionUID = 1982294624076306127L;
+
+ private ResultResponse response;
+
+
+ public LdapRequestUnsuccessfulException( ResultResponse response )
+ {
+ super();
+ }
+
+
+ public ResultResponse getResponse()
+ {
+ return response;
+ }
+
+}
Propchange: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/template/exception/LdapRequestUnsuccessfulException.java
------------------------------------------------------------------------------
svn:executable = *