View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.api.ldap.codec.api;
21  
22  
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import org.apache.directory.api.asn1.Asn1Object;
27  import org.apache.directory.api.ldap.codec.decorators.AbandonRequestDecorator;
28  import org.apache.directory.api.ldap.codec.decorators.AddRequestDecorator;
29  import org.apache.directory.api.ldap.codec.decorators.AddResponseDecorator;
30  import org.apache.directory.api.ldap.codec.decorators.BindRequestDecorator;
31  import org.apache.directory.api.ldap.codec.decorators.BindResponseDecorator;
32  import org.apache.directory.api.ldap.codec.decorators.CompareRequestDecorator;
33  import org.apache.directory.api.ldap.codec.decorators.CompareResponseDecorator;
34  import org.apache.directory.api.ldap.codec.decorators.DeleteRequestDecorator;
35  import org.apache.directory.api.ldap.codec.decorators.DeleteResponseDecorator;
36  import org.apache.directory.api.ldap.codec.decorators.IntermediateResponseDecorator;
37  import org.apache.directory.api.ldap.codec.decorators.ModifyDnRequestDecorator;
38  import org.apache.directory.api.ldap.codec.decorators.ModifyDnResponseDecorator;
39  import org.apache.directory.api.ldap.codec.decorators.ModifyRequestDecorator;
40  import org.apache.directory.api.ldap.codec.decorators.ModifyResponseDecorator;
41  import org.apache.directory.api.ldap.codec.decorators.SearchRequestDecorator;
42  import org.apache.directory.api.ldap.codec.decorators.SearchResultDoneDecorator;
43  import org.apache.directory.api.ldap.codec.decorators.SearchResultEntryDecorator;
44  import org.apache.directory.api.ldap.codec.decorators.SearchResultReferenceDecorator;
45  import org.apache.directory.api.ldap.codec.decorators.UnbindRequestDecorator;
46  import org.apache.directory.api.ldap.model.message.AbandonRequest;
47  import org.apache.directory.api.ldap.model.message.AddRequest;
48  import org.apache.directory.api.ldap.model.message.AddResponse;
49  import org.apache.directory.api.ldap.model.message.BindRequest;
50  import org.apache.directory.api.ldap.model.message.BindResponse;
51  import org.apache.directory.api.ldap.model.message.CompareRequest;
52  import org.apache.directory.api.ldap.model.message.CompareResponse;
53  import org.apache.directory.api.ldap.model.message.Control;
54  import org.apache.directory.api.ldap.model.message.DeleteRequest;
55  import org.apache.directory.api.ldap.model.message.DeleteResponse;
56  import org.apache.directory.api.ldap.model.message.ExtendedRequest;
57  import org.apache.directory.api.ldap.model.message.ExtendedResponse;
58  import org.apache.directory.api.ldap.model.message.IntermediateResponse;
59  import org.apache.directory.api.ldap.model.message.Message;
60  import org.apache.directory.api.ldap.model.message.MessageTypeEnum;
61  import org.apache.directory.api.ldap.model.message.ModifyDnRequest;
62  import org.apache.directory.api.ldap.model.message.ModifyDnResponse;
63  import org.apache.directory.api.ldap.model.message.ModifyRequest;
64  import org.apache.directory.api.ldap.model.message.ModifyResponse;
65  import org.apache.directory.api.ldap.model.message.SearchRequest;
66  import org.apache.directory.api.ldap.model.message.SearchResultDone;
67  import org.apache.directory.api.ldap.model.message.SearchResultEntry;
68  import org.apache.directory.api.ldap.model.message.SearchResultReference;
69  import org.apache.directory.api.ldap.model.message.UnbindRequest;
70  
71  
72  /**
73   * A decorator for the generic LDAP Message
74   *
75   * @TODO make this class abstract, after finishing switch and all types and make default blow an EncoderException
76   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
77   */
78  public abstract class MessageDecorator<E extends Message> implements Message, Decorator<E>, Asn1Object
79  {
80      /** The decorated Control */
81      private final E decoratedMessage;
82  
83      /** Map of message controls using OID Strings for keys and Control values */
84      private final Map<String, Control> controls;
85  
86      /** The current control */
87      private CodecControl<? extends Control> currentControl;
88  
89      /** The encoded Message length */
90      protected int messageLength;
91  
92      /** The length of the controls */
93      private int controlsLength;
94  
95      /** The LdapCodecService */
96      private final LdapApiService codec;
97  
98  
99      public static MessageDecorator<? extends Message> getDecorator( LdapApiService codec, Message decoratedMessage )
100     {
101         if ( decoratedMessage instanceof MessageDecorator )
102         {
103             return ( MessageDecorator<?> ) decoratedMessage;
104         }
105 
106         MessageDecorator<?> decorator = null;
107 
108         switch ( decoratedMessage.getType() )
109         {
110             case ABANDON_REQUEST:
111                 decorator = new AbandonRequestDecorator( codec, ( AbandonRequest ) decoratedMessage );
112                 break;
113 
114             case ADD_REQUEST:
115                 decorator = new AddRequestDecorator( codec, ( AddRequest ) decoratedMessage );
116                 break;
117 
118             case ADD_RESPONSE:
119                 decorator = new AddResponseDecorator( codec, ( AddResponse ) decoratedMessage );
120                 break;
121 
122             case BIND_REQUEST:
123                 decorator = new BindRequestDecorator( codec, ( BindRequest ) decoratedMessage );
124                 break;
125 
126             case BIND_RESPONSE:
127                 decorator = new BindResponseDecorator( codec, ( BindResponse ) decoratedMessage );
128                 break;
129 
130             case COMPARE_REQUEST:
131                 decorator = new CompareRequestDecorator( codec, ( CompareRequest ) decoratedMessage );
132                 break;
133 
134             case COMPARE_RESPONSE:
135                 decorator = new CompareResponseDecorator( codec, ( CompareResponse ) decoratedMessage );
136                 break;
137 
138             case DEL_REQUEST:
139                 decorator = new DeleteRequestDecorator( codec, ( DeleteRequest ) decoratedMessage );
140                 break;
141 
142             case DEL_RESPONSE:
143                 decorator = new DeleteResponseDecorator( codec, ( DeleteResponse ) decoratedMessage );
144                 break;
145 
146             case EXTENDED_REQUEST:
147                 decorator = codec.decorate( ( ExtendedRequest ) decoratedMessage );
148                 break;
149 
150             case EXTENDED_RESPONSE:
151                 decorator = codec.decorate( ( ExtendedResponse ) decoratedMessage );
152                 break;
153 
154             case INTERMEDIATE_RESPONSE:
155                 decorator = new IntermediateResponseDecorator( codec, ( IntermediateResponse ) decoratedMessage );
156                 break;
157 
158             case MODIFY_REQUEST:
159                 decorator = new ModifyRequestDecorator( codec, ( ModifyRequest ) decoratedMessage );
160                 break;
161 
162             case MODIFY_RESPONSE:
163                 decorator = new ModifyResponseDecorator( codec, ( ModifyResponse ) decoratedMessage );
164                 break;
165 
166             case MODIFYDN_REQUEST:
167                 decorator = new ModifyDnRequestDecorator( codec, ( ModifyDnRequest ) decoratedMessage );
168                 break;
169 
170             case MODIFYDN_RESPONSE:
171                 decorator = new ModifyDnResponseDecorator( codec, ( ModifyDnResponse ) decoratedMessage );
172                 break;
173 
174             case SEARCH_REQUEST:
175                 decorator = new SearchRequestDecorator( codec, ( SearchRequest ) decoratedMessage );
176                 break;
177 
178             case SEARCH_RESULT_DONE:
179                 decorator = new SearchResultDoneDecorator( codec, ( SearchResultDone ) decoratedMessage );
180                 break;
181 
182             case SEARCH_RESULT_ENTRY:
183                 decorator = new SearchResultEntryDecorator( codec, ( SearchResultEntry ) decoratedMessage );
184                 break;
185 
186             case SEARCH_RESULT_REFERENCE:
187                 decorator = new SearchResultReferenceDecorator( codec, ( SearchResultReference ) decoratedMessage );
188                 break;
189 
190             case UNBIND_REQUEST:
191                 decorator = new UnbindRequestDecorator( codec, ( UnbindRequest ) decoratedMessage );
192                 break;
193 
194             default:
195                 return null;
196         }
197 
198         Map<String, Control> controls = decoratedMessage.getControls();
199 
200         if ( controls != null )
201         {
202             for ( Control control : controls.values() )
203             {
204                 decorator.addControl( control );
205             }
206         }
207 
208         return decorator;
209     }
210 
211 
212     /**
213      * Makes a Message an Decorator object.
214      */
215     protected MessageDecorator( LdapApiService codec, E decoratedMessage )
216     {
217         this.codec = codec;
218         this.decoratedMessage = decoratedMessage;
219         controls = new HashMap<String, Control>();
220     }
221 
222 
223     /**
224      * @param controlsLength the encoded controls length
225      */
226     public void setControlsLength( int controlsLength )
227     {
228         this.controlsLength = controlsLength;
229     }
230 
231 
232     /**
233      * @return the encoded controls length
234      */
235     public int getControlsLength()
236     {
237         return controlsLength;
238     }
239 
240 
241     /**
242      * @param messageLength The encoded message length
243      */
244     public void setMessageLength( int messageLength )
245     {
246         this.messageLength = messageLength;
247     }
248 
249 
250     /**
251      * @return The encoded message length
252      */
253     public int getMessageLength()
254     {
255         return messageLength;
256     }
257 
258 
259     /**
260      * Get the current Control Object
261      * 
262      * @return The current Control Object
263      */
264     public CodecControl<? extends Control> getCurrentControl()
265     {
266         return currentControl;
267     }
268 
269 
270     //-------------------------------------------------------------------------
271     // The Message methods
272     //-------------------------------------------------------------------------
273 
274     /**
275      * {@inheritDoc}
276      */
277     public MessageTypeEnum getType()
278     {
279         return decoratedMessage.getType();
280     }
281 
282 
283     /**
284      * {@inheritDoc}
285      */
286     public Map<String, Control> getControls()
287     {
288         return controls;
289     }
290 
291 
292     /**
293      * {@inheritDoc}
294      */
295     public Control getControl( String oid )
296     {
297         return controls.get( oid );
298     }
299 
300 
301     /**
302      * {@inheritDoc}
303      */
304     public boolean hasControl( String oid )
305     {
306         return controls.containsKey( oid );
307     }
308 
309 
310     /**
311      * {@inheritDoc}
312      */
313     @SuppressWarnings("unchecked")
314     public Message addControl( Control control )
315     {
316         Control decorated;
317         CodecControl<? extends Control> controlDecorator;
318 
319         if ( control instanceof ControlDecorator )
320         {
321             controlDecorator = ( org.apache.directory.api.ldap.codec.api.CodecControl<? extends Control> ) control;
322             decorated = controlDecorator.getDecorated();
323         }
324         else
325         {
326             controlDecorator = codec.newControl( control );
327             decorated = control;
328         }
329 
330         decoratedMessage.addControl( decorated );
331         controls.put( control.getOid(), controlDecorator );
332         currentControl = controlDecorator;
333 
334         return this;
335     }
336 
337 
338     /**
339      * {@inheritDoc}
340      */
341     public Message addAllControls( Control[] controls )
342     {
343         for ( Control control : controls )
344         {
345             addControl( control );
346         }
347 
348         return this;
349     }
350 
351 
352     /**
353      * {@inheritDoc}
354      */
355     public Message removeControl( Control control )
356     {
357         decoratedMessage.removeControl( control );
358         controls.remove( control.getOid() );
359 
360         return this;
361     }
362 
363 
364     /**
365      * {@inheritDoc}
366      */
367     public int getMessageId()
368     {
369         return decoratedMessage.getMessageId();
370     }
371 
372 
373     /**
374      * {@inheritDoc}
375      */
376     public Object get( Object key )
377     {
378         return decoratedMessage.get( key );
379     }
380 
381 
382     /**
383      * {@inheritDoc}
384      */
385     public Object put( Object key, Object value )
386     {
387         return decoratedMessage.put( key, value );
388     }
389 
390 
391     /**
392      * {@inheritDoc}
393      */
394     public Message setMessageId( int messageId )
395     {
396         decoratedMessage.setMessageId( messageId );
397 
398         return this;
399     }
400 
401 
402     /**
403      * Delegates to the toString() method of the decorated Message.
404      */
405     public String toString()
406     {
407         return decoratedMessage.toString();
408     }
409 
410 
411     /**
412      * {@inheritDoc}
413      */
414     public E getDecorated()
415     {
416         return decoratedMessage;
417     }
418 
419 
420     /**
421      * {@inheritDoc}
422      */
423     public LdapApiService getCodecService()
424     {
425         return codec;
426     }
427 }