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 */ 020package org.apache.directory.shared.ldap.codec.api; 021 022 023import java.util.HashMap; 024import java.util.Map; 025 026import org.apache.directory.shared.ldap.codec.decorators.AbandonRequestDecorator; 027import org.apache.directory.shared.ldap.codec.decorators.AddRequestDecorator; 028import org.apache.directory.shared.ldap.codec.decorators.AddResponseDecorator; 029import org.apache.directory.shared.ldap.codec.decorators.BindRequestDecorator; 030import org.apache.directory.shared.ldap.codec.decorators.BindResponseDecorator; 031import org.apache.directory.shared.ldap.codec.decorators.CompareRequestDecorator; 032import org.apache.directory.shared.ldap.codec.decorators.CompareResponseDecorator; 033import org.apache.directory.shared.ldap.codec.decorators.DeleteRequestDecorator; 034import org.apache.directory.shared.ldap.codec.decorators.DeleteResponseDecorator; 035import org.apache.directory.shared.ldap.codec.decorators.IntermediateResponseDecorator; 036import org.apache.directory.shared.ldap.codec.decorators.ModifyDnRequestDecorator; 037import org.apache.directory.shared.ldap.codec.decorators.ModifyDnResponseDecorator; 038import org.apache.directory.shared.ldap.codec.decorators.ModifyRequestDecorator; 039import org.apache.directory.shared.ldap.codec.decorators.ModifyResponseDecorator; 040import org.apache.directory.shared.ldap.codec.decorators.SearchRequestDecorator; 041import org.apache.directory.shared.ldap.codec.decorators.SearchResultDoneDecorator; 042import org.apache.directory.shared.ldap.codec.decorators.SearchResultEntryDecorator; 043import org.apache.directory.shared.ldap.codec.decorators.SearchResultReferenceDecorator; 044import org.apache.directory.shared.ldap.codec.decorators.UnbindRequestDecorator; 045import org.apache.directory.shared.ldap.model.exception.MessageException; 046import org.apache.directory.shared.ldap.model.message.AbandonRequest; 047import org.apache.directory.shared.ldap.model.message.AddRequest; 048import org.apache.directory.shared.ldap.model.message.AddResponse; 049import org.apache.directory.shared.ldap.model.message.BindRequest; 050import org.apache.directory.shared.ldap.model.message.BindResponse; 051import org.apache.directory.shared.ldap.model.message.CompareRequest; 052import org.apache.directory.shared.ldap.model.message.CompareResponse; 053import org.apache.directory.shared.ldap.model.message.Control; 054import org.apache.directory.shared.ldap.model.message.DeleteRequest; 055import org.apache.directory.shared.ldap.model.message.DeleteResponse; 056import org.apache.directory.shared.ldap.model.message.ExtendedRequest; 057import org.apache.directory.shared.ldap.model.message.ExtendedResponse; 058import org.apache.directory.shared.ldap.model.message.IntermediateResponse; 059import org.apache.directory.shared.ldap.model.message.Message; 060import org.apache.directory.shared.ldap.model.message.MessageTypeEnum; 061import org.apache.directory.shared.ldap.model.message.ModifyDnRequest; 062import org.apache.directory.shared.ldap.model.message.ModifyDnResponse; 063import org.apache.directory.shared.ldap.model.message.ModifyRequest; 064import org.apache.directory.shared.ldap.model.message.ModifyResponse; 065import org.apache.directory.shared.ldap.model.message.SearchRequest; 066import org.apache.directory.shared.ldap.model.message.SearchResultDone; 067import org.apache.directory.shared.ldap.model.message.SearchResultEntry; 068import org.apache.directory.shared.ldap.model.message.SearchResultReference; 069import org.apache.directory.shared.ldap.model.message.UnbindRequest; 070 071 072/** 073 * A decorator for the generic LDAP Message 074 * 075 * @TODO make this class abstract, after finishing switch and all types and make default blow an EncoderException 076 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 077 */ 078public abstract class MessageDecorator<E extends Message> implements Message, Decorator<E> 079{ 080 /** The decorated Control */ 081 private final E decoratedMessage; 082 083 /** Map of message controls using OID Strings for keys and Control values */ 084 private final Map<String, Control> controls; 085 086 /** The current control */ 087 private CodecControl<? extends Control> currentControl; 088 089 /** The encoded Message length */ 090 protected int messageLength; 091 092 /** The length of the controls */ 093 private int controlsLength; 094 095 /** The LdapCodecService */ 096 private final LdapApiService codec; 097 098 099 public static MessageDecorator<? extends Message> getDecorator( LdapApiService codec, Message decoratedMessage ) 100 { 101 if ( decoratedMessage instanceof MessageDecorator ) 102 { 103 return (org.apache.directory.shared.ldap.codec.api.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 /** 276 * {@inheritDoc} 277 */ 278 public MessageTypeEnum getType() 279 { 280 return decoratedMessage.getType(); 281 } 282 283 284 /** 285 * {@inheritDoc} 286 */ 287 public Map<String, Control> getControls() 288 { 289 return controls; 290 } 291 292 293 /** 294 * {@inheritDoc} 295 */ 296 public Control getControl( String oid ) 297 { 298 return controls.get( oid ); 299 } 300 301 302 /** 303 * {@inheritDoc} 304 */ 305 public boolean hasControl( String oid ) 306 { 307 return controls.containsKey( oid ); 308 } 309 310 311 /** 312 * {@inheritDoc} 313 */ 314 @SuppressWarnings("unchecked") 315 public Message addControl( Control control ) throws MessageException 316 { 317 Control decorated; 318 CodecControl<? extends Control> controlDecorator; 319 320 if ( control instanceof ControlDecorator) 321 { 322 controlDecorator = (org.apache.directory.shared.ldap.codec.api.CodecControl<? extends Control> ) control; 323 decorated = controlDecorator.getDecorated(); 324 } 325 else 326 { 327 controlDecorator = codec.newControl( control ); 328 decorated = control; 329 } 330 331 decoratedMessage.addControl( decorated ); 332 controls.put( control.getOid(), controlDecorator ); 333 currentControl = controlDecorator; 334 335 return this; 336 } 337 338 339 /** 340 * {@inheritDoc} 341 */ 342 public Message addAllControls( Control[] controls ) throws MessageException 343 { 344 for ( Control control : controls ) 345 { 346 addControl( control ); 347 } 348 349 return this; 350 } 351 352 353 /** 354 * {@inheritDoc} 355 */ 356 public Message removeControl( Control control ) throws MessageException 357 { 358 decoratedMessage.removeControl( control ); 359 controls.remove( control.getOid() ); 360 361 return this; 362 } 363 364 365 /** 366 * {@inheritDoc} 367 */ 368 public int getMessageId() 369 { 370 return decoratedMessage.getMessageId(); 371 } 372 373 374 /** 375 * {@inheritDoc} 376 */ 377 public Object get( Object key ) 378 { 379 return decoratedMessage.get( key ); 380 } 381 382 383 /** 384 * {@inheritDoc} 385 */ 386 public Object put( Object key, Object value ) 387 { 388 return decoratedMessage.put( key, value ); 389 } 390 391 392 /** 393 * {@inheritDoc} 394 */ 395 public Message setMessageId( int messageId ) 396 { 397 decoratedMessage.setMessageId( messageId ); 398 399 return this; 400 } 401 402 403 /** 404 * Delegates to the toString() method of the decorated Message. 405 */ 406 public String toString() 407 { 408 return decoratedMessage.toString(); 409 } 410 411 412 /** 413 * {@inheritDoc} 414 */ 415 public E getDecorated() 416 { 417 return decoratedMessage; 418 } 419 420 421 /** 422 * {@inheritDoc} 423 */ 424 public LdapApiService getCodecService() 425 { 426 return codec; 427 } 428}