1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.codec.controls.search.entryChange;
21
22
23 import org.apache.directory.api.asn1.DecoderException;
24 import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
25 import org.apache.directory.api.asn1.ber.grammar.Grammar;
26 import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
27 import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
28 import org.apache.directory.api.asn1.ber.tlv.BerValue;
29 import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder;
30 import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException;
31 import org.apache.directory.api.asn1.ber.tlv.LongDecoder;
32 import org.apache.directory.api.asn1.ber.tlv.LongDecoderException;
33 import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
34 import org.apache.directory.api.i18n.I18n;
35 import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
36 import org.apache.directory.api.ldap.model.message.controls.ChangeType;
37 import org.apache.directory.api.ldap.model.name.Dn;
38 import org.apache.directory.api.util.Strings;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45
46
47
48
49 public final class EntryChangeGrammar extends AbstractGrammar<EntryChangeContainer>
50 {
51
52 static final Logger LOG = LoggerFactory.getLogger( EntryChangeGrammar.class );
53
54
55 private static Grammar<?> instance = new EntryChangeGrammar();
56
57
58
59
60
61 @SuppressWarnings("unchecked")
62 private EntryChangeGrammar()
63 {
64 setName( EntryChangeGrammar.class.getName() );
65
66
67 super.transitions = new GrammarTransition[EntryChangeStates.LAST_EC_STATE.ordinal()][256];
68
69
70
71
72
73
74
75
76 super.transitions[EntryChangeStates.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
77 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.START_STATE,
78 EntryChangeStates.EC_SEQUENCE_STATE,
79 UniversalTag.SEQUENCE.getValue(), null );
80
81
82
83
84
85
86
87
88
89 super.transitions[EntryChangeStates.EC_SEQUENCE_STATE.ordinal()][UniversalTag.ENUMERATED.getValue()] =
90 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.EC_SEQUENCE_STATE,
91 EntryChangeStates.CHANGE_TYPE_STATE,
92 UniversalTag.ENUMERATED.getValue(),
93 new GrammarAction<EntryChangeContainer>( "Set EntryChangeControl changeType" )
94 {
95 public void action( EntryChangeContainer container ) throws DecoderException
96 {
97 BerValue value = container.getCurrentTLV().getValue();
98
99 try
100 {
101 int change = IntegerDecoder.parse( value, 1, 8 );
102
103 switch ( ChangeType.getChangeType( change ) )
104 {
105 case ADD:
106 case DELETE:
107 case MODDN:
108 case MODIFY:
109 ChangeType changeType = ChangeType.getChangeType( change );
110
111 if ( LOG.isDebugEnabled() )
112 {
113 LOG.debug( I18n.msg( I18n.MSG_05300_CHANGE_TYPE, changeType ) );
114 }
115
116 container.getEntryChange().setChangeType( changeType );
117 break;
118
119 default:
120 String msg = I18n.err( I18n.ERR_05300_CANT_DECODE_CHANGE_TYPE );
121 LOG.error( msg );
122 throw new DecoderException( msg );
123 }
124
125
126 container.setGrammarEndAllowed( true );
127 }
128 catch ( IntegerDecoderException ide )
129 {
130 String msg = I18n.err( I18n.ERR_05300_CANT_DECODE_CHANGE_TYPE );
131 LOG.error( msg, ide );
132 throw new DecoderException( msg, ide );
133 }
134 catch ( IllegalArgumentException iae )
135 {
136 throw new DecoderException( iae.getLocalizedMessage(), iae );
137 }
138 }
139 } );
140
141
142
143
144
145
146
147
148
149
150
151 super.transitions[EntryChangeStates.CHANGE_TYPE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] =
152 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.CHANGE_TYPE_STATE,
153 EntryChangeStates.PREVIOUS_DN_STATE,
154 UniversalTag.OCTET_STRING.getValue(),
155 new GrammarAction<EntryChangeContainer>( "Set EntryChangeControl previousDN" )
156 {
157 public void action( EntryChangeContainer container ) throws DecoderException
158 {
159 ChangeType changeType = container.getEntryChange().getChangeType();
160
161 if ( changeType != ChangeType.MODDN )
162 {
163 LOG.error( I18n.err( I18n.ERR_05301_INVALID_PREVIOUS_DN ) );
164 throw new DecoderException( I18n.err( I18n.ERR_05302_PREVIOUS_DN_NOT_ALLOWED ) );
165 }
166 else
167 {
168 BerValue value = container.getCurrentTLV().getValue();
169 Dn previousDn;
170
171 try
172 {
173 previousDn = new Dn( Strings.utf8ToString( value.getData() ) );
174 }
175 catch ( LdapInvalidDnException ine )
176 {
177 LOG.error( I18n.err( I18n.ERR_05303_BAD_PREVIOUS_DN, Strings.dumpBytes( value.getData() ) ) );
178 throw new DecoderException( I18n.err( I18n.ERR_05304_FAILED_TO_DECODE_PREVIOUS_DN ), ine );
179 }
180
181 if ( LOG.isDebugEnabled() )
182 {
183 LOG.debug( I18n.msg( I18n.MSG_05301_PREVIOUS_DN, previousDn ) );
184 }
185
186 container.getEntryChange().setPreviousDn( previousDn );
187
188
189 container.setGrammarEndAllowed( true );
190 }
191 }
192 } );
193
194
195 GrammarAction<EntryChangeContainer> setChangeNumberAction = new GrammarAction<EntryChangeContainer>(
196 "Set EntryChangeControl changeNumber" )
197 {
198 public void action( EntryChangeContainer container ) throws DecoderException
199 {
200 BerValue value = container.getCurrentTLV().getValue();
201
202 try
203 {
204 long changeNumber = LongDecoder.parse( value );
205
206 if ( LOG.isDebugEnabled() )
207 {
208 LOG.debug( I18n.msg( I18n.MSG_05302_CHANGE_NUMBER, changeNumber ) );
209 }
210
211 container.getEntryChange().setChangeNumber( changeNumber );
212
213
214 container.setGrammarEndAllowed( true );
215 }
216 catch ( LongDecoderException lde )
217 {
218 String msg = I18n.err( I18n.ERR_05305_CHANGE_NUMBER_DECODING_ERROR );
219 LOG.error( msg, lde );
220 throw new DecoderException( msg, lde );
221 }
222 }
223 };
224
225
226
227
228
229
230
231
232
233
234 super.transitions[EntryChangeStates.PREVIOUS_DN_STATE.ordinal()][UniversalTag.INTEGER.getValue()] =
235 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.PREVIOUS_DN_STATE,
236 EntryChangeStates.CHANGE_NUMBER_STATE,
237 UniversalTag.INTEGER.getValue(),
238 setChangeNumberAction );
239
240
241
242
243
244
245
246
247
248
249 super.transitions[EntryChangeStates.CHANGE_TYPE_STATE.ordinal()][UniversalTag.INTEGER.getValue()] =
250 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.CHANGE_TYPE_STATE,
251 EntryChangeStates.CHANGE_NUMBER_STATE,
252 UniversalTag.INTEGER.getValue(),
253 setChangeNumberAction );
254 }
255
256
257
258
259
260
261
262 public static Grammar<?> getInstance()
263 {
264 return instance;
265 }
266 }