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 *    https://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 */
020package org.apache.directory.api.ldap.extras.controls.ad_impl;
021
022import org.apache.directory.api.asn1.DecoderException;
023import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
024import org.apache.directory.api.asn1.ber.grammar.Grammar;
025import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
026import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
027import org.apache.directory.api.asn1.ber.tlv.BerValue;
028import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder;
029import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException;
030import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
031import org.apache.directory.api.i18n.I18n;
032import org.apache.directory.api.util.Strings;
033import org.slf4j.Logger;
034import org.slf4j.LoggerFactory;
035
036
037/**
038 *
039 * Implementation of AdDirSync Request Control. All the actions are declared in
040 * this class. As it is a singleton, these declaration are only done once.
041 *
042 *  The decoded grammar is as follows :
043 *
044 *  <pre>
045 * realReplControlValue ::= SEQUENCE {
046 *     parentsFirst          integer
047 *     maxAttributeCount     integer
048 *     cookie                OCTET STRING
049 * }
050 * </pre>
051 *
052 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
053 */
054public final class AdDirSyncRequestGrammar extends AbstractGrammar<AdDirSyncRequestContainer>
055{
056
057    /** the logger */
058    private static final Logger LOG = LoggerFactory.getLogger( AdDirSyncRequestGrammar.class );
059
060    /** AdDirSyncRequestControlGrammar singleton instance */
061    private static final AdDirSyncRequestGrammar INSTANCE = new AdDirSyncRequestGrammar();
062
063
064    /**
065     *
066     * Creates a new instance of AdDirSyncRequestControlGrammar.
067     *
068     */
069    @SuppressWarnings("unchecked")
070    private AdDirSyncRequestGrammar()
071    {
072        setName( AdDirSyncRequestGrammar.class.getName() );
073
074        super.transitions = new GrammarTransition[AdDirSyncRequestStatesEnum.LAST_AD_DIR_SYNC_REQUEST_STATE.ordinal()][256];
075
076        /**
077         * Transition from initial state to AdDirSyncRequest sequence
078         * AdDirSync ::= SEQUENCE {
079         *     ...
080         *
081         * Initialize the adDirSyncRequest object
082         */
083        super.transitions[AdDirSyncRequestStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
084            new GrammarTransition<AdDirSyncRequestContainer>(
085            AdDirSyncRequestStatesEnum.START_STATE, AdDirSyncRequestStatesEnum.AD_DIR_SYNC_REQUEST_SEQUENCE_STATE,
086            UniversalTag.SEQUENCE.getValue(),
087            new GrammarAction<AdDirSyncRequestContainer>( "Initialization" )
088            {
089                @Override
090                public void action( AdDirSyncRequestContainer container ) throws DecoderException
091                {
092                }
093            } );
094
095
096        /**
097         * transition from start to parentsFirst
098         * realReplControlValue ::= SEQUENCE {
099         *     parentsFirst          integer
100         *    ....
101         * }
102         */
103        super.transitions[AdDirSyncRequestStatesEnum.AD_DIR_SYNC_REQUEST_SEQUENCE_STATE.ordinal()][UniversalTag.INTEGER
104            .getValue()] =
105            new GrammarTransition<AdDirSyncRequestContainer>( AdDirSyncRequestStatesEnum.AD_DIR_SYNC_REQUEST_SEQUENCE_STATE,
106                AdDirSyncRequestStatesEnum.PARENTS_FIRST_STATE, UniversalTag.INTEGER.getValue(),
107                new GrammarAction<AdDirSyncRequestContainer>( "Set AdDirSyncRequestControl parentsFirst" )
108                {
109                    @Override
110                    public void action( AdDirSyncRequestContainer container ) throws DecoderException
111                    {
112                        BerValue value = container.getCurrentTLV().getValue();
113
114                        try
115                        {
116                            int parentsFirst = IntegerDecoder.parse( value );
117
118                            if ( LOG.isDebugEnabled() )
119                            {
120                                LOG.debug( I18n.msg( I18n.MSG_08108_PARENTS_FIRST, parentsFirst ) );
121                            }
122
123                            container.getAdDirSyncRequest().setParentsFirst( parentsFirst );
124                        }
125                        catch ( IntegerDecoderException ide )
126                        {
127                            String msg = I18n.err( I18n.ERR_08107_AD_DIR_SYNC_PARENTS_FIRST_DECODING_ERROR, ide.getMessage() );
128                            LOG.error( msg, ide );
129                            throw new DecoderException( msg, ide );
130                        }
131                    }
132                } );
133
134
135        /**
136         * transition from flag to maxAttributeCount
137         * realReplControlValue ::= SEQUENCE {
138         *     parentsFirst          integer
139         *     maxAttributeCount     integer
140         *    ....
141         * }
142         */
143        super.transitions[AdDirSyncRequestStatesEnum.PARENTS_FIRST_STATE.ordinal()][UniversalTag.INTEGER
144            .getValue()] =
145            new GrammarTransition<AdDirSyncRequestContainer>( AdDirSyncRequestStatesEnum.PARENTS_FIRST_STATE,
146                AdDirSyncRequestStatesEnum.MAX_ATTRIBUTE_COUNT_STATE, UniversalTag.INTEGER.getValue(),
147                new GrammarAction<AdDirSyncRequestContainer>( "Set AdDirSyncRequestControl maxAttributeCount" )
148                {
149                    @Override
150                    public void action( AdDirSyncRequestContainer container ) throws DecoderException
151                    {
152                        BerValue value = container.getCurrentTLV().getValue();
153
154                        try
155                        {
156                            int maxAttributeCount = IntegerDecoder.parse( value );
157
158                            if ( LOG.isDebugEnabled() )
159                            {
160                                LOG.debug( I18n.msg( I18n.MSG_08109_MAX_ATTRIBUTE_COUNT, maxAttributeCount ) );
161                            }
162
163                            container.getAdDirSyncRequest().setMaxAttributeCount( maxAttributeCount );
164                        }
165                        catch ( IntegerDecoderException ide )
166                        {
167                            String msg = I18n.err( I18n.ERR_08108_AD_DIR_SYNC_MAX_ATTRIBUTE_COUNT_DECODING_ERROR, ide.getMessage() );
168                            LOG.error( msg, ide );
169                            throw new DecoderException( msg, ide );
170                        }
171                    }
172                } );
173
174
175        /**
176         * transition from maxAttributeCount to cookie
177         *     ...
178         *     maxAttributeCount         integer
179         *     cookie                  OCTET STRING
180         * }
181         */
182        super.transitions[AdDirSyncRequestStatesEnum.MAX_ATTRIBUTE_COUNT_STATE.ordinal()][UniversalTag.OCTET_STRING
183            .getValue()] =
184            new GrammarTransition<AdDirSyncRequestContainer>( AdDirSyncRequestStatesEnum.MAX_ATTRIBUTE_COUNT_STATE,
185                AdDirSyncRequestStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING.getValue(),
186                new GrammarAction<AdDirSyncRequestContainer>( "Set AdDirSyncRequestControl cookie" )
187                {
188                    @Override
189                    public void action( AdDirSyncRequestContainer container )
190                    {
191                        BerValue value = container.getCurrentTLV().getValue();
192
193                        byte[] cookie = value.getData();
194
195                        if ( LOG.isDebugEnabled() )
196                        {
197                            LOG.debug( I18n.msg( I18n.MSG_08000_COOKIE, Strings.dumpBytes( cookie ) ) );
198                        }
199
200                        container.getAdDirSyncRequest().setCookie( cookie );
201
202                        container.setGrammarEndAllowed( true );
203                    }
204                } );
205    }
206
207
208    /**
209     * @return the singleton instance of the AdDirSyncControlGrammar
210     */
211    public static Grammar<AdDirSyncRequestContainer> getInstance()
212    {
213        return INSTANCE;
214    }
215}