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.i18n.I18n;
035 import org.apache.directory.shared.ldap.util.StringTools;
036 import org.slf4j.Logger;
037 import org.slf4j.LoggerFactory;
038
039
040 /**
041 * This class implements the Cancel operation. All the actions are declared
042 * in this class. As it is a singleton, these declaration are only done once.
043 * The grammar is :
044 *
045 * <pre>
046 * cancelRequestValue ::= SEQUENCE {
047 * cancelId MessageID
048 * -- MessageID is as defined in [RFC2251]
049 * }
050 * </pre>
051 *
052 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
053 * @version $Rev: 687720 $, $Date: 2008-08-21 14:05:50 +0200 (Thu, 21 Aug 2008) $,
054 */
055 public class CancelGrammar extends AbstractGrammar
056 {
057 /** The logger */
058 static final Logger LOG = LoggerFactory.getLogger( CancelGrammar.class );
059
060 /** Speedup for logs */
061 static final boolean IS_DEBUG = LOG.isDebugEnabled();
062
063 /** The instance of grammar. CancelGrammar is a singleton */
064 private static IGrammar instance = new CancelGrammar();
065
066
067 /**
068 * Creates a new GracefulDisconnectGrammar object.
069 */
070 private CancelGrammar()
071 {
072 name = CancelGrammar.class.getName();
073 statesEnum = CancelStatesEnum.getInstance();
074
075 // Create the transitions table
076 super.transitions = new GrammarTransition[CancelStatesEnum.LAST_CANCEL_STATE][256];
077
078 /**
079 * Transition from init state to cancel sequence
080 * cancelRequestValue ::= SEQUENCE {
081 * ...
082 *
083 * Creates the Cancel object
084 */
085 super.transitions[IStates.INIT_GRAMMAR_STATE][UniversalTag.SEQUENCE_TAG] =
086 new GrammarTransition( IStates.INIT_GRAMMAR_STATE,
087 CancelStatesEnum.CANCEL_SEQUENCE_STATE,
088 UniversalTag.SEQUENCE_TAG,
089 new GrammarAction(
090 "Init Cancel" )
091 {
092 public void action( IAsn1Container container )
093 {
094 CancelContainer cancelContainer = ( CancelContainer ) container;
095 Cancel cancel = new Cancel();
096 cancelContainer.setCancel( cancel );
097 }
098 } );
099
100 /**
101 * Transition from cancel SEQ to cancelId
102 *
103 * cancelRequestValue ::= SEQUENCE {
104 * cancelId MessageID
105 * }
106 *
107 * Set the cancelId value into the Cancel object.
108 */
109 super.transitions[CancelStatesEnum.CANCEL_SEQUENCE_STATE][UniversalTag.INTEGER_TAG] =
110 new GrammarTransition( CancelStatesEnum.CANCEL_SEQUENCE_STATE,
111 CancelStatesEnum.CANCEL_ID_STATE,
112 UniversalTag.INTEGER_TAG,
113 new GrammarAction( "Stores CancelId" )
114 {
115 public void action( IAsn1Container container ) throws DecoderException
116 {
117 CancelContainer cancelContainer = ( CancelContainer ) container;
118 Value value = cancelContainer.getCurrentTLV().getValue();
119
120 try
121 {
122 int cancelId = IntegerDecoder.parse( value, 0, Integer.MAX_VALUE );
123
124 if ( IS_DEBUG )
125 {
126 LOG.debug( "CancelId = " + cancelId );
127 }
128
129 cancelContainer.getCancel().setCancelId( cancelId );
130 cancelContainer.grammarEndAllowed( true );
131 }
132 catch ( IntegerDecoderException e )
133 {
134 String msg = I18n.err( I18n.ERR_04031, 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 }