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 2006/01/22 01:34:12 UTC
svn commit: r371152 - in /directory/trunks/common/ldap/src:
main/java/org/apache/ldap/common/codec/extended/operations/
test/java/org/apache/ldap/common/codec/extended/operations/
Author: elecharny
Date: Sat Jan 21 16:34:03 2006
New Revision: 371152
URL: http://svn.apache.org/viewcvs?rev=371152&view=rev
Log:
Created a first version of GracefulDisconnect.
Test to be completed
Added:
directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnect.java
directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectConstants.java
directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectContainer.java
directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectDecoder.java
directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectGrammar.java
directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectStatesEnum.java
directory/trunks/common/ldap/src/test/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectTest.java
Added: directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnect.java
URL: http://svn.apache.org/viewcvs/directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnect.java?rev=371152&view=auto
==============================================================================
--- directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnect.java (added)
+++ directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnect.java Sat Jan 21 16:34:03 2006
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ldap.common.codec.extended.operations;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.asn1.Asn1Object;
+import org.apache.asn1.ber.tlv.Length;
+import org.apache.asn1.ber.tlv.UniversalTag;
+import org.apache.asn1.ber.tlv.Value;
+import org.apache.asn1.codec.EncoderException;
+import org.apache.ldap.common.codec.util.LdapURL;
+
+
+/**
+ * An extended operation to proceed a graceful disconnect
+ *
+ * <pre>
+ * GracefulDisconnect ::= SEQUENCE
+ * {
+ * timeOffline INTEGER (0..720) DEFAULT 0,
+ * delay [0] INTEGER (0..86400) DEFAULT 0,
+ * replicatedContexts Referral OPTIONAL
+ * }
+ * </pre>
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class GracefulDisconnect extends Asn1Object
+{
+ private int timeOffline;
+ private int delay;
+ private List replicatedContexts;
+ private transient int gracefulDisconnectSequenceLength;
+ private transient int replicatedContextsLength;
+
+ public GracefulDisconnect( int timeOffline, int delay )
+ {
+ this.timeOffline = timeOffline;
+ this.delay = delay;
+ this.replicatedContexts = new ArrayList(2);
+ }
+
+ public GracefulDisconnect()
+ {
+ this.timeOffline = 0;
+ this.delay = 0;
+ this.replicatedContexts = new ArrayList(2);
+ }
+
+ public int getDelay()
+ {
+ return delay;
+ }
+
+
+ public void setDelay( int delay )
+ {
+ this.delay = delay;
+ }
+
+
+ public int getTimeOffline()
+ {
+ return timeOffline;
+ }
+
+
+ public void setTimeOffline( int timeOffline )
+ {
+ this.timeOffline = timeOffline;
+ }
+
+ public List getReplicatedContexts()
+ {
+ return replicatedContexts;
+ }
+
+ public void setReplicatedContexts( List replicatedContexts )
+ {
+ this.replicatedContexts = replicatedContexts;
+ }
+
+ public void addReplicatedContexts( LdapURL replicatedContext )
+ {
+ replicatedContexts.add( replicatedContext );
+ }
+
+ /**
+ * Compute the GracefulDisconnect length
+ * 0x30 L1
+ * |
+ * +--> [ 0x02 0x0(1-4) [0..720] ]
+ * +--> [ 0x80 0x0(1-3) [0..86400] ]
+ * +--> [ 0x30 L2
+ * |
+ * +--> (0x04 L3 value) +
+ *
+ */
+ public int computeLength()
+ {
+ gracefulDisconnectSequenceLength = 0;
+
+ if ( timeOffline != 0 )
+ {
+ gracefulDisconnectSequenceLength += 1 + 1 + Length.getNbBytes( timeOffline );
+ }
+
+ if ( delay != 0 )
+ {
+ gracefulDisconnectSequenceLength += 1 + 1 + Length.getNbBytes( delay );
+ }
+
+ if ( replicatedContexts.size() > 0 )
+ {
+ replicatedContextsLength = 0;
+
+ Iterator replicatedContextIterator = replicatedContexts.iterator();
+
+ // We may have more than one reference.
+ while (replicatedContextIterator.hasNext())
+ {
+ int ldapUrlLength = ((LdapURL)replicatedContextIterator.next()).getNbBytes();
+ replicatedContextsLength += 1 + Length.getNbBytes( ldapUrlLength ) + ldapUrlLength;
+ }
+ }
+ else
+ {
+ replicatedContextsLength = 1 + 1;
+ }
+
+ gracefulDisconnectSequenceLength += 1 + Length.getNbBytes( replicatedContextsLength ) + replicatedContextsLength;
+
+ return 1 + Length.getNbBytes( gracefulDisconnectSequenceLength ) + gracefulDisconnectSequenceLength;
+ }
+
+ /**
+ * Encodes the gracefulDisconnect extended request.
+ *
+ * @param buffer The encoded sink
+ * @return A ByteBuffer that contains the encoded PDU
+ * @throws EncoderException If anything goes wrong.
+ */
+ public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
+ {
+ // Allocate the bytes buffer.
+ ByteBuffer bb = ByteBuffer.allocate( computeLength() );
+
+ bb.put( UniversalTag.SEQUENCE_TAG );
+ bb.put( Length.getBytes( gracefulDisconnectSequenceLength ) );
+
+ if ( timeOffline != 0 )
+ {
+ Value.encode( bb, timeOffline );
+ }
+
+ if ( delay != 0 )
+ {
+ bb.put( (byte)GracefulDisconnectConstants.GRACEFUL_DISCONNECT_DELAY_TAG );
+ bb.put( (byte)Length.getNbBytes( delay ) );
+ bb.put( Value.getBytes( delay ) );
+ }
+
+ if ( replicatedContexts.size() != 0 )
+ {
+ bb.put( UniversalTag.SEQUENCE_TAG );
+ bb.put( Length.getBytes( replicatedContextsLength ) );
+
+ Iterator replicatedContextIterator = replicatedContexts.iterator();
+
+ // We may have more than one reference.
+ while (replicatedContextIterator.hasNext())
+ {
+ LdapURL url = (LdapURL)replicatedContextIterator.next();
+ Value.encode( bb, url.getBytes() );
+ }
+ }
+
+ return bb;
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append( " TimeOffline : " ).append( timeOffline ).append( '\n' );
+ sb.append( " Delay : ").append( delay ).append( '\n' );
+
+ if ( replicatedContexts.size() != 0 )
+ {
+ Iterator replicatedContextIterator = replicatedContexts.iterator();
+ sb.append( " Replicated contexts :" );
+
+ // We may have more than one reference.
+ while (replicatedContextIterator.hasNext())
+ {
+ LdapURL url = (LdapURL)replicatedContextIterator.next();
+ sb.append( "\n " ).append(url.toString() );
+ }
+ }
+
+ return sb.toString();
+ }
+}
Added: directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectConstants.java
URL: http://svn.apache.org/viewcvs/directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectConstants.java?rev=371152&view=auto
==============================================================================
--- directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectConstants.java (added)
+++ directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectConstants.java Sat Jan 21 16:34:03 2006
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ldap.common.codec.extended.operations;
+
+
+/**
+ * GracefulDisconnect extended operation constants
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class GracefulDisconnectConstants
+{
+ public static final int GRACEFUL_DISCONNECT_DELAY_TAG = 0x80;
+}
Added: directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectContainer.java
URL: http://svn.apache.org/viewcvs/directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectContainer.java?rev=371152&view=auto
==============================================================================
--- directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectContainer.java (added)
+++ directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectContainer.java Sat Jan 21 16:34:03 2006
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ldap.common.codec.extended.operations;
+
+
+import org.apache.asn1.ber.AbstractContainer;
+import org.apache.asn1.ber.IAsn1Container;
+import org.apache.asn1.ber.grammar.IGrammar;
+
+
+/**
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class GracefulDisconnectContainer extends AbstractContainer implements IAsn1Container
+{
+ /** GracefulShutdown */
+ private GracefulDisconnect gracefulDisconnect;
+
+ /**
+ * Creates a new GracefulDisconnectContainer object.
+ * We will store one grammar, it's enough ...
+ */
+ public GracefulDisconnectContainer()
+ {
+ super( );
+ currentGrammar = 0;
+ grammars = new IGrammar[GracefulDisconnectStatesEnum.NB_GRAMMARS];
+ grammarStack = new IGrammar[1];
+ stateStack = new int[1];
+ nbGrammars = 0;
+
+ grammars[GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_GRAMMAR] = GracefulDisconnectGrammar.getInstance();
+ grammarStack[currentGrammar] = grammars[GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_GRAMMAR];
+ states = GracefulDisconnectStatesEnum.getInstance();
+ }
+
+
+ /**
+ * @return Returns the Graceful Shutdown object.
+ */
+ public GracefulDisconnect getGracefulDisconnect()
+ {
+
+ return gracefulDisconnect;
+ }
+
+
+ /**
+ * Set a GracefulDisconnect Object into the container. It will be completed
+ * by the ldapDecoder.
+ *
+ * @param control the GracefulShutdown to set.
+ */
+ public void setGracefulDisconnect( GracefulDisconnect gracefulDisconnect )
+ {
+ this.gracefulDisconnect = gracefulDisconnect;
+ }
+
+
+ public void clean()
+ {
+ super.clean();
+ gracefulDisconnect = null;
+ }
+}
Added: directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectDecoder.java
URL: http://svn.apache.org/viewcvs/directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectDecoder.java?rev=371152&view=auto
==============================================================================
--- directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectDecoder.java (added)
+++ directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectDecoder.java Sat Jan 21 16:34:03 2006
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ldap.common.codec.extended.operations;
+
+
+import java.nio.ByteBuffer;
+
+import org.apache.asn1.Asn1Object;
+import org.apache.asn1.ber.Asn1Decoder;
+import org.apache.asn1.codec.DecoderException;
+
+
+/**
+ * A decoder for GracefulDisconnects.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class GracefulDisconnectDecoder extends Asn1Decoder
+{
+ private static final Asn1Decoder decoder = new Asn1Decoder();
+
+ public Asn1Object decode(byte[] controlBytes) throws DecoderException
+ {
+ ByteBuffer bb = ByteBuffer.wrap( controlBytes );
+ GracefulDisconnectContainer container = new GracefulDisconnectContainer();
+ decoder.decode( bb, container );
+ return container.getGracefulDisconnect();
+ }
+}
Added: directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectGrammar.java
URL: http://svn.apache.org/viewcvs/directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectGrammar.java?rev=371152&view=auto
==============================================================================
--- directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectGrammar.java (added)
+++ directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectGrammar.java Sat Jan 21 16:34:03 2006
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ldap.common.codec.extended.operations;
+
+import org.apache.asn1.ber.IAsn1Container;
+import org.apache.asn1.ber.grammar.AbstractGrammar;
+import org.apache.asn1.ber.grammar.GrammarAction;
+import org.apache.asn1.ber.grammar.GrammarTransition;
+import org.apache.asn1.ber.grammar.IGrammar;
+import org.apache.asn1.ber.tlv.UniversalTag;
+import org.apache.asn1.ber.tlv.Value;
+import org.apache.asn1.codec.DecoderException;
+import org.apache.asn1.util.IntegerDecoder;
+import org.apache.asn1.util.IntegerDecoderException;
+import org.apache.ldap.common.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.ldap.common.codec.util.LdapURL;
+import org.apache.ldap.common.codec.util.LdapURLEncodingException;
+
+
+
+/**
+ * This class implements the Graceful Disconnect. All the actions are declared in this
+ * class. As it is a singleton, these declaration are only done once.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class GracefulDisconnectGrammar extends AbstractGrammar implements IGrammar
+{
+ /** The logger */
+ private static final Logger log = LoggerFactory.getLogger( GracefulDisconnectGrammar.class );
+
+ /** The instance of grammar. GracefulDisconnectnGrammar is a singleton */
+ private static IGrammar instance = new GracefulDisconnectGrammar();
+
+ /**
+ * Creates a new GracefulDisconnectGrammar object.
+ */
+ private GracefulDisconnectGrammar()
+ {
+ name = GracefulDisconnectGrammar.class.getName();
+ statesEnum = GracefulDisconnectStatesEnum.getInstance();
+
+ // Create the transitions table
+ super.transitions = new GrammarTransition[GracefulDisconnectStatesEnum.LAST_GRACEFUL_DISCONNECT_STATE][256];
+
+ super.transitions[GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_TAG][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_TAG,
+ GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_VALUE, null );
+
+ super.transitions[GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_VALUE][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_VALUE,
+ GracefulDisconnectStatesEnum.TIME_OFFLINE_OR_DELAY_OR_REPLICATED_OR_END_TAG,
+ new GrammarAction( "Init Graceful Disconnect" )
+ {
+ public void action( IAsn1Container container )
+ {
+ GracefulDisconnectContainer gracefulDisconnectContainer = ( GracefulDisconnectContainer ) container;
+ GracefulDisconnect gracefulDisconnect = new GracefulDisconnect();
+ gracefulDisconnectContainer.setGracefulDisconnect( gracefulDisconnect );
+ gracefulDisconnectContainer.grammarEndAllowed( true );
+ }
+ }
+ );
+
+ super.transitions[GracefulDisconnectStatesEnum.TIME_OFFLINE_OR_DELAY_OR_REPLICATED_OR_END_TAG][UniversalTag.INTEGER_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.TIME_OFFLINE_OR_DELAY_OR_REPLICATED_OR_END_TAG,
+ GracefulDisconnectStatesEnum.TIME_OFFLINE_VALUE, null );
+
+ super.transitions[GracefulDisconnectStatesEnum.TIME_OFFLINE_OR_DELAY_OR_REPLICATED_OR_END_TAG][GracefulDisconnectConstants.GRACEFUL_DISCONNECT_DELAY_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.TIME_OFFLINE_OR_DELAY_OR_REPLICATED_OR_END_TAG,
+ GracefulDisconnectStatesEnum.DELAY_VALUE, null );
+
+ super.transitions[GracefulDisconnectStatesEnum.TIME_OFFLINE_OR_DELAY_OR_REPLICATED_OR_END_TAG][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.TIME_OFFLINE_OR_DELAY_OR_REPLICATED_OR_END_TAG,
+ GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_VALUE, null );
+
+ super.transitions[GracefulDisconnectStatesEnum.TIME_OFFLINE_VALUE][UniversalTag.INTEGER_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.TIME_OFFLINE_VALUE,
+ GracefulDisconnectStatesEnum.DELAY_OR_REPLICATED_OR_END_TAG,
+ new GrammarAction( "Set Graceful Disconnect delay" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ GracefulDisconnectContainer gracefulDisconnectContainer = ( GracefulDisconnectContainer ) container;
+ Value value = gracefulDisconnectContainer.getCurrentTLV().getValue();
+
+ try
+ {
+ int timeOffline = IntegerDecoder.parse( value, 0, 720 );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Time Offline = " + timeOffline );
+ }
+
+ gracefulDisconnectContainer.getGracefulDisconnect().setTimeOffline( timeOffline );
+ gracefulDisconnectContainer.grammarEndAllowed( true );
+ }
+ catch ( IntegerDecoderException e )
+ {
+ String msg = "failed to decode the timeOffline, the value should be between 0 and 720 minutes, it is '" +
+ StringTools.dumpBytes( value.getData() ) + "'";
+ log.error( msg );
+ throw new DecoderException( msg );
+ }
+ }
+ }
+ );
+
+ super.transitions[GracefulDisconnectStatesEnum.DELAY_OR_REPLICATED_OR_END_TAG][GracefulDisconnectConstants.GRACEFUL_DISCONNECT_DELAY_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.DELAY_OR_REPLICATED_OR_END_TAG,
+ GracefulDisconnectStatesEnum.DELAY_VALUE, null );
+
+ super.transitions[GracefulDisconnectStatesEnum.DELAY_VALUE][GracefulDisconnectConstants.GRACEFUL_DISCONNECT_DELAY_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.DELAY_VALUE,
+ GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_OR_END_TAG,
+ new GrammarAction( "Set Graceful Disconnect Delay" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ GracefulDisconnectContainer gracefulDisconnectContainer = ( GracefulDisconnectContainer ) container;
+ Value value = gracefulDisconnectContainer.getCurrentTLV().getValue();
+
+ try
+ {
+ int delay = IntegerDecoder.parse( value, 0, 86400 );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Delay = " + delay );
+ }
+
+ gracefulDisconnectContainer.getGracefulDisconnect().setDelay( delay );
+ gracefulDisconnectContainer.grammarEndAllowed( true );
+ }
+ catch ( IntegerDecoderException e )
+ {
+ String msg = "failed to decode the delay, the value should be between 0 and 86400 seconds, it is '" +
+ StringTools.dumpBytes( value.getData() ) + "'";
+ log.error( msg );
+ throw new DecoderException( msg );
+ }
+ }
+ }
+ );
+
+ super.transitions[GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_OR_END_TAG][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_OR_END_TAG,
+ GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_VALUE, null );
+
+ super.transitions[GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_VALUE][UniversalTag.SEQUENCE_TAG] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_VALUE,
+ GracefulDisconnectStatesEnum.REPLICATED_CONTEXT_OR_END_TAG, null );
+
+ super.transitions[GracefulDisconnectStatesEnum.REPLICATED_CONTEXT_OR_END_TAG][UniversalTag.OCTET_STRING] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.REPLICATED_CONTEXT_OR_END_TAG,
+ GracefulDisconnectStatesEnum.REPLICATED_CONTEXT_VALUE, null );
+
+ super.transitions[GracefulDisconnectStatesEnum.REPLICATED_CONTEXT_VALUE][UniversalTag.OCTET_STRING] =
+ new GrammarTransition( GracefulDisconnectStatesEnum.REPLICATED_CONTEXT_VALUE,
+ GracefulDisconnectStatesEnum.REPLICATED_CONTEXT_OR_END_TAG,
+ new GrammarAction( "Replicated context URL" )
+ {
+ public void action( IAsn1Container container ) throws DecoderException
+ {
+ GracefulDisconnectContainer gracefulDisconnectContainer = ( GracefulDisconnectContainer ) container;
+ Value value = gracefulDisconnectContainer.getCurrentTLV().getValue();
+
+ try
+ {
+ LdapURL url = new LdapURL( value.getData() );
+ gracefulDisconnectContainer.getGracefulDisconnect().addReplicatedContexts( url );
+ gracefulDisconnectContainer.grammarEndAllowed( true );
+ }
+ catch ( LdapURLEncodingException e )
+ {
+ String msg = "failed to decode the URL '" +
+ StringTools.dumpBytes( value.getData() ) + "'";
+ log.error( msg );
+ throw new DecoderException( msg );
+ }
+ }
+ }
+ );
+ }
+
+ /**
+ * This class is a singleton.
+ *
+ * @return An instance on this grammar
+ */
+ public static IGrammar getInstance()
+ {
+ return instance;
+ }
+}
Added: directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectStatesEnum.java
URL: http://svn.apache.org/viewcvs/directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectStatesEnum.java?rev=371152&view=auto
==============================================================================
--- directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectStatesEnum.java (added)
+++ directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectStatesEnum.java Sat Jan 21 16:34:03 2006
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ldap.common.codec.extended.operations;
+
+
+import org.apache.asn1.ber.grammar.IStates;
+import org.apache.asn1.ber.grammar.IGrammar;
+
+
+/**
+ * This class store the GracefulDisconnect's grammar constants.
+ * It is also used for debugging purposes.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class GracefulDisconnectStatesEnum implements IStates
+{
+ //~ Static fields/initializers -----------------------------------------------------------------
+
+ //=========================================================================
+ // GracefulDisconnect grammar states
+ //=========================================================================
+
+ /** Sequence Tag */
+ public static int GRACEFUL_DISCONNECT_SEQUENCE_TAG = 0;
+
+ /** Sequence Value */
+ public static int GRACEFUL_DISCONNECT_SEQUENCE_VALUE = 1;
+
+ /** Time offline Tag */
+ public static int TIME_OFFLINE_OR_DELAY_OR_REPLICATED_OR_END_TAG = 2;
+
+ /** Time offline Value */
+ public static int TIME_OFFLINE_VALUE = 3;
+
+ /** Delay Tag */
+ public static int DELAY_OR_REPLICATED_OR_END_TAG = 4;
+
+ /** Delay Value */
+ public static int DELAY_VALUE = 5;
+
+ /** Replicated contexts Tag */
+ public static int REPLICATED_CONTEXTS_OR_END_TAG = 6;
+
+ /** Replicated contexts Value */
+ public static int REPLICATED_CONTEXTS_VALUE = 7;
+
+ /** Replicated contexts Tag */
+ public static int REPLICATED_CONTEXT_OR_END_TAG = 8;
+
+ /** Replicated contexts Value */
+ public static int REPLICATED_CONTEXT_VALUE = 9;
+
+ /** terminal state */
+ public static int LAST_GRACEFUL_DISCONNECT_STATE = 10;
+
+ //=========================================================================
+ // Grammars declaration.
+ //=========================================================================
+ /** GracefulDisconnect grammar */
+ public static final int GRACEFUL_DISCONNECT_GRAMMAR_SWITCH = 0x0100;
+
+ /** GracefulDisconnect grammar number */
+ public static final int GRACEFUL_DISCONNECT_GRAMMAR = 0;
+
+ /** The total number of grammars used */
+ public static final int NB_GRAMMARS = 1;
+
+ //=========================================================================
+ // Grammar switches debug strings
+ //=========================================================================
+ /** A string representation of grammars */
+ private static String[] GrammarSwitchString =
+ new String[]
+ {
+ "GRACEFUL_DISCONNECT_GRAMMAR_SWITCH"
+ };
+
+ //=========================================================================
+ // States debug strings
+ //=========================================================================
+ /** A string representation of all the states */
+ private static String[] GracefulDisconnectString = new String[]
+ {
+ "GRACEFUL_DISCONNECT_SEQUENCE_TAG",
+ "GRACEFUL_DISCONNECT_SEQUENCE_VALUE",
+ "TIME_OFFLINE_OR_DELAY_OR_REPLICATED_OR_END_TAG",
+ "TIME_OFFLINE_VALUE",
+ "DELAY_OR_REPLICATED_OR_END_TAG",
+ "DELAY_VALUE",
+ "REPLICATED_CONTEXTS_OR_END_TAG",
+ "REPLICATED_CONTEXTS_VALUE",
+ "REPLICATED_CONTEXT_OR_END_TAG",
+ "REPLICATED_CONTEXT_VALUE"
+ };
+
+ /** The instance */
+ private static GracefulDisconnectStatesEnum instance = new GracefulDisconnectStatesEnum();
+
+ //~ Constructors -------------------------------------------------------------------------------
+
+ /**
+ * This is a private constructor. This class is a singleton
+ *
+ */
+ private GracefulDisconnectStatesEnum()
+ {
+ }
+
+ //~ Methods ------------------------------------------------------------------------------------
+
+ /**
+ * Get an instance of this class
+ * @return An instance on this class
+ */
+ public static IStates getInstance()
+ {
+ return instance;
+ }
+
+ /**
+ * Get the grammar name
+ * @param grammar The grammar code
+ * @return The grammar name
+ */
+ public String getGrammarName( int grammar )
+ {
+ switch ( grammar )
+ {
+ case GRACEFUL_DISCONNECT_GRAMMAR: return "GRACEFUL_DISCONNECT_GRAMMAR";
+ default: return "UNKNOWN";
+ }
+ }
+
+ /**
+ * Get the grammar name
+ * @param grammar The grammar class
+ * @return The grammar name
+ */
+ public String getGrammarName( IGrammar grammar )
+ {
+ if ( grammar instanceof GracefulDisconnectGrammar )
+ {
+ return "GRACEFUL_DISCONNECT_GRAMMAR";
+ }
+
+ return "UNKNOWN GRAMMAR";
+ }
+
+ /**
+ * Get the string representing the state
+ *
+ * @param grammar The current grammar being used
+ * @param state The state number
+ * @return The String representing the state
+ */
+ public String getState( int grammar, int state )
+ {
+
+ if ( ( state & GRAMMAR_SWITCH_MASK ) != 0 )
+ {
+ return ( state == END_STATE ) ? "END_STATE"
+ : GrammarSwitchString[( ( state & GRAMMAR_SWITCH_MASK ) >> 8 ) - 1];
+ }
+ else
+ {
+
+ switch ( grammar )
+ {
+
+ case GRACEFUL_DISCONNECT_GRAMMAR :
+ return ( ( state == GRAMMAR_END ) ? "GRACEFUL_DISCONNECT_END_STATE" : GracefulDisconnectString[state] );
+
+ default :
+ return "UNKNOWN";
+ }
+ }
+ }
+}
Added: directory/trunks/common/ldap/src/test/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectTest.java
URL: http://svn.apache.org/viewcvs/directory/trunks/common/ldap/src/test/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectTest.java?rev=371152&view=auto
==============================================================================
--- directory/trunks/common/ldap/src/test/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectTest.java (added)
+++ directory/trunks/common/ldap/src/test/java/org/apache/ldap/common/codec/extended/operations/GracefulDisconnectTest.java Sat Jan 21 16:34:03 2006
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.ldap.common.codec.extended.operations;
+
+import java.nio.ByteBuffer;
+
+import javax.naming.NamingException;
+
+import org.apache.asn1.codec.DecoderException;
+import org.apache.asn1.ber.Asn1Decoder;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+/**
+ * Test the GracefulDisconnectTest codec
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class GracefulDisconnectTest extends TestCase {
+ /**
+ * Test the decoding of a GracefulDisconnect
+ */
+ public void testDecodeGracefulDisconnectSuccess() throws NamingException
+ {
+ Asn1Decoder decoder = new GracefulDisconnectDecoder();
+ ByteBuffer bb = ByteBuffer.allocate( 0x70 );
+ bb.put( new byte[]
+ {
+ 0x30, 0x6E, // GracefulDisconnec ::= SEQUENCE {
+ 0x02, 0x01, 0x01, // timeOffline INTEGER (0..720) DEFAULT 0,
+ (byte)0x80, 0x01, 0x01, // delay INTEGER (0..86400) DEFAULT 0
+ // replicatedContexts Referral OPTIONAL
+ 0x30, 0x66,
+ 0x04, 0x1F,
+ 'l', 'd', 'a', 'p', ':', '/', '/', 'd',
+ 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y',
+ '.', 'a', 'p', 'a', 'c', 'h', 'e', '.',
+ 'o', 'r', 'g', ':', '8', '0', '/',
+ 0x04, 0x43,
+ 'l', 'd', 'a', 'p', ':', '/', '/', 'l',
+ 'd', 'a', 'p', '.', 'n', 'e', 't', 's',
+ 'c', 'a', 'p', 'e', '.', 'c', 'o', 'm',
+ '/', 'o', '=', 'B', 'a', 'b', 's', 'c',
+ 'o', ',', 'c', '=', 'U', 'S', '?', '?',
+ '?', '(', 'i', 'n', 't', '=', '%', '5',
+ 'c', '0', '0', '%', '5', 'c', '0', '0',
+ '%', '5', 'c', '0', '0', '%', '5', 'c',
+ '0', '4', ')'
+ // }
+ } );
+ bb.flip();
+
+ GracefulDisconnectContainer container = new GracefulDisconnectContainer();
+
+ try
+ {
+ decoder.decode( bb, container );
+ }
+ catch ( DecoderException de )
+ {
+ de.printStackTrace();
+ Assert.fail( de.getMessage() );
+ }
+
+ GracefulDisconnect gracefulDisconnect = container.getGracefulDisconnect();
+ assertEquals( 1, gracefulDisconnect.getTimeOffline() );
+ assertEquals( 1, gracefulDisconnect.getDelay() );
+ assertEquals( 2, gracefulDisconnect.getReplicatedContexts().size() );
+ assertEquals( "ldap://directory.apache.org:80/", gracefulDisconnect.getReplicatedContexts().get( 0 ).toString() );
+ assertEquals( "ldap://ldap.netscape.com/o=Babsco,c=US???(int=%5c00%5c00%5c00%5c04)", gracefulDisconnect.getReplicatedContexts().get( 1 ).toString() );
+ }
+
+ /**
+ * Test the decoding of a GracefulDisconnect with a timeOffline only
+ */
+ public void testDecodeGracefulDisconnectTimeOffline() throws NamingException
+ {
+ Asn1Decoder decoder = new GracefulDisconnectDecoder();
+ ByteBuffer bb = ByteBuffer.allocate( 0x0b );
+ bb.put( new byte[]
+ {
+ 0x30, 0x03, // GracefulDisconnect ::= SEQUENCE {
+ 0x02, 0x01, 0x01 // timeOffline INTEGER (0..720) DEFAULT 0,
+ } );
+ bb.flip();
+
+ GracefulDisconnectContainer container = new GracefulDisconnectContainer();
+
+ try
+ {
+ decoder.decode( bb, container );
+ }
+ catch ( DecoderException de )
+ {
+ de.printStackTrace();
+ Assert.fail( de.getMessage() );
+ }
+
+ GracefulDisconnect gracefulDisconnect = container.getGracefulDisconnect();
+ assertEquals( 1, gracefulDisconnect.getTimeOffline() );
+ assertEquals( 0, gracefulDisconnect.getDelay() );
+ }
+
+ /**
+ * Test the decoding of a GracefulDisconnect with a delay only
+ */
+ public void testDecodeGracefulDisconnectDelay() throws NamingException
+ {
+ Asn1Decoder decoder = new GracefulDisconnectDecoder();
+ ByteBuffer bb = ByteBuffer.allocate( 0x0b );
+ bb.put( new byte[]
+ {
+ 0x30, 0x03, // GracefulDisconnect ::= SEQUENCE {
+ (byte)0x80, 0x01, 0x01 // delay INTEGER (0..86400) DEFAULT 0
+ } );
+ bb.flip();
+
+ GracefulDisconnectContainer container = new GracefulDisconnectContainer();
+
+ try
+ {
+ decoder.decode( bb, container );
+ }
+ catch ( DecoderException de )
+ {
+ de.printStackTrace();
+ Assert.fail( de.getMessage() );
+ }
+
+ GracefulDisconnect gracefulDisconnect = container.getGracefulDisconnect();
+ assertEquals( 0, gracefulDisconnect.getTimeOffline() );
+ assertEquals( 1, gracefulDisconnect.getDelay() );
+ }
+
+ /**
+ * Test the decoding of a empty GracefulDisconnect
+ */
+ public void testDecodeGracefulDisconnectEmpty() throws NamingException
+ {
+ Asn1Decoder decoder = new GracefulDisconnectDecoder();
+ ByteBuffer bb = ByteBuffer.allocate( 0x0b );
+ bb.put( new byte[]
+ {
+ 0x30, 0x00 // GracefulDisconnect ::= SEQUENCE {
+ } );
+ bb.flip();
+
+ GracefulDisconnectContainer container = new GracefulDisconnectContainer();
+
+ try
+ {
+ decoder.decode( bb, container );
+ }
+ catch ( DecoderException de )
+ {
+ de.printStackTrace();
+ Assert.fail( de.getMessage() );
+ }
+
+ GracefulDisconnect gracefulDisconnect = container.getGracefulDisconnect();
+ assertEquals( 0, gracefulDisconnect.getTimeOffline() );
+ assertEquals( 0, gracefulDisconnect.getDelay() );
+ }
+
+ // Defensive tests
+
+ /**
+ * Test the decoding of a GracefulDisconnect with a timeOffline off limit
+ */
+ public void testDecodeGracefulDisconnectTimeOfflineOffLimit() throws NamingException
+ {
+ Asn1Decoder decoder = new GracefulDisconnectDecoder();
+ ByteBuffer bb = ByteBuffer.allocate( 0x0b );
+ bb.put( new byte[]
+ {
+ 0x30, 0x04, // GracefulDisconnect ::= SEQUENCE {
+ 0x02, 0x02, 0x03, (byte)0xE8 // timeOffline INTEGER (0..720) DEFAULT 0,
+ } );
+ bb.flip();
+
+ GracefulDisconnectContainer container = new GracefulDisconnectContainer();
+
+ try
+ {
+ decoder.decode( bb, container );
+ }
+ catch ( DecoderException de )
+ {
+ System.out.println( de.getMessage() );
+ assertTrue( true );
+ return;
+ }
+
+ fail( "We should not reach this point" );
+ }
+
+ /**
+ * Test the decoding of a GracefulDisconnect with a delay off limit
+ */
+ public void testDecodeGracefulDisconnectDelayOffLimit() throws NamingException
+ {
+ Asn1Decoder decoder = new GracefulDisconnectDecoder();
+ ByteBuffer bb = ByteBuffer.allocate( 0x0b );
+ bb.put( new byte[]
+ {
+ 0x30, 0x05, // GracefulDisconnect ::= SEQUENCE {
+ (byte)0x80, 0x03, 0x01, (byte)0x86, (byte)0xA0 // delay INTEGER (0..86400) DEFAULT 0
+ } );
+ bb.flip();
+
+ GracefulDisconnectContainer container = new GracefulDisconnectContainer();
+
+ try
+ {
+ decoder.decode( bb, container );
+ }
+ catch ( DecoderException de )
+ {
+ System.out.println( de.getMessage() );
+ assertTrue( true );
+ return;
+ }
+
+ fail( "We should not reach this point" );
+ }
+
+ /**
+ * Test the decoding of a GracefulDisconnect with an empty TimeOffline
+ */
+ public void testDecodeGracefulDisconnectTimeOfflineEmpty() throws NamingException
+ {
+ Asn1Decoder decoder = new GracefulDisconnectDecoder();
+ ByteBuffer bb = ByteBuffer.allocate( 0x0b );
+ bb.put( new byte[]
+ {
+ 0x30, 0x02, // GracefulDisconnect ::= SEQUENCE {
+ 0x02, 0x00 // timeOffline INTEGER (0..720) DEFAULT 0,
+ } );
+ bb.flip();
+
+ GracefulDisconnectContainer container = new GracefulDisconnectContainer();
+
+ try
+ {
+ decoder.decode( bb, container );
+ }
+ catch ( DecoderException de )
+ {
+ System.out.println( de.getMessage() );
+ assertTrue( true );
+ return;
+ }
+
+ fail( "We should not reach this point" );
+ }
+
+ /**
+ * Test the decoding of a GracefulDisconnect with an empty delay
+ */
+ public void testDecodeGracefulDisconnectDelayEmpty() throws NamingException
+ {
+ Asn1Decoder decoder = new GracefulDisconnectDecoder();
+ ByteBuffer bb = ByteBuffer.allocate( 0x0b );
+ bb.put( new byte[]
+ {
+ 0x30, 0x02, // GracefulDisconnect ::= SEQUENCE {
+ (byte)0x80, 0x00 // delay INTEGER (0..86400) DEFAULT 0
+ } );
+ bb.flip();
+
+ GracefulDisconnectContainer container = new GracefulDisconnectContainer();
+
+ try
+ {
+ decoder.decode( bb, container );
+ }
+ catch ( DecoderException de )
+ {
+ System.out.println( de.getMessage() );
+ assertTrue( true );
+ return;
+ }
+
+ fail( "We should not reach this point" );
+ }
+}