You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2014/03/26 17:53:18 UTC

svn commit: r1581932 - in /directory/shared/trunk/ldap: codec/standalone/src/main/java/org/apache/directory/api/ldap/codec/standalone/ codec/standalone/src/test/java/org/apache/directory/api/ldap/codec/standalone/ extras/codec-api/src/main/java/org/apa...

Author: elecharny
Date: Wed Mar 26 16:53:17 2014
New Revision: 1581932

URL: http://svn.apache.org/r1581932
Log:
o Added the support for the WhoAmI extended operation

Added:
    directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/
    directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequest.java
    directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequestImpl.java
    directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponse.java
    directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponseImpl.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIFactory.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIRequestDecorator.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseContainer.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecoder.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecorator.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseGrammar.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseStatesEnum.java
    directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/
    directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseTest.java
Modified:
    directory/shared/trunk/ldap/codec/standalone/src/main/java/org/apache/directory/api/ldap/codec/standalone/CodecFactoryUtil.java
    directory/shared/trunk/ldap/codec/standalone/src/test/java/org/apache/directory/api/ldap/codec/standalone/AbstractCodecServiceTest.java
    directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/ExtrasBundleActivator.java

Modified: directory/shared/trunk/ldap/codec/standalone/src/main/java/org/apache/directory/api/ldap/codec/standalone/CodecFactoryUtil.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/codec/standalone/src/main/java/org/apache/directory/api/ldap/codec/standalone/CodecFactoryUtil.java?rev=1581932&r1=1581931&r2=1581932&view=diff
==============================================================================
--- directory/shared/trunk/ldap/codec/standalone/src/main/java/org/apache/directory/api/ldap/codec/standalone/CodecFactoryUtil.java (original)
+++ directory/shared/trunk/ldap/codec/standalone/src/main/java/org/apache/directory/api/ldap/codec/standalone/CodecFactoryUtil.java Wed Mar 26 16:53:17 2014
@@ -49,6 +49,7 @@ import org.apache.directory.api.ldap.ext
 import org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulShutdown.GracefulShutdownFactory;
 import org.apache.directory.api.ldap.extras.extended.ads_impl.pwdModify.PasswordModifyFactory;
 import org.apache.directory.api.ldap.extras.extended.ads_impl.storedProcedure.StoredProcedureFactory;
+import org.apache.directory.api.ldap.extras.extended.ads_impl.whoAmI.WhoAmIFactory;
 import org.apache.directory.api.ldap.model.message.controls.Cascade;
 import org.apache.directory.api.ldap.model.message.controls.EntryChange;
 import org.apache.directory.api.ldap.model.message.controls.ManageDsaIT;
@@ -156,5 +157,9 @@ public class CodecFactoryUtil
         PasswordModifyFactory passwordModifyFactory = new PasswordModifyFactory( apiService );
         extendendOperationsFactories.put( passwordModifyFactory.getOid(), passwordModifyFactory );
         LOG.info( "Registered pre-bundled extended operation factory: {}", passwordModifyFactory.getOid() );
+
+        WhoAmIFactory whoAmIFactory = new WhoAmIFactory( apiService );
+        extendendOperationsFactories.put( whoAmIFactory.getOid(), whoAmIFactory );
+        LOG.info( "Registered pre-bundled extended operation factory: {}", whoAmIFactory.getOid() );
     }
 }

Modified: directory/shared/trunk/ldap/codec/standalone/src/test/java/org/apache/directory/api/ldap/codec/standalone/AbstractCodecServiceTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/codec/standalone/src/test/java/org/apache/directory/api/ldap/codec/standalone/AbstractCodecServiceTest.java?rev=1581932&r1=1581931&r2=1581932&view=diff
==============================================================================
--- directory/shared/trunk/ldap/codec/standalone/src/test/java/org/apache/directory/api/ldap/codec/standalone/AbstractCodecServiceTest.java (original)
+++ directory/shared/trunk/ldap/codec/standalone/src/test/java/org/apache/directory/api/ldap/codec/standalone/AbstractCodecServiceTest.java Wed Mar 26 16:53:17 2014
@@ -67,7 +67,8 @@ public abstract class AbstractCodecServi
                 "org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulShutdown.GracefulShutdownFactory," +
                 "org.apache.directory.api.ldap.extras.extended.ads_impl.storedProcedure.StoredProcedureFactory," +
                 "org.apache.directory.api.ldap.extras.extended.ads_impl.pwdModify.PasswordModifyFactory," +
-                "org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulDisconnectFactory" );
+                "org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulDisconnectFactory" +
+                "org.apache.directory.api.ldap.extras.extended.ads_impl.whoAmI.WhoAmIFactory" );
 
         codec = LdapApiServiceFactory.getSingleton();
         encoder = new LdapEncoder( codec );

Added: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequest.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequest.java (added)
+++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequest.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,35 @@
+/*
+ *  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.api.ldap.extras.extended.whoAmI;
+
+
+import org.apache.directory.api.ldap.model.message.ExtendedRequest;
+
+
+/**
+ * The RFC 4532 WhoAmI request
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface WhoAmIRequest extends ExtendedRequest
+{
+    /** The OID for the WhoAmI extended operation request. */
+    String EXTENSION_OID = "1.3.6.1.4.1.4203.1.11.3";
+}

Added: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequestImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequestImpl.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequestImpl.java (added)
+++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIRequestImpl.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,76 @@
+/*
+ *  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.api.ldap.extras.extended.whoAmI;
+
+
+import org.apache.directory.api.ldap.model.message.AbstractExtendedRequest;
+
+
+/**
+ * The RFC 4532 WhoAmI request
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class WhoAmIRequestImpl extends AbstractExtendedRequest implements WhoAmIRequest
+{
+    /**
+     * Create a new instance of the PwdModifyRequest extended operation
+     */
+    public WhoAmIRequestImpl()
+    {
+        setRequestName( EXTENSION_OID );
+    }
+
+
+    /**
+     * Create a new instance of the PwdModifyRequest extended operation
+     * 
+     * @param messageId The message ID
+     */
+    public WhoAmIRequestImpl( int messageId )
+    {
+        super( messageId );
+        setRequestName( EXTENSION_OID );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public WhoAmIResponse getResultResponse()
+    {
+        if ( response == null )
+        {
+            response = new WhoAmIResponseImpl( getMessageId() );
+        }
+
+        return ( WhoAmIResponse ) response;
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        return "Who Am I extended request";
+    }
+}

Added: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponse.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponse.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponse.java (added)
+++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponse.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,92 @@
+/*
+ *  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.api.ldap.extras.extended.whoAmI;
+
+
+import org.apache.directory.api.ldap.model.message.ExtendedResponse;
+import org.apache.directory.api.ldap.model.name.Dn;
+
+
+/**
+ * The RFC 4532 WhoAmI response :
+ * 
+ * <pre>
+ * authzid ::= OCTET STRING OPTIONAL
+ * </pre>
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface WhoAmIResponse extends ExtendedResponse
+{
+    /** The OID for the WhoAmI extended operation response. */
+    String EXTENSION_OID = WhoAmIRequest.EXTENSION_OID;
+
+    
+    /**
+     * @return true if the response contains a DN authz (dn:XXX)
+     */
+    boolean isDnAuthzId();
+    
+    
+    /**
+     * @return true if the response contains a userID authz (u:XXX)
+     */
+    boolean isUserAuthzId();
+    
+
+    /**
+     * Get the authzid as a byte[]
+     * 
+     * @return The authzid or null
+     */
+    byte[] getAuthzId();
+
+
+    /**
+     * Get the authzid as String. We will strip out the 'dn:' or 'u:' part.
+     * 
+     * @return The authzid or null
+     */
+    String getAuthzIdString();
+
+
+    /**
+     * Get the UserId
+     * 
+     * @return The userId or null
+     */
+    String getUserId();
+
+
+    /**
+     * Get the DN authzid.
+     * 
+     * @return The DN or null
+     */
+    Dn getDn();
+
+
+    /**
+     * set the authzid
+     * 
+     * @param The authzid to set
+     */
+    void setAuthzId( byte[] authzId );
+}

Added: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponseImpl.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponseImpl.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponseImpl.java (added)
+++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/extended/whoAmI/WhoAmIResponseImpl.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,220 @@
+/*
+ *  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.api.ldap.extras.extended.whoAmI;
+
+
+import org.apache.directory.api.ldap.model.message.ExtendedResponseImpl;
+import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.util.Strings;
+
+
+/**
+ * The RFC 4532 WhoAmI response :
+ * 
+ * <pre>
+ * authzid OCTET STRING OPTIONAL
+ * </pre>
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class WhoAmIResponseImpl extends ExtendedResponseImpl implements WhoAmIResponse
+{
+    /** The authzid */
+    private byte[] authzId;
+    
+    /** The authzId when it's a DN */
+    private Dn dn;
+    
+    /** The authzId when it's a userId */
+    private String userId;
+
+    
+    /**
+     * Create a new instance for the WhoAmI response
+     * @param messageId The Message ID
+     * @param rcode The result code
+     * @param diagnosticMessage The diagnostic message
+     */
+    public WhoAmIResponseImpl( int messageId, ResultCodeEnum rcode, String diagnosticMessage )
+    {
+        super( messageId, EXTENSION_OID );
+
+        super.getLdapResult().setMatchedDn( null );
+        super.getLdapResult().setResultCode( rcode );
+        super.getLdapResult().setDiagnosticMessage( diagnosticMessage );
+    }
+
+
+    /**
+     * Create a new instance for the WhoAmI response
+     * @param messageId The Message ID
+     * @param rcode The result code
+     */
+    public WhoAmIResponseImpl( int messageId, ResultCodeEnum rcode )
+    {
+        super( messageId, EXTENSION_OID );
+
+        super.getLdapResult().setMatchedDn( null );
+        super.getLdapResult().setResultCode( rcode );
+    }
+
+
+    /**
+     * Instantiates a new WhoAmI response.
+     *
+     * @param messageId the message id
+     */
+    public WhoAmIResponseImpl( int messageId )
+    {
+        super( messageId, EXTENSION_OID );
+        super.getLdapResult().setMatchedDn( null );
+        super.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS );
+    }
+
+
+    /**
+     * Instantiates a new WhoAmI response.
+     */
+    public WhoAmIResponseImpl()
+    {
+        super( EXTENSION_OID );
+        super.getLdapResult().setMatchedDn( null );
+        super.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public byte[] getAuthzId()
+    {
+        return authzId;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setAuthzId( byte[] authzId )
+    {
+        this.authzId = authzId;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isDnAuthzId()
+    {
+        if ( authzId != null )
+        {
+            return false;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isUserAuthzId()
+    {
+        return userId != null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getAuthzIdString()
+    {
+        return Strings.utf8ToString( authzId );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getUserId()
+    {
+        return userId;
+    }
+
+
+    /**
+     * Set the userId
+     */
+    public void setUserId( String userId )
+    {
+        this.userId = userId;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Dn getDn()
+    {
+        return dn;
+    }
+
+
+    /**
+     * Set the DN
+     */
+    public void setDn( Dn dn )
+    {
+        this.dn = dn;
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "PwdModifyResponse :" );
+        sb.append( "\n    authzid : " );
+
+        if ( authzId != null )
+        {
+            if ( isDnAuthzId() )
+            {
+                sb.append( "DN: " ).append( getDn() );
+            }
+            else
+            {
+                sb.append( "UserId: " ).append( getUserId() );
+            }
+        }
+        else
+        {
+            sb.append( "null" );
+        }
+
+        return sb.toString();
+    }
+}

Modified: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/ExtrasBundleActivator.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/ExtrasBundleActivator.java?rev=1581932&r1=1581931&r2=1581932&view=diff
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/ExtrasBundleActivator.java (original)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/ExtrasBundleActivator.java Wed Mar 26 16:53:17 2014
@@ -38,11 +38,14 @@ import org.apache.directory.api.ldap.ext
 import org.apache.directory.api.ldap.extras.extended.ads_impl.gracefulShutdown.GracefulShutdownFactory;
 import org.apache.directory.api.ldap.extras.extended.ads_impl.pwdModify.PasswordModifyFactory;
 import org.apache.directory.api.ldap.extras.extended.ads_impl.storedProcedure.StoredProcedureFactory;
+import org.apache.directory.api.ldap.extras.extended.ads_impl.whoAmI.WhoAmIFactory;
 import org.apache.directory.api.ldap.extras.extended.cancel.CancelRequest;
 import org.apache.directory.api.ldap.extras.extended.certGeneration.CertGenerationRequest;
 import org.apache.directory.api.ldap.extras.extended.gracefulDisconnect.GracefulDisconnectResponse;
 import org.apache.directory.api.ldap.extras.extended.gracefulShutdown.GracefulShutdownRequest;
+import org.apache.directory.api.ldap.extras.extended.pwdModify.PasswordModifyRequest;
 import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureRequest;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIRequest;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -123,6 +126,9 @@ public class ExtrasBundleActivator imple
 
         GracefulDisconnectFactory gracefulDisconnectFactory = new GracefulDisconnectFactory( codec );
         codec.registerExtendedRequest( gracefulDisconnectFactory );
+
+        WhoAmIFactory whoAmIFactory = new WhoAmIFactory( codec );
+        codec.registerExtendedRequest( whoAmIFactory );
     }
 
 
@@ -144,5 +150,7 @@ public class ExtrasBundleActivator imple
         codec.unregisterExtendedRequest( GracefulShutdownRequest.EXTENSION_OID );
         codec.unregisterExtendedRequest( StoredProcedureRequest.EXTENSION_OID );
         codec.unregisterExtendedRequest( GracefulDisconnectResponse.EXTENSION_OID );
+        codec.unregisterExtendedRequest( PasswordModifyRequest.EXTENSION_OID );
+        codec.unregisterExtendedRequest( WhoAmIRequest.EXTENSION_OID );
     }
 }

Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIFactory.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIFactory.java (added)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIFactory.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,165 @@
+/*
+ *   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.api.ldap.extras.extended.ads_impl.whoAmI;
+
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+
+import org.apache.directory.api.asn1.DecoderException;
+import org.apache.directory.api.asn1.ber.Asn1Decoder;
+import org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory;
+import org.apache.directory.api.ldap.codec.api.ExtendedResponseDecorator;
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIRequest;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIRequestImpl;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponse;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponseImpl;
+import org.apache.directory.api.ldap.model.message.ExtendedRequest;
+import org.apache.directory.api.ldap.model.message.ExtendedResponse;
+import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
+
+
+/**
+ * An {@link ExtendedOperationFactory} for creating WhoAmI extended request response 
+ * pairs.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class WhoAmIFactory implements ExtendedOperationFactory
+{
+    private LdapApiService codec;
+
+
+    public WhoAmIFactory( LdapApiService codec )
+    {
+        this.codec = codec;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getOid()
+    {
+        return WhoAmIRequest.EXTENSION_OID;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public WhoAmIResponse newResponse( byte[] encodedValue ) throws DecoderException
+    {
+        WhoAmIResponseDecorator response = new WhoAmIResponseDecorator( codec,
+            new WhoAmIResponseImpl() );
+        response.setResponseValue( encodedValue );
+        return response;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public WhoAmIRequest newRequest( byte[] value )
+    {
+        WhoAmIRequestDecorator req = new WhoAmIRequestDecorator( codec, new WhoAmIRequestImpl() );
+
+        if ( value != null )
+        {
+            req.setRequestValue( value );
+        }
+
+        return req;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public WhoAmIRequestDecorator decorate( ExtendedRequest modelRequest )
+    {
+        if ( modelRequest instanceof WhoAmIRequestDecorator )
+        {
+            return ( WhoAmIRequestDecorator ) modelRequest;
+        }
+
+        return new WhoAmIRequestDecorator( codec, ( WhoAmIRequest ) modelRequest );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public WhoAmIResponseDecorator decorate( ExtendedResponse decoratedResponse )
+    {
+        if ( decoratedResponse instanceof WhoAmIResponseDecorator )
+        {
+            return ( WhoAmIResponseDecorator ) decoratedResponse;
+        }
+
+        if ( decoratedResponse instanceof WhoAmIResponse )
+        {
+            return new WhoAmIResponseDecorator( codec, ( WhoAmIResponse ) decoratedResponse );
+        }
+
+        // It's an opaque extended operation
+        ExtendedResponseDecorator<ExtendedResponse> response = ( ExtendedResponseDecorator<ExtendedResponse> ) decoratedResponse;
+
+        // Decode the response, as it's an opaque operation
+        Asn1Decoder decoder = new Asn1Decoder();
+
+        byte[] value = response.getResponseValue();
+        ByteBuffer buffer = ByteBuffer.wrap( value );
+
+        WhoAmIResponseContainer container = new WhoAmIResponseContainer();
+        WhoAmIResponse whoAmIResponse = null;
+
+        try
+        {
+            decoder.decode( buffer, container );
+
+            whoAmIResponse = container.getWhoAmIResponse();
+
+            // Now, update the created response with what we got from the extendedResponse
+            whoAmIResponse.getLdapResult().setResultCode( response.getLdapResult().getResultCode() );
+            whoAmIResponse.getLdapResult().setDiagnosticMessage( response.getLdapResult().getDiagnosticMessage() );
+            whoAmIResponse.getLdapResult().setMatchedDn( response.getLdapResult().getMatchedDn() );
+            whoAmIResponse.getLdapResult().setReferral( response.getLdapResult().getReferral() );
+        }
+        catch ( DecoderException de )
+        {
+            StringWriter sw = new StringWriter();
+            de.printStackTrace( new PrintWriter( sw ) );
+            String stackTrace = sw.toString();
+
+            // Error while decoding the value. 
+            whoAmIResponse = new WhoAmIResponseImpl(
+                decoratedResponse.getMessageId(),
+                ResultCodeEnum.OPERATIONS_ERROR,
+                stackTrace );
+        }
+
+        WhoAmIResponseDecorator decorated = new WhoAmIResponseDecorator( codec, whoAmIResponse );
+
+        return decorated;
+    }
+}

Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIRequestDecorator.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIRequestDecorator.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIRequestDecorator.java (added)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIRequestDecorator.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,59 @@
+/*
+ *   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.api.ldap.extras.extended.ads_impl.whoAmI;
+
+
+import org.apache.directory.api.ldap.codec.api.ExtendedRequestDecorator;
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIRequest;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponse;
+
+
+/**
+ * A Decorator for WhoAmIRequest extended request.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class WhoAmIRequestDecorator extends ExtendedRequestDecorator<WhoAmIRequest> implements WhoAmIRequest
+{
+    /** The internal WhoAmIRequest */
+    private WhoAmIRequest whoAmIRequest;
+
+    /**
+     * Create a new decorator instance 
+     * @param codec The codec service
+     * @param decoratedMessage The decorated WhoAmIRequest
+     */
+    public WhoAmIRequestDecorator( LdapApiService codec, WhoAmIRequest decoratedMessage )
+    {
+        super( codec, decoratedMessage );
+        whoAmIRequest = decoratedMessage;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public WhoAmIResponse getResultResponse()
+    {
+        return ( WhoAmIResponse ) whoAmIRequest.getResultResponse();
+    }
+}

Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseContainer.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseContainer.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseContainer.java (added)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseContainer.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,78 @@
+/*
+ *  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.api.ldap.extras.extended.ads_impl.whoAmI;
+
+
+import org.apache.directory.api.asn1.ber.AbstractContainer;
+
+
+/**
+ * A container for WhoAmIResponse codec.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class WhoAmIResponseContainer extends AbstractContainer
+{
+    /** WhoAmIResponse decorator*/
+    private WhoAmIResponseDecorator whoAmIResponse;
+
+
+    /**
+     * Creates a new WhoAmIResponseContainer object. We will store one
+     * grammar, it's enough ...
+     */
+    public WhoAmIResponseContainer()
+    {
+        super();
+        grammar = WhoAmIResponseGrammar.getInstance();
+        setTransition( WhoAmIResponseStatesEnum.START_STATE );
+    }
+
+
+    /**
+     * @return Returns the WhoAmIResponse instance.
+     */
+    public WhoAmIResponseDecorator getWhoAmIResponse()
+    {
+        return whoAmIResponse;
+    }
+
+
+    /**
+     * Set a WhoAmIResponse Object into the container. It will be completed by
+     * the ldapDecoder.
+     * 
+     * @param whoAmIResponseDecorator the WhoAmIResponse to set.
+     */
+    public void setWhoAmIResponse( WhoAmIResponseDecorator whoAmIResponseDecorator )
+    {
+        this.whoAmIResponse = whoAmIResponseDecorator;
+    }
+
+
+    /**
+     * Clean the container for the next decoding.
+     */
+    public void clean()
+    {
+        super.clean();
+        whoAmIResponse = null;
+    }
+}

Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecoder.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecoder.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecoder.java (added)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecoder.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,62 @@
+/*
+ *  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.api.ldap.extras.extended.ads_impl.whoAmI;
+
+
+import java.nio.ByteBuffer;
+
+import org.apache.directory.api.asn1.DecoderException;
+import org.apache.directory.api.asn1.ber.Asn1Decoder;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponse;
+
+
+/**
+ * 
+ * A decoder for WhoAmIRequest.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class WhoAmIResponseDecoder extends Asn1Decoder
+{
+    /** The decoder */
+    private static final Asn1Decoder decoder = new Asn1Decoder();
+
+
+    /**
+     * Decode a PDU which must contain a WhoAmIRequest extended operation.
+     * Note that the stream of bytes much contain a full PDU, not a partial one.
+     * 
+     * @param stream The bytes to be decoded
+     * @return a WhoAmIRequest object
+     * @throws org.apache.directory.api.asn1.DecoderException If the decoding failed
+     */
+    public WhoAmIResponse decode( byte[] stream ) throws DecoderException
+    {
+        ByteBuffer bb = ByteBuffer.wrap( stream );
+        WhoAmIResponseContainer container = new WhoAmIResponseContainer();
+        decoder.decode( bb, container );
+        WhoAmIResponseDecorator whoAmIResponse = container.getWhoAmIResponse();
+
+        // Clean the container for the next decoding
+        container.clean();
+
+        return whoAmIResponse;
+    }
+}

Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecorator.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecorator.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecorator.java (added)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseDecorator.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,226 @@
+/*
+ *   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.api.ldap.extras.extended.ads_impl.whoAmI;
+
+
+import java.nio.ByteBuffer;
+
+import org.apache.directory.api.asn1.DecoderException;
+import org.apache.directory.api.asn1.EncoderException;
+import org.apache.directory.api.asn1.ber.tlv.BerValue;
+import org.apache.directory.api.i18n.I18n;
+import org.apache.directory.api.ldap.codec.api.ExtendedResponseDecorator;
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponse;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponseImpl;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Decorator for WhoAmIResponse extended request.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class WhoAmIResponseDecorator extends ExtendedResponseDecorator<WhoAmIResponse>
+    implements WhoAmIResponse
+{
+    private static final Logger LOG = LoggerFactory.getLogger( WhoAmIResponseDecorator.class );
+
+    private WhoAmIResponse whoAmIResponse;
+
+    public WhoAmIResponseDecorator( LdapApiService codec, WhoAmIResponse decoratedMessage )
+    {
+        super( codec, decoratedMessage );
+        whoAmIResponse = decoratedMessage;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setResponseValue( byte[] responseValue )
+    {
+        WhoAmIResponseDecoder decoder = new WhoAmIResponseDecoder();
+
+        try
+        {
+            whoAmIResponse = decoder.decode( responseValue );
+
+            if ( responseValue != null )
+            {
+                this.responseValue = new byte[responseValue.length];
+                System.arraycopy( responseValue, 0, this.responseValue, 0, responseValue.length );
+            }
+            else
+            {
+                this.responseValue = null;
+            }
+        }
+        catch ( DecoderException e )
+        {
+            LOG.error( I18n.err( I18n.ERR_04165 ), e );
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public byte[] getResponseValue()
+    {
+        if ( responseValue == null )
+        {
+            try
+            {
+                responseValue = encodeInternal().array();
+
+                if ( responseValue == null )
+                {
+                    return null;
+                }
+            }
+            catch ( EncoderException e )
+            {
+                LOG.error( I18n.err( I18n.ERR_04167 ), e );
+                throw new RuntimeException( e );
+            }
+        }
+
+        return responseValue;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public byte[] getAuthzId()
+    {
+        return getDecorated().getAuthzId();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setAuthzId( byte[] authzId )
+    {
+        ( ( WhoAmIResponseImpl ) getDecorated() ).setAuthzId( authzId );
+    }
+
+
+    /**
+     * Set the userId
+     */
+    /* no qualifier*/ void setUserId( String userId )
+    {
+        ((WhoAmIResponseImpl)whoAmIResponse).setUserId( userId );
+    }
+
+
+    /**
+     * Overload the parent's getResponseName method, as the WhoAmI response should not
+     * contain the responseName.
+     */
+    public String getResponseName()
+    {
+        return null;
+    }
+
+
+    /**
+     * Compute the WhoAmIResponse extended operation length
+     * <pre>
+     * 0x04 L1 authzId
+     * </pre>
+     */
+    /* no qualifier */ int computeLengthInternal()
+    {
+        if ( whoAmIResponse.getAuthzId() != null )
+        {
+            return 1 + BerValue.getNbBytes( whoAmIResponse.getAuthzId().length ) + 
+                whoAmIResponse.getAuthzId().length;
+        }
+        else
+        {
+            return 1 + 1;
+        }
+    }
+
+
+    /**
+     * Encodes the WhoAmIResponse extended operation.
+     * 
+     * @return A ByteBuffer that contains the encoded PDU
+     * @throws org.apache.directory.api.asn1.EncoderException If anything goes wrong.
+     */
+    /* no qualifier */ ByteBuffer encodeInternal() throws EncoderException
+    {
+        ByteBuffer bb = ByteBuffer.allocate( computeLengthInternal() );
+
+        BerValue.encode( bb, whoAmIResponse.getAuthzId() );
+    
+        return bb;
+    }
+
+
+    @Override
+    public boolean isDnAuthzId()
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+    @Override
+    public boolean isUserAuthzId()
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+    @Override
+    public String getAuthzIdString()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    @Override
+    public String getUserId()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    @Override
+    public Dn getDn()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseGrammar.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseGrammar.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseGrammar.java (added)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseGrammar.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,191 @@
+/*
+ *  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.api.ldap.extras.extended.ads_impl.whoAmI;
+
+
+import org.apache.directory.api.asn1.DecoderException;
+import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
+import org.apache.directory.api.asn1.ber.grammar.Grammar;
+import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
+import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
+import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
+import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
+import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponseImpl;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.util.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class implements the WhoAmIResponse extended operation's ASN.1 grammer. 
+ * All the actions are declared in this class. As it is a singleton, 
+ * these declaration are only done once. The grammar is :
+ * 
+ * <pre>
+ *  WhoAmIResponseValue ::= OCTET STRING OPTIONAL }
+ * </pre>
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+
+public class WhoAmIResponseGrammar extends AbstractGrammar<WhoAmIResponseContainer>
+{
+    /** logger */
+    private static final Logger LOG = LoggerFactory.getLogger( WhoAmIResponseGrammar.class );
+
+    /** Speedup for logs */
+    static final boolean IS_DEBUG = LOG.isDebugEnabled();
+
+    /** The instance of grammar. WhoAmIResponseGrammar is a singleton */
+    private static Grammar<WhoAmIResponseContainer> instance = new WhoAmIResponseGrammar();
+
+
+    @SuppressWarnings("unchecked")
+    public WhoAmIResponseGrammar()
+    {
+        setName( WhoAmIResponseGrammar.class.getName() );
+
+        // Create the transitions table
+        super.transitions = new GrammarTransition[WhoAmIResponseStatesEnum.LAST_WHO_AM_I_RESPONSE_STATE
+            .ordinal()][256];
+
+        /**
+         * Transition from init state to WhoAmI Authzid Response Value
+         * 
+         * authzId ::= OCTET STRING OPTIONAL
+         *     
+         * Creates the authzid object
+         */
+        super.transitions[WhoAmIResponseStatesEnum.START_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] =
+            new GrammarTransition<WhoAmIResponseContainer>(
+                WhoAmIResponseStatesEnum.START_STATE,
+                WhoAmIResponseStatesEnum.AUTHZ_ID_RESPONSE_STATE,
+                UniversalTag.OCTET_STRING.getValue(), new GrammarAction<WhoAmIResponseContainer>(
+                    "Store AuthzId" )
+                {
+                    public void action( WhoAmIResponseContainer container ) throws DecoderException
+                    {
+                        WhoAmIResponseDecorator whoAmIResponse = new WhoAmIResponseDecorator(
+                            LdapApiServiceFactory.getSingleton(), new WhoAmIResponseImpl() );
+                        container.setWhoAmIResponse( whoAmIResponse );
+                        
+                        byte[] data = container.getCurrentTLV().getValue().getData();
+                        
+                        if ( data != null )
+                        {
+                            switch ( data.length )
+                            {
+                                case 0:
+                                    // Error
+                                case 1:
+                                    // Error
+                                    String msg = "authzId too short. Must starts with either u: or dn:";
+                                    LOG.error( msg );
+                                    throw new DecoderException( msg );
+
+                                case 2 :
+                                    if ( ( data[0] == 'u' ) && ( data[1] == ':' ) )
+                                    {
+                                        whoAmIResponse.setAuthzId( data );
+                                        whoAmIResponse.setUserId( Strings.utf8ToString( data, 3, data.length - 3 ) );
+                                    }
+                                    else
+                                    {
+                                        msg = "authzId Must starts with either u: or dn:, it starts with " + Strings.utf8ToString( data );
+                                        LOG.error( msg );
+                                        throw new DecoderException( msg );
+                                    }
+                                    
+                                    break;
+                                    
+                                default :
+                                    switch ( data[0] )
+                                    {
+                                        case 'u' :
+                                            if ( data[1] == ':' )
+                                            {
+                                                whoAmIResponse.setAuthzId( data );
+                                                whoAmIResponse.setUserId( Strings.utf8ToString( data, 3, data.length - 3 ) );
+                                            }
+                                            else
+                                            {
+                                                msg = "authzId Must starts with either u: or dn:, it starts with " + Strings.utf8ToString( data );
+                                                LOG.error( msg );
+                                                throw new DecoderException( msg );
+                                            }
+                                            
+                                            break;
+                                            
+                                        case 'd' :
+                                            if ( ( data[1] == 'n' ) && ( data[2] == ':' ) )
+                                            {
+                                                // Check that the remaining bytes are a valid DN
+                                                if ( Dn.isValid( Strings.utf8ToString( data, 3, data.length - 3 ) ) )
+                                                {
+                                                    whoAmIResponse.setAuthzId( data );
+                                                }
+                                                else
+                                                {
+                                                    msg = "authzId Must starts with either u: or dn:, it starts with " + Strings.utf8ToString( data );
+                                                    LOG.error( msg );
+                                                    throw new DecoderException( msg );
+                                                }
+                                            }
+                                            else
+                                            {
+                                                msg = "authzId Must starts with either u: or dn:, it starts with " + Strings.utf8ToString( data );
+                                                LOG.error( msg );
+                                                throw new DecoderException( msg );
+                                            }
+                                            
+                                            break;
+
+                                        default :
+                                            msg = "authzId Must starts with either u: or dn:, it starts with " + Strings.utf8ToString( data );
+                                            LOG.error( msg );
+                                            throw new DecoderException( msg );
+                                    }
+                                    
+                                    break;
+                            }
+                        }
+                        else
+                        {
+                            whoAmIResponse.setAuthzId( null );
+                        }
+
+                        // We may have nothing left
+                        container.setGrammarEndAllowed( true );
+                    }
+                } );
+    }
+
+
+    /**
+     * This class is a singleton.
+     * 
+     * @return An instance on this grammar
+     */
+    public static Grammar<WhoAmIResponseContainer> getInstance()
+    {
+        return instance;
+    }
+}

Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseStatesEnum.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseStatesEnum.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseStatesEnum.java (added)
+++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseStatesEnum.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,100 @@
+/*
+ *  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.api.ldap.extras.extended.ads_impl.whoAmI;
+
+
+import org.apache.directory.api.asn1.ber.grammar.Grammar;
+import org.apache.directory.api.asn1.ber.grammar.States;
+
+
+/**
+ * This class store the WhoAmIResponse's grammar constants. It is also used
+ * for debugging purposes.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public enum WhoAmIResponseStatesEnum implements States
+{
+
+    /** The END_STATE */
+    END_STATE,
+
+    /** start state*/
+    START_STATE,
+
+    /** the authzid */
+    AUTHZ_ID_RESPONSE_STATE,
+
+    /** Last state */
+    LAST_WHO_AM_I_RESPONSE_STATE;
+
+    /**
+     * Get the grammar name
+     * 
+     * @param grammar The grammar class
+     * @return The grammar name
+     */
+    public String getGrammarName( Grammar<WhoAmIResponseContainer> grammar )
+    {
+        return "WHO_AM_I_RESPONSE_GRAMMER";
+    }
+
+
+    /**
+     * Get the grammar name
+     * 
+     * @param grammar The grammar code
+     * @return The grammar name
+     */
+    public String getGrammarName( int grammar )
+    {
+        return "WHO_AM_I_RESPONSE_GRAMMER";
+    }
+
+
+    /**
+     * Get the string representing the state
+     * 
+     * @param state The state number
+     * @return The String representing the state
+     */
+    public String getState( int state )
+    {
+        return ( ( state == END_STATE.ordinal() ) ? "WHO_AM_I_RESPONSE_GRAMMER" : this.name() );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isEndState()
+    {
+        return this == END_STATE;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public WhoAmIResponseStatesEnum getStartState()
+    {
+        return START_STATE;
+    }
+}

Added: directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseTest.java?rev=1581932&view=auto
==============================================================================
--- directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseTest.java (added)
+++ directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/extended/ads_impl/whoAmI/WhoAmIResponseTest.java Wed Mar 26 16:53:17 2014
@@ -0,0 +1,243 @@
+/*
+ *  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.api.ldap.extras.extended.ads_impl.whoAmI;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.nio.ByteBuffer;
+
+import org.apache.directory.api.asn1.DecoderException;
+import org.apache.directory.api.asn1.EncoderException;
+import org.apache.directory.api.asn1.ber.Asn1Container;
+import org.apache.directory.api.asn1.ber.Asn1Decoder;
+import org.apache.directory.api.util.Strings;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.mycila.junit.concurrent.Concurrency;
+import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+
+
+/*
+ * TestCase for a WhoAmI response Extended Operation
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(ConcurrentJunitRunner.class)
+@Concurrency()
+public class WhoAmIResponseTest
+{
+    /**
+     * Test the normal WhoAmI response message
+     */
+    @Test
+    public void testDecodeWhoAmINull()
+    {
+        Asn1Decoder whoAmIResponseDecoder = new WhoAmIResponseDecoder();
+
+        ByteBuffer stream = ByteBuffer.allocate( 0x00 );
+
+        stream.put( new byte[]
+            {} ).flip();
+
+        String decodedPdu = Strings.dumpBytes( stream.array() );
+
+        // Allocate a WhoAmI Container
+        Asn1Container whoAmIResponseContainer = new WhoAmIResponseContainer();
+
+        // Decode a WhoAmI message
+        try
+        {
+            whoAmIResponseDecoder.decode( stream, whoAmIResponseContainer );
+        }
+        catch ( DecoderException de )
+        {
+            de.printStackTrace();
+            fail( de.getMessage() );
+        }
+
+        WhoAmIResponseDecorator whoAmIResponse = ( ( WhoAmIResponseContainer ) whoAmIResponseContainer ).getWhoAmIResponse();
+
+        assertNull( whoAmIResponse );
+    }
+
+
+    /**
+     * Test a WhoAmI message with no authzId
+     */
+    @Test
+    public void testDecodeWhoAmINoWhoAmIAuthzIdEmpty()
+    {
+        Asn1Decoder whoAmIResponseDecoder = new WhoAmIResponseDecoder();
+
+        ByteBuffer stream = ByteBuffer.allocate( 0x02 );
+
+        stream.put( new byte[]
+            {
+                0x04, 0x00
+        } ).flip();
+
+        String decodedPdu = Strings.dumpBytes( stream.array() );
+
+        // Allocate a WhoAmI Container
+        Asn1Container whoAmIResponseContainer = new WhoAmIResponseContainer();
+
+        // Decode a WhoAmI message
+        try
+        {
+            whoAmIResponseDecoder.decode( stream, whoAmIResponseContainer );
+        }
+        catch ( DecoderException de )
+        {
+            fail();
+        }
+        
+        WhoAmIResponseDecorator whoAmIResponse = ( (WhoAmIResponseContainer ) whoAmIResponseContainer ).getWhoAmIResponse();
+
+        assertNull( whoAmIResponse.getAuthzId() );
+
+        // Check the encoding
+        try
+        {
+            ByteBuffer bb = whoAmIResponse.encodeInternal();
+
+            String encodedPdu = Strings.dumpBytes( bb.array() );
+
+            assertEquals( encodedPdu, decodedPdu );
+        }
+        catch ( EncoderException ee )
+        {
+            ee.printStackTrace();
+            fail( ee.getMessage() );
+        }
+    }
+
+
+    /**
+     * Test a WhoAmI message with a DN authzId
+     */
+    @Test
+    public void testDecodeWhoAmINoWhoAmIAuthzIdDN()
+    {
+        Asn1Decoder whoAmIResponseDecoder = new WhoAmIResponseDecoder();
+
+        ByteBuffer stream = ByteBuffer.allocate( 0x0E );
+
+        stream.put( new byte[]
+            {
+                0x04, 0x0C,
+                  'd', 'n', ':', 'o', 'u', '=', 's', 'y', 's', 't', 'e', 'm'
+        } ).flip();
+
+        String decodedPdu = Strings.dumpBytes( stream.array() );
+
+        // Allocate a WhoAmI Container
+        Asn1Container whoAmIResponseContainer = new WhoAmIResponseContainer();
+
+        // Decode a WhoAmI message
+        try
+        {
+            whoAmIResponseDecoder.decode( stream, whoAmIResponseContainer );
+        }
+        catch ( DecoderException de )
+        {
+            fail();
+        }
+        
+        WhoAmIResponseDecorator whoAmIResponse = ( (WhoAmIResponseContainer ) whoAmIResponseContainer ).getWhoAmIResponse();
+
+        assertNotNull( whoAmIResponse.getAuthzId() );
+        assertEquals( "dn:ou=system", Strings.utf8ToString( whoAmIResponse.getAuthzId() ) );
+        
+
+        // Check the encoding
+        try
+        {
+            ByteBuffer bb = whoAmIResponse.encodeInternal();
+
+            String encodedPdu = Strings.dumpBytes( bb.array() );
+
+            assertEquals( encodedPdu, decodedPdu );
+        }
+        catch ( EncoderException ee )
+        {
+            ee.printStackTrace();
+            fail( ee.getMessage() );
+        }
+    }
+
+
+    /**
+     * Test a WhoAmI message with a UserId authzId
+     */
+    @Test
+    public void testDecodeWhoAmINoWhoAmIAuthzIdUserId()
+    {
+        Asn1Decoder whoAmIResponseDecoder = new WhoAmIResponseDecoder();
+
+        ByteBuffer stream = ByteBuffer.allocate( 0x09 );
+
+        stream.put( new byte[]
+            {
+                0x04, 0x07,
+                  'u', ':', 't', 'e', 's', 't', 0x00
+        } ).flip();
+
+        String decodedPdu = Strings.dumpBytes( stream.array() );
+
+        // Allocate a WhoAmI Container
+        Asn1Container whoAmIResponseContainer = new WhoAmIResponseContainer();
+
+        // Decode a WhoAmI message
+        try
+        {
+            whoAmIResponseDecoder.decode( stream, whoAmIResponseContainer );
+        }
+        catch ( DecoderException de )
+        {
+            fail();
+        }
+        
+        WhoAmIResponseDecorator whoAmIResponse = ( (WhoAmIResponseContainer ) whoAmIResponseContainer ).getWhoAmIResponse();
+
+        assertNotNull( whoAmIResponse.getAuthzId() );
+
+        // Check the encoding
+        try
+        {
+            ByteBuffer bb = whoAmIResponse.encodeInternal();
+
+            String encodedPdu = Strings.dumpBytes( bb.array() );
+
+            assertEquals( encodedPdu, decodedPdu );
+        }
+        catch ( EncoderException ee )
+        {
+            ee.printStackTrace();
+            fail( ee.getMessage() );
+        }
+    }
+}