001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.codec.extended.operations.cancel;
021
022
023 import org.apache.directory.shared.asn1.ber.IAsn1Container;
024 import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar;
025 import org.apache.directory.shared.asn1.ber.grammar.GrammarAction;
026 import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition;
027 import org.apache.directory.shared.asn1.ber.grammar.IGrammar;
028 import org.apache.directory.shared.asn1.ber.grammar.IStates;
029 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
030 import org.apache.directory.shared.asn1.ber.tlv.Value;
031 import org.apache.directory.shared.asn1.codec.DecoderException;
032 import org.apache.directory.shared.asn1.util.IntegerDecoder;
033 import org.apache.directory.shared.asn1.util.IntegerDecoderException;
034 import org.apache.directory.shared.ldap.util.StringTools;
035 import org.slf4j.Logger;
036 import org.slf4j.LoggerFactory;
037
038
039 /**
040 * This class implements the Cancel operation. All the actions are declared
041 * in this class. As it is a singleton, these declaration are only done once.
042 * The grammar is :
043 *
044 * <pre>
045 * cancelRequestValue ::= SEQUENCE {
046 * cancelId MessageID
047 * -- MessageID is as defined in [RFC2251]
048 * }
049 * </pre>
050 *
051 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
052 * @version $Rev: 687720 $, $Date: 2008-08-21 14:05:50 +0200 (Thu, 21 Aug 2008) $,
053 */
054 public class CancelGrammar extends AbstractGrammar
055 {
056 /** The logger */
057 static final Logger LOG = LoggerFactory.getLogger( CancelGrammar.class );
058
059 /** Speedup for logs */
060 static final boolean IS_DEBUG = LOG.isDebugEnabled();
061
062 /** The instance of grammar. CancelGrammar is a singleton */
063 private static IGrammar instance = new CancelGrammar();
064
065
066 /**
067 * Creates a new GracefulDisconnectGrammar object.
068 */
069 private CancelGrammar()
070 {
071 name = CancelGrammar.class.getName();
072 statesEnum = CancelStatesEnum.getInstance();
073
074 // Create the transitions table
075 super.transitions = new GrammarTransition[CancelStatesEnum.LAST_CANCEL_STATE][256];
076
077 /**
078 * Transition from init state to cancel sequence
079 * cancelRequestValue ::= SEQUENCE {
080 * ...
081 *
082 * Creates the Cancel object
083 */
084 super.transitions[IStates.INIT_GRAMMAR_STATE][UniversalTag.SEQUENCE_TAG] =
085 new GrammarTransition( IStates.INIT_GRAMMAR_STATE,
086 CancelStatesEnum.CANCEL_SEQUENCE_STATE,
087 UniversalTag.SEQUENCE_TAG,
088 new GrammarAction(
089 "Init Cancel" )
090 {
091 public void action( IAsn1Container container )
092 {
093 CancelContainer cancelContainer = ( CancelContainer ) container;
094 Cancel cancel = new Cancel();
095 cancelContainer.setCancel( cancel );
096 }
097 } );
098
099 /**
100 * Transition from cancel SEQ to cancelId
101 *
102 * cancelRequestValue ::= SEQUENCE {
103 * cancelId MessageID
104 * }
105 *
106 * Set the cancelId value into the Cancel object.
107 */
108 super.transitions[CancelStatesEnum.CANCEL_SEQUENCE_STATE][UniversalTag.INTEGER_TAG] =
109 new GrammarTransition( CancelStatesEnum.CANCEL_SEQUENCE_STATE,
110 CancelStatesEnum.CANCEL_ID_STATE,
111 UniversalTag.INTEGER_TAG,
112 new GrammarAction( "Stores CancelId" )
113 {
114 public void action( IAsn1Container container ) throws DecoderException
115 {
116 CancelContainer cancelContainer = ( CancelContainer ) container;
117 Value value = cancelContainer.getCurrentTLV().getValue();
118
119 try
120 {
121 int cancelId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
122
123 if ( IS_DEBUG )
124 {
125 LOG.debug( "CancelId = " + cancelId );
126 }
127
128 cancelContainer.getCancel().setCancelId( cancelId );
129 cancelContainer.grammarEndAllowed( true );
130 }
131 catch ( IntegerDecoderException e )
132 {
133 String msg = "failed to decode the cancelId, the value should be between 0 and 2^31-1, " +
134 "it is '" + StringTools.dumpBytes( value.getData() ) + "'";
135 LOG.error( msg );
136 throw new DecoderException( msg );
137 }
138 }
139 });
140 }
141
142
143 /**
144 * This class is a singleton.
145 *
146 * @return An instance on this grammar
147 */
148 public static IGrammar getInstance()
149 {
150 return instance;
151 }
152 }