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 static final boolean IS_DEBUG = LOG.isDebugEnabled();
56
57
58 private static Grammar<?> instance = new EntryChangeGrammar();
59
60
61
62
63
64 @SuppressWarnings("unchecked")
65 private EntryChangeGrammar()
66 {
67 setName( EntryChangeGrammar.class.getName() );
68
69
70 super.transitions = new GrammarTransition[EntryChangeStates.LAST_EC_STATE.ordinal()][256];
71
72
73
74
75
76
77
78
79 super.transitions[EntryChangeStates.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
80 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.START_STATE,
81 EntryChangeStates.EC_SEQUENCE_STATE,
82 UniversalTag.SEQUENCE.getValue(), null );
83
84
85
86
87
88
89
90
91
92 super.transitions[EntryChangeStates.EC_SEQUENCE_STATE.ordinal()][UniversalTag.ENUMERATED.getValue()] =
93 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.EC_SEQUENCE_STATE,
94 EntryChangeStates.CHANGE_TYPE_STATE,
95 UniversalTag.ENUMERATED.getValue(),
96 new GrammarAction<EntryChangeContainer>( "Set EntryChangeControl changeType" )
97 {
98 public void action( EntryChangeContainer container ) throws DecoderException
99 {
100 BerValue value = container.getCurrentTLV().getValue();
101
102 try
103 {
104 int change = IntegerDecoder.parse( value, 1, 8 );
105
106 switch ( ChangeType.getChangeType( change ) )
107 {
108 case ADD:
109 case DELETE:
110 case MODDN:
111 case MODIFY:
112 ChangeType changeType = ChangeType.getChangeType( change );
113
114 if ( IS_DEBUG )
115 {
116 LOG.debug( "changeType = " + changeType );
117 }
118
119 container.getEntryChangeDecorator().setChangeType( changeType );
120 break;
121
122 default:
123 String msg = I18n.err( I18n.ERR_04044 );
124 LOG.error( msg );
125 throw new DecoderException( msg );
126 }
127
128
129 container.setGrammarEndAllowed( true );
130 }
131 catch ( IntegerDecoderException ide )
132 {
133 String msg = I18n.err( I18n.ERR_04044 );
134 LOG.error( msg, ide );
135 throw new DecoderException( msg, ide );
136 }
137 catch ( IllegalArgumentException iae )
138 {
139 throw new DecoderException( iae.getLocalizedMessage(), iae );
140 }
141 }
142 } );
143
144
145
146
147
148
149
150
151
152
153
154 super.transitions[EntryChangeStates.CHANGE_TYPE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] =
155 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.CHANGE_TYPE_STATE,
156 EntryChangeStates.PREVIOUS_DN_STATE,
157 UniversalTag.OCTET_STRING.getValue(),
158 new GrammarAction<EntryChangeContainer>( "Set EntryChangeControl previousDN" )
159 {
160 public void action( EntryChangeContainer container ) throws DecoderException
161 {
162 ChangeType changeType = container.getEntryChangeDecorator().getChangeType();
163
164 if ( changeType != ChangeType.MODDN )
165 {
166 LOG.error( I18n.err( I18n.ERR_04045 ) );
167 throw new DecoderException( I18n.err( I18n.ERR_04046 ) );
168 }
169 else
170 {
171 BerValue value = container.getCurrentTLV().getValue();
172 Dn previousDn;
173
174 try
175 {
176 previousDn = new Dn( Strings.utf8ToString( value.getData() ) );
177 }
178 catch ( LdapInvalidDnException ine )
179 {
180 LOG.error( I18n.err( I18n.ERR_04047, Strings.dumpBytes( value.getData() ) ) );
181 throw new DecoderException( I18n.err( I18n.ERR_04048 ), ine );
182 }
183
184 if ( IS_DEBUG )
185 {
186 LOG.debug( "previousDN = " + previousDn );
187 }
188
189 container.getEntryChangeDecorator().setPreviousDn( previousDn );
190
191
192 container.setGrammarEndAllowed( true );
193 }
194 }
195 } );
196
197
198 GrammarAction<EntryChangeContainer> setChangeNumberAction = new GrammarAction<EntryChangeContainer>(
199 "Set EntryChangeControl changeNumber" )
200 {
201 public void action( EntryChangeContainer container ) throws DecoderException
202 {
203 BerValue value = container.getCurrentTLV().getValue();
204
205 try
206 {
207 long changeNumber = LongDecoder.parse( value );
208
209 if ( IS_DEBUG )
210 {
211 LOG.debug( "changeNumber = " + changeNumber );
212 }
213
214 container.getEntryChangeDecorator().setChangeNumber( changeNumber );
215
216
217 container.setGrammarEndAllowed( true );
218 }
219 catch ( LongDecoderException lde )
220 {
221 String msg = I18n.err( I18n.ERR_04049 );
222 LOG.error( msg, lde );
223 throw new DecoderException( msg, lde );
224 }
225 }
226 };
227
228
229
230
231
232
233
234
235
236
237 super.transitions[EntryChangeStates.PREVIOUS_DN_STATE.ordinal()][UniversalTag.INTEGER.getValue()] =
238 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.PREVIOUS_DN_STATE,
239 EntryChangeStates.CHANGE_NUMBER_STATE,
240 UniversalTag.INTEGER.getValue(),
241 setChangeNumberAction );
242
243
244
245
246
247
248
249
250
251
252 super.transitions[EntryChangeStates.CHANGE_TYPE_STATE.ordinal()][UniversalTag.INTEGER.getValue()] =
253 new GrammarTransition<EntryChangeContainer>( EntryChangeStates.CHANGE_TYPE_STATE,
254 EntryChangeStates.CHANGE_NUMBER_STATE,
255 UniversalTag.INTEGER.getValue(),
256 setChangeNumberAction );
257 }
258
259
260
261
262
263
264
265 public static Grammar<?> getInstance()
266 {
267 return instance;
268 }
269 }