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.gracefulShutdown;
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.codec.extended.operations.GracefulActionConstants;
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 Graceful shutdown. All the actions are declared in
042 * this class. As it is a singleton, these declaration are only done once. The
043 * grammar is :
044 *
045 * <pre>
046 * GracefulShutdwon ::= SEQUENCE {
047 * timeOffline INTEGER (0..720) DEFAULT 0,
048 * delay [0] INTEGER (0..86400) DEFAULT 0
049 * }
050 * </pre>
051 *
052 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
053 * @version $Rev: 764131 $, $Date: 2009-04-11 03:03:00 +0200 (Sam, 11 avr 2009) $,
054 */
055 public class GracefulShutdownGrammar extends AbstractGrammar
056 {
057 /** The logger */
058 static final Logger log = LoggerFactory.getLogger( GracefulShutdownGrammar.class );
059
060 /** Speedup for logs */
061 static final boolean IS_DEBUG = log.isDebugEnabled();
062
063 /** The instance of grammar. GracefulShutdownGrammar is a singleton */
064 private static IGrammar instance = new GracefulShutdownGrammar();
065
066
067 /**
068 * Creates a new GracefulShutdownGrammar object.
069 */
070 private GracefulShutdownGrammar()
071 {
072 name = GracefulShutdownGrammar.class.getName();
073 statesEnum = GracefulShutdownStatesEnum.getInstance();
074
075 // Create the transitions table
076 super.transitions = new GrammarTransition[GracefulShutdownStatesEnum.LAST_GRACEFUL_SHUTDOWN_STATE][256];
077
078 /**
079 * Transition from init state to graceful shutdown
080 *
081 * GracefulShutdown ::= SEQUENCE {
082 * ...
083 *
084 * Creates the GracefulShutdown object
085 */
086 super.transitions[IStates.INIT_GRAMMAR_STATE][UniversalTag.SEQUENCE_TAG] =
087 new GrammarTransition( IStates.INIT_GRAMMAR_STATE,
088 GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE,
089 UniversalTag.SEQUENCE_TAG,
090 new GrammarAction( "Init GracefulShutdown" )
091 {
092 public void action( IAsn1Container container )
093 {
094 GracefulShutdownContainer gracefulShutdownContainer = ( GracefulShutdownContainer ) container;
095 GracefulShutdown gracefulShutdown = new GracefulShutdown();
096 gracefulShutdownContainer.setGracefulShutdown( gracefulShutdown );
097 gracefulShutdownContainer.grammarEndAllowed( true );
098 }
099 } );
100
101 /**
102 * Transition from graceful shutdown to time offline
103 *
104 * GracefulShutdown ::= SEQUENCE {
105 * timeOffline INTEGER (0..720) DEFAULT 0,
106 * ...
107 *
108 * Set the time offline value into the GracefulShutdown
109 * object.
110 */
111 super.transitions[GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE][UniversalTag.INTEGER_TAG] =
112 new GrammarTransition( GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE,
113 GracefulShutdownStatesEnum.TIME_OFFLINE_STATE,
114 UniversalTag.INTEGER_TAG,
115 new GrammarAction( "Set Graceful Shutdown time offline" )
116 {
117 public void action( IAsn1Container container ) throws DecoderException
118 {
119 GracefulShutdownContainer gracefulShutdownContainer = ( GracefulShutdownContainer ) container;
120 Value value = gracefulShutdownContainer.getCurrentTLV().getValue();
121
122 try
123 {
124 int timeOffline = IntegerDecoder.parse( value, 0, 720 );
125
126 if ( IS_DEBUG )
127 {
128 log.debug( "Time Offline = " + timeOffline );
129 }
130
131 gracefulShutdownContainer.getGracefulShutdown().setTimeOffline( timeOffline );
132 gracefulShutdownContainer.grammarEndAllowed( true );
133 }
134 catch ( IntegerDecoderException e )
135 {
136 String msg = "failed to decode the timeOffline, the value should be between 0 and 720 minutes, it is '"
137 + StringTools.dumpBytes( value.getData() ) + "'";
138 log.error( msg );
139 throw new DecoderException( msg );
140 }
141 }
142 } );
143
144 /**
145 * Transition from time offline to delay
146 *
147 * GracefulShutdown ::= SEQUENCE {
148 * ...
149 * delay [0] INTEGER (0..86400) DEFAULT 0 }
150 *
151 * Set the delay value into the GracefulShutdown
152 * object.
153 */
154 super.transitions[GracefulShutdownStatesEnum.TIME_OFFLINE_STATE][GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG] =
155 new GrammarTransition( GracefulShutdownStatesEnum.TIME_OFFLINE_STATE,
156 GracefulShutdownStatesEnum.DELAY_STATE,
157 GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG,
158
159 new GrammarAction( "Set Graceful Shutdown Delay" )
160 {
161 public void action( IAsn1Container container ) throws DecoderException
162 {
163 GracefulShutdownContainer gracefulShutdownContainer = ( GracefulShutdownContainer ) container;
164 Value value = gracefulShutdownContainer.getCurrentTLV().getValue();
165
166 try
167 {
168 int delay = IntegerDecoder.parse( value, 0, 86400 );
169
170 if ( IS_DEBUG )
171 {
172 log.debug( "Delay = " + delay );
173 }
174
175 gracefulShutdownContainer.getGracefulShutdown().setDelay( delay );
176 gracefulShutdownContainer.grammarEndAllowed( true );
177 }
178 catch ( IntegerDecoderException e )
179 {
180 String msg = "failed to decode the delay, the value should be between 0 and 86400 seconds, it is '"
181 + StringTools.dumpBytes( value.getData() ) + "'";
182 log.error( msg );
183 throw new DecoderException( msg );
184 }
185 }
186 } );
187
188 /**
189 * Transition from graceful shutdown to delay
190 *
191 * GracefulShutdown ::= SEQUENCE {
192 * ...
193 * delay [0] INTEGER (0..86400) DEFAULT 0 }
194 *
195 * Set the delay value into the GracefulShutdown
196 * object.
197 */
198 super.transitions[GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE]
199 [GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG] =
200 new GrammarTransition( GracefulShutdownStatesEnum.GRACEFUL_SHUTDOWN_SEQUENCE_STATE,
201 GracefulShutdownStatesEnum.DELAY_STATE,
202 GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG,
203
204 new GrammarAction( "Set Graceful Shutdown Delay" )
205 {
206 public void action( IAsn1Container container ) throws DecoderException
207 {
208 GracefulShutdownContainer gracefulShutdownContainer = ( GracefulShutdownContainer ) container;
209 Value value = gracefulShutdownContainer.getCurrentTLV().getValue();
210
211 try
212 {
213 int delay = IntegerDecoder.parse( value, 0, 86400 );
214
215 if ( IS_DEBUG )
216 {
217 log.debug( "Delay = " + delay );
218 }
219
220 gracefulShutdownContainer.getGracefulShutdown().setDelay( delay );
221 gracefulShutdownContainer.grammarEndAllowed( true );
222 }
223 catch ( IntegerDecoderException e )
224 {
225 String msg = "failed to decode the delay, the value should be between 0 and 86400 seconds, it is '"
226 + StringTools.dumpBytes( value.getData() ) + "'";
227 log.error( msg );
228 throw new DecoderException( msg );
229 }
230 }
231 } );
232 }
233
234
235 /**
236 * This class is a singleton.
237 *
238 * @return An instance on this grammar
239 */
240 public static IGrammar getInstance()
241 {
242 return instance;
243 }
244 }