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     */
020    package org.apache.directory.shared.ldap.codec;
021    
022    
023    import java.util.ArrayList;
024    import java.util.Collection;
025    import java.util.List;
026    
027    import org.apache.directory.shared.asn1.Asn1Object;
028    import org.apache.directory.shared.asn1.codec.DecoderException;
029    import org.apache.directory.shared.asn1.primitives.OID;
030    import org.apache.directory.shared.i18n.I18n;
031    import org.apache.directory.shared.ldap.codec.abandon.AbandonRequestCodec;
032    import org.apache.directory.shared.ldap.codec.add.AddRequestCodec;
033    import org.apache.directory.shared.ldap.codec.add.AddResponseCodec;
034    import org.apache.directory.shared.ldap.codec.bind.BindRequestCodec;
035    import org.apache.directory.shared.ldap.codec.bind.BindResponseCodec;
036    import org.apache.directory.shared.ldap.codec.bind.SaslCredentials;
037    import org.apache.directory.shared.ldap.codec.bind.SimpleAuthentication;
038    import org.apache.directory.shared.ldap.codec.compare.CompareRequestCodec;
039    import org.apache.directory.shared.ldap.codec.compare.CompareResponseCodec;
040    import org.apache.directory.shared.ldap.codec.del.DelRequestCodec;
041    import org.apache.directory.shared.ldap.codec.del.DelResponseCodec;
042    import org.apache.directory.shared.ldap.codec.extended.ExtendedRequestCodec;
043    import org.apache.directory.shared.ldap.codec.extended.ExtendedResponseCodec;
044    import org.apache.directory.shared.ldap.codec.intermediate.IntermediateResponseCodec;
045    import org.apache.directory.shared.ldap.codec.modify.ModifyRequestCodec;
046    import org.apache.directory.shared.ldap.codec.modify.ModifyResponseCodec;
047    import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNRequestCodec;
048    import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNResponseCodec;
049    import org.apache.directory.shared.ldap.codec.search.AndFilter;
050    import org.apache.directory.shared.ldap.codec.search.AttributeValueAssertionFilter;
051    import org.apache.directory.shared.ldap.codec.search.ConnectorFilter;
052    import org.apache.directory.shared.ldap.codec.search.ExtensibleMatchFilter;
053    import org.apache.directory.shared.ldap.codec.search.Filter;
054    import org.apache.directory.shared.ldap.codec.search.NotFilter;
055    import org.apache.directory.shared.ldap.codec.search.OrFilter;
056    import org.apache.directory.shared.ldap.codec.search.PresentFilter;
057    import org.apache.directory.shared.ldap.codec.search.SearchRequestCodec;
058    import org.apache.directory.shared.ldap.codec.search.SearchResultDoneCodec;
059    import org.apache.directory.shared.ldap.codec.search.SearchResultEntryCodec;
060    import org.apache.directory.shared.ldap.codec.search.SearchResultReferenceCodec;
061    import org.apache.directory.shared.ldap.codec.search.SubstringFilter;
062    import org.apache.directory.shared.ldap.codec.unbind.UnBindRequestCodec;
063    import org.apache.directory.shared.ldap.codec.util.LdapURLEncodingException;
064    import org.apache.directory.shared.ldap.entry.EntryAttribute;
065    import org.apache.directory.shared.ldap.entry.Modification;
066    import org.apache.directory.shared.ldap.entry.Value;
067    import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
068    import org.apache.directory.shared.ldap.filter.AndNode;
069    import org.apache.directory.shared.ldap.filter.ApproximateNode;
070    import org.apache.directory.shared.ldap.filter.BranchNode;
071    import org.apache.directory.shared.ldap.filter.EqualityNode;
072    import org.apache.directory.shared.ldap.filter.ExprNode;
073    import org.apache.directory.shared.ldap.filter.ExtensibleNode;
074    import org.apache.directory.shared.ldap.filter.GreaterEqNode;
075    import org.apache.directory.shared.ldap.filter.LeafNode;
076    import org.apache.directory.shared.ldap.filter.LessEqNode;
077    import org.apache.directory.shared.ldap.filter.NotNode;
078    import org.apache.directory.shared.ldap.filter.OrNode;
079    import org.apache.directory.shared.ldap.filter.PresenceNode;
080    import org.apache.directory.shared.ldap.filter.SimpleNode;
081    import org.apache.directory.shared.ldap.filter.SubstringNode;
082    import org.apache.directory.shared.ldap.message.AbandonRequestImpl;
083    import org.apache.directory.shared.ldap.message.AddRequestImpl;
084    import org.apache.directory.shared.ldap.message.AddResponseImpl;
085    import org.apache.directory.shared.ldap.message.AliasDerefMode;
086    import org.apache.directory.shared.ldap.message.BindRequestImpl;
087    import org.apache.directory.shared.ldap.message.BindResponseImpl;
088    import org.apache.directory.shared.ldap.message.CompareRequestImpl;
089    import org.apache.directory.shared.ldap.message.CompareResponseImpl;
090    import org.apache.directory.shared.ldap.message.DeleteRequestImpl;
091    import org.apache.directory.shared.ldap.message.DeleteResponseImpl;
092    import org.apache.directory.shared.ldap.message.ExtendedRequestImpl;
093    import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
094    import org.apache.directory.shared.ldap.message.IntermediateResponseImpl;
095    import org.apache.directory.shared.ldap.message.LdapResultImpl;
096    import org.apache.directory.shared.ldap.message.ModifyDnRequestImpl;
097    import org.apache.directory.shared.ldap.message.ModifyDnResponseImpl;
098    import org.apache.directory.shared.ldap.message.ModifyRequestImpl;
099    import org.apache.directory.shared.ldap.message.ModifyResponseImpl;
100    import org.apache.directory.shared.ldap.message.ReferralImpl;
101    import org.apache.directory.shared.ldap.message.SearchRequestImpl;
102    import org.apache.directory.shared.ldap.message.SearchResponseDoneImpl;
103    import org.apache.directory.shared.ldap.message.SearchResponseEntryImpl;
104    import org.apache.directory.shared.ldap.message.SearchResponseReferenceImpl;
105    import org.apache.directory.shared.ldap.message.UnbindRequestImpl;
106    import org.apache.directory.shared.ldap.message.control.Control;
107    import org.apache.directory.shared.ldap.message.extended.GracefulShutdownRequest;
108    import org.apache.directory.shared.ldap.message.internal.InternalLdapResult;
109    import org.apache.directory.shared.ldap.message.internal.InternalMessage;
110    import org.apache.directory.shared.ldap.message.internal.InternalReferral;
111    import org.apache.directory.shared.ldap.name.DN;
112    import org.apache.directory.shared.ldap.util.LdapURL;
113    import org.apache.directory.shared.ldap.util.StringTools;
114    import org.slf4j.Logger;
115    import org.slf4j.LoggerFactory;
116    
117    
118    /**
119     * A Codec to Internal Message transformer.
120     * 
121     * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
122     * @version $Rev: 923473 $, $Date: 2010-03-15 23:25:03 +0100 (Mon, 15 Mar 2010) $, 
123     */
124    public class LdapTransformer
125    {
126        /** The logger */
127        private static Logger LOG = LoggerFactory.getLogger( LdapTransformer.class );
128    
129        /** A speedup for logger */
130        private static final boolean IS_DEBUG = LOG.isDebugEnabled();
131    
132    
133        /**
134         * Transform an AbandonRequest message from a codec Message to an
135         * InternalMessage
136         * 
137         * @param codecMessage The message to transform
138         * @param messageId The message Id
139         * @return An internal AbandonRequest message
140         */
141        private static InternalMessage transformAbandonRequest( AbandonRequestCodec abandonRequest, int messageId )
142        {
143            AbandonRequestImpl internalMessage = new AbandonRequestImpl( messageId );
144    
145            // Codec : int abandonnedMessageId -> Internal : int abandonId
146            internalMessage.setAbandoned( abandonRequest.getAbandonedMessageId() );
147    
148            return internalMessage;
149        }
150    
151    
152        /**
153         * Transform an AddRequest message from a addRequest to a InternalMessage
154         * 
155         * @param addRequest The message to transform
156         * @param messageId The message Id
157         * @return A Internal AddRequestImpl
158         */
159        private static InternalMessage transformAddRequest( AddRequestCodec addRequest, int messageId )
160        {
161            AddRequestImpl internalMessage = new AddRequestImpl( messageId );
162    
163            // Codec : DN entry -> Internal : String name
164            internalMessage.setEntry( addRequest.getEntry() );
165    
166            // Codec : Attributes attributes -> Internal : Attributes entry
167            internalMessage.setEntry( addRequest.getEntry() );
168    
169            return internalMessage;
170        }
171    
172    
173        /**
174         * Transform a BindRequest message from a CodecMessage to a InternalMessage
175         * 
176         * @param bindRequest The message to transform
177         * @param messageId The message Id
178         * @return A Internal BindRequestImpl
179         */
180        private static InternalMessage transformBindRequest( BindRequestCodec bindRequest, int messageId )
181        {
182            BindRequestImpl internalMessage = new BindRequestImpl( messageId );
183    
184            // Codec : int version -> Internal : boolean isVersion3
185            internalMessage.setVersion3( bindRequest.isLdapV3() );
186    
187            // Codec : DN name -> Internal : DN name
188            internalMessage.setName( bindRequest.getName() );
189    
190            // Codec : Asn1Object authentication instanceOf SimpleAuthentication ->
191            // Internal : boolean isSimple
192            // Codec : SimpleAuthentication OctetString simple -> Internal : byte []
193            // credentials
194            Asn1Object authentication = bindRequest.getAuthentication();
195    
196            if ( authentication instanceof SimpleAuthentication )
197            {
198                internalMessage.setSimple( true );
199                internalMessage.setCredentials( ( ( SimpleAuthentication ) authentication ).getSimple() );
200            }
201            else
202            {
203                internalMessage.setSimple( false );
204                internalMessage.setCredentials( ( ( SaslCredentials ) authentication ).getCredentials() );
205                internalMessage.setSaslMechanism( ( ( SaslCredentials ) authentication ).getMechanism() );
206            }
207    
208            return internalMessage;
209        }
210    
211    
212        /**
213         * Transform a BindResponse message from a CodecMessage to a 
214         * InternalMessage.  This is used by clients which are receiving a 
215         * BindResponse PDU and must decode it to return the Internal 
216         * representation.
217         * 
218         * @param bindResponse The message to transform
219         * @param messageId The message Id
220         * @return a Internal BindResponseImpl
221         */
222        private static InternalMessage transformBindResponse( BindResponseCodec bindResponse, int messageId )
223        {
224            BindResponseImpl internalMessage = new BindResponseImpl( messageId );
225    
226            // Codec : byte[] serverSaslcreds -> Internal : byte[] serverSaslCreds
227            internalMessage.setServerSaslCreds( bindResponse.getServerSaslCreds() );
228            //transformControlsCodecToInternal( codecMessage, internalMessage );
229            transformLdapResultCodecToInternal( bindResponse.getLdapResult(), internalMessage.getLdapResult() );
230            
231            return internalMessage;
232        }
233    
234        
235        /**
236         * Transforms parameters of a Codec LdapResult into a Internal LdapResult.
237         *
238         * @param codecLdapResult the codec LdapResult representation
239         * @param InternalResult the Internal LdapResult representation
240         */
241        private static void transformLdapResultCodecToInternal( LdapResultCodec codecLdapResult, InternalLdapResult internalLdapResult )
242        {
243            internalLdapResult.setErrorMessage( codecLdapResult.getErrorMessage() );
244            
245            try
246            {
247                internalLdapResult.setMatchedDn( new DN( codecLdapResult.getMatchedDN() ) );
248            }
249            catch ( LdapInvalidDnException e )
250            {
251                LOG.error( I18n.err( I18n.ERR_04111, codecLdapResult.getMatchedDN() ) );
252                internalLdapResult.setMatchedDn( new DN() );
253            }
254            
255            internalLdapResult.setResultCode( codecLdapResult.getResultCode() );
256    
257            if ( codecLdapResult.getReferrals() == null )
258            {
259                
260            }
261            else
262            {
263                ReferralImpl referral = new ReferralImpl();
264                
265                for ( LdapURL url : codecLdapResult.getReferrals() )
266                {
267                    referral.addLdapUrl( url.toString() );
268                }
269                
270                internalLdapResult.setReferral( referral );
271            }
272        }
273        
274    
275        /**
276         * Transform a CompareRequest message from a CodecMessage to a
277         * InternalMessage
278         * 
279         * @param compareRequest The message to transform
280         * @param messageId The message Id
281         * @return A Internal CompareRequestImpl
282         */
283        private static InternalMessage transformCompareRequest( CompareRequestCodec compareRequest, int messageId )
284        {
285            CompareRequestImpl internalMessage = new CompareRequestImpl( messageId );
286    
287            // Codec : DN entry -> Internal : private DN
288            internalMessage.setName( compareRequest.getEntry() );
289    
290            // Codec : LdapString attributeDesc -> Internal : String attrId
291            internalMessage.setAttributeId( compareRequest.getAttributeDesc() );
292    
293            // Codec : OctetString assertionValue -> Internal : byte[] attrVal
294            if ( compareRequest.getAssertionValue() instanceof String )
295            {
296                internalMessage.setAssertionValue( ( String ) compareRequest.getAssertionValue() );
297            }
298            else
299            {
300                internalMessage.setAssertionValue( ( byte[] ) compareRequest.getAssertionValue() );
301            }
302    
303            return internalMessage;
304        }
305    
306    
307        /**
308         * Transform a DelRequest message from a CodecMessage to a InternalMessage
309         * 
310         * @param delRequest The message to transform
311         * @param messageId The message Id
312         * @return A Internal DeleteRequestImpl
313         */
314        private static InternalMessage transformDelRequest( DelRequestCodec delRequest, int messageId )
315        {
316            DeleteRequestImpl internalMessage = new DeleteRequestImpl( messageId );
317    
318            // Codec : DN entry -> Internal : DN
319            internalMessage.setName( delRequest.getEntry() );
320    
321            return internalMessage;
322        }
323    
324    
325        /**
326         * Transform an ExtendedRequest message from a CodecMessage to a
327         * InternalMessage
328         * 
329         * @param extendedRequest The message to transform
330         * @param messageId The message Id
331         * @return A Internal ExtendedRequestImpl
332         */
333        private static InternalMessage transformExtendedRequest( ExtendedRequestCodec extendedRequest, int messageId )
334        {
335            ExtendedRequestImpl internalMessage;
336    
337            if ( extendedRequest.getRequestName().equals( GracefulShutdownRequest.EXTENSION_OID ) )
338            {
339                internalMessage = new GracefulShutdownRequest( messageId );
340            }
341            else
342            {
343                internalMessage = new ExtendedRequestImpl( messageId );
344            }
345    
346            // Codec : OID requestName -> Internal : String oid
347            internalMessage.setOid( extendedRequest.getRequestName() );
348    
349            // Codec : OctetString requestValue -> Internal : byte [] payload
350            internalMessage.setPayload( extendedRequest.getRequestValue() );
351    
352            return internalMessage;
353        }
354    
355    
356        /**
357         * Transform a ModifyDNRequest message from a CodecMessage to a
358         * InternalMessage
359         * 
360         * @param modifyDNRequest The message to transform
361         * @param messageId The message Id
362         * @return A Internal ModifyDNRequestImpl
363         */
364        private static InternalMessage transformModifyDNRequest( ModifyDNRequestCodec modifyDNRequest, int messageId )
365        {
366            ModifyDnRequestImpl internalMessage = new ModifyDnRequestImpl( messageId );
367    
368            // Codec : DN entry -> Internal : DN m_name
369            internalMessage.setName( modifyDNRequest.getEntry() );
370    
371            // Codec : RelativeDN newRDN -> Internal : DN m_newRdn
372            internalMessage.setNewRdn( modifyDNRequest.getNewRDN() );
373    
374            // Codec : boolean deleteOldRDN -> Internal : boolean m_deleteOldRdn
375            internalMessage.setDeleteOldRdn( modifyDNRequest.isDeleteOldRDN() );
376    
377            // Codec : DN newSuperior -> Internal : DN m_newSuperior
378            internalMessage.setNewSuperior( modifyDNRequest.getNewSuperior() );
379    
380            return internalMessage;
381        }
382    
383    
384        /**
385         * Transform a ModifyRequest message from a CodecMessage to a InternalMessage
386         * 
387         * @param modifyRequest The message to transform
388         * @param messageId The message Id
389         * @return A Internal ModifyRequestImpl
390         */
391        private static InternalMessage transformModifyRequest( ModifyRequestCodec modifyRequest, int messageId )
392        {
393            ModifyRequestImpl internalMessage = new ModifyRequestImpl( messageId );
394    
395            // Codec : DN object -> Internal : String name
396            internalMessage.setName( modifyRequest.getObject() );
397    
398            // Codec : ArrayList modifications -> Internal : ArrayList mods
399            if ( modifyRequest.getModifications() != null )
400            {
401                // Loop through the modifications
402                for ( Modification modification:modifyRequest.getModifications() )
403                {
404                    internalMessage.addModification( modification );
405                }
406            }
407    
408            return internalMessage;
409        }
410    
411    
412        /**
413         * Transform the Filter part of a SearchRequest to an ExprNode
414         * 
415         * @param codecFilter The filter to be transformed
416         * @return An ExprNode
417         */
418        private static ExprNode transformFilter( Filter codecFilter )
419        {
420            if ( codecFilter != null )
421            {
422                // Transform OR, AND or NOT leaves
423                if ( codecFilter instanceof ConnectorFilter )
424                {
425                    BranchNode branch = null;
426    
427                    if ( codecFilter instanceof AndFilter )
428                    {
429                        branch = new AndNode();
430                    }
431                    else if ( codecFilter instanceof OrFilter )
432                    {
433                        branch = new OrNode();
434                    }
435                    else if ( codecFilter instanceof NotFilter )
436                    {
437                        branch = new NotNode();
438                    }
439    
440                    List<Filter> filtersSet = ( ( ConnectorFilter ) codecFilter ).getFilterSet();
441    
442                    // Loop on all AND/OR children
443                    if ( filtersSet != null )
444                    {
445                        for ( Filter filter:filtersSet )
446                        {
447                            branch.addNode( transformFilter( filter ) );
448                        }
449                    }
450    
451                    return branch;
452                }
453                else
454                {
455                    // Transform PRESENT or ATTRIBUTE_VALUE_ASSERTION
456                    LeafNode branch = null;
457    
458                    if ( codecFilter instanceof PresentFilter )
459                    {
460                        branch = new PresenceNode( ( ( PresentFilter ) codecFilter ).getAttributeDescription() );
461                    }
462                    else if ( codecFilter instanceof AttributeValueAssertionFilter )
463                    {
464                        AttributeValueAssertion ava = ( ( AttributeValueAssertionFilter ) codecFilter ).getAssertion();
465    
466                        // Transform =, >=, <=, ~= filters
467                        switch ( ( ( AttributeValueAssertionFilter ) codecFilter ).getFilterType() )
468                        {
469                            case LdapConstants.EQUALITY_MATCH_FILTER:
470                                branch = new EqualityNode( ava.getAttributeDesc(), 
471                                    ava.getAssertionValue() );
472                                
473                                break;
474    
475                            case LdapConstants.GREATER_OR_EQUAL_FILTER:
476                                branch = new GreaterEqNode( ava.getAttributeDesc(),
477                                    ava.getAssertionValue() );
478    
479                                break;
480    
481                            case LdapConstants.LESS_OR_EQUAL_FILTER:
482                                branch = new LessEqNode( ava.getAttributeDesc(), 
483                                    ava.getAssertionValue() );
484    
485                                break;
486    
487                            case LdapConstants.APPROX_MATCH_FILTER:
488                                branch = new ApproximateNode( ava.getAttributeDesc(), 
489                                    ava.getAssertionValue() );
490    
491                                break;
492                        }
493    
494                    }
495                    else if ( codecFilter instanceof SubstringFilter )
496                    {
497                        // Transform Substring filters
498                        SubstringFilter filter = ( SubstringFilter ) codecFilter;
499                        String initialString = null;
500                        String finalString = null;
501                        List<String> anyString = null;
502    
503                        if ( filter.getInitialSubstrings() != null )
504                        {
505                            initialString = filter.getInitialSubstrings();
506                        }
507    
508                        if ( filter.getFinalSubstrings() != null )
509                        {
510                            finalString = filter.getFinalSubstrings();
511                        }
512    
513                        if ( filter.getAnySubstrings() != null )
514                        {
515                            anyString = new ArrayList<String>();
516    
517                            for ( String any:filter.getAnySubstrings() )
518                            {
519                                anyString.add( any );
520                            }
521                        }
522    
523                        branch = new SubstringNode( anyString, filter.getType(), initialString, finalString );
524                    }
525                    else if ( codecFilter instanceof ExtensibleMatchFilter )
526                    {
527                        // Transform Extensible Match Filter
528                        ExtensibleMatchFilter filter = ( ExtensibleMatchFilter ) codecFilter;
529                        String attribute = null;
530                        String matchingRule = null;
531    
532                        if ( filter.getType() != null )
533                        {
534                            attribute = filter.getType();
535                        }
536    
537                        Value<?> value = filter.getMatchValue();
538    
539                        if ( filter.getMatchingRule() != null )
540                        {
541                            matchingRule = filter.getMatchingRule();
542                        }
543    
544                        branch = new ExtensibleNode( attribute, value, matchingRule, filter.isDnAttributes() );
545                    }
546    
547                    return branch;
548                }
549            }
550            else
551            {
552                // We have found nothing to transform. Return null then.
553                return null;
554            }
555        }
556    
557    
558        /**
559         * Transform an ExprNode filter to a CodecFilter
560         * 
561         * @param exprNode The filter to be transformed
562         * @return A Codec filter
563         */
564        public static Filter transformFilter( ExprNode exprNode )
565        {
566            if ( exprNode != null )
567            {
568                Filter filter  = null;
569    
570                // Transform OR, AND or NOT leaves
571                if ( exprNode instanceof BranchNode )
572                {
573                    if ( exprNode instanceof AndNode )
574                    {
575                        filter = new AndFilter();
576                    }
577                    else if ( exprNode instanceof OrNode )
578                    {
579                        filter = new OrFilter();
580                    }
581                    else if ( exprNode instanceof NotNode )
582                    {
583                        filter = new NotFilter();
584                    }
585    
586                    List<ExprNode> children = ((BranchNode)exprNode).getChildren();
587    
588                    // Loop on all AND/OR children
589                    if ( children != null )
590                    {
591                        for ( ExprNode child:children )
592                        {
593                            try
594                            {
595                                ((ConnectorFilter)filter).addFilter( transformFilter( child ) );
596                            }
597                            catch ( DecoderException de )
598                            {
599                                LOG.error( I18n.err( I18n.ERR_04112, de.getLocalizedMessage() ) );
600                                return null;
601                            }
602                        }
603                    }
604                }
605                else
606                {
607                    if ( exprNode instanceof PresenceNode )
608                    {
609                        // Transform Presence Node
610                        filter = new PresentFilter();
611                        ((PresentFilter)filter).setAttributeDescription( ((PresenceNode)exprNode).getAttribute() );
612                    }
613                    else if ( exprNode instanceof SimpleNode<?> )
614                    {
615                        if ( exprNode instanceof EqualityNode<?> )
616                        {
617                            filter = new AttributeValueAssertionFilter( LdapConstants.EQUALITY_MATCH_FILTER );
618                            AttributeValueAssertion assertion = new AttributeValueAssertion();
619                            assertion.setAttributeDesc( ((EqualityNode<?>)exprNode).getAttribute() );
620                            assertion.setAssertionValue( ((EqualityNode<?>)exprNode).getValue() );
621                            ((AttributeValueAssertionFilter)filter).setAssertion( assertion );
622                        }
623                        else if ( exprNode instanceof GreaterEqNode<?> ) 
624                        {
625                            filter = new AttributeValueAssertionFilter( LdapConstants.GREATER_OR_EQUAL_FILTER );
626                            AttributeValueAssertion assertion = new AttributeValueAssertion();
627                            assertion.setAttributeDesc( ((EqualityNode<?>)exprNode).getAttribute() );
628                            assertion.setAssertionValue( ((EqualityNode<?>)exprNode).getValue() );
629                            ((AttributeValueAssertionFilter)filter).setAssertion( assertion );
630                        }
631                        else if ( exprNode instanceof LessEqNode<?> ) 
632                        {
633                            filter = new AttributeValueAssertionFilter( LdapConstants.LESS_OR_EQUAL_FILTER );
634                            AttributeValueAssertion assertion = new AttributeValueAssertion();
635                            assertion.setAttributeDesc( ((EqualityNode<?>)exprNode).getAttribute() );
636                            assertion.setAssertionValue( ((EqualityNode<?>)exprNode).getValue() );
637                            ((AttributeValueAssertionFilter)filter).setAssertion( assertion );
638                        }
639                        else if ( exprNode instanceof ApproximateNode<?> )
640                        {
641                            filter = new AttributeValueAssertionFilter( LdapConstants.APPROX_MATCH_FILTER );
642                            AttributeValueAssertion assertion = new AttributeValueAssertion();
643                            assertion.setAttributeDesc( ((EqualityNode<?>)exprNode).getAttribute() );
644                            assertion.setAssertionValue( ((EqualityNode<?>)exprNode).getValue() );
645                            ((AttributeValueAssertionFilter)filter).setAssertion( assertion );
646                        }
647                    }
648                    else if ( exprNode instanceof SubstringNode )
649                    {
650                        // Transform Substring Nodes
651                        filter = new SubstringFilter();
652    
653                        String initialString = ((SubstringNode)exprNode).getInitial();
654                        String finalString = ((SubstringNode)exprNode).getFinal();
655                        List<String> anyStrings = ((SubstringNode)exprNode).getAny();
656    
657                        if ( initialString != null )
658                        {
659                            ((SubstringFilter)filter).setInitialSubstrings( initialString );
660                        }
661    
662                        if ( finalString != null )
663                        {
664                            ((SubstringFilter)filter).setFinalSubstrings( finalString );
665                        }
666    
667                        if ( anyStrings != null )
668                        {
669                            for ( String any:anyStrings )
670                            {
671                                ((SubstringFilter)filter).addAnySubstrings( any );
672                            }
673                        }
674                    }
675                    else if ( exprNode instanceof ExtensibleNode )
676                    {
677                        // Transform Extensible Node
678                        filter = new ExtensibleMatchFilter();
679                        
680                        String attribute = ((ExtensibleNode)exprNode).getAttribute();
681                        String matchingRule = ((ExtensibleNode)exprNode).getMatchingRuleId();
682                        boolean dnAttributes = ((ExtensibleNode)exprNode).hasDnAttributes();
683                        Value<?> value = ((ExtensibleNode)exprNode).getValue();
684    
685                        if ( attribute != null )
686                        {
687                            ((ExtensibleMatchFilter)filter).setType( attribute );
688                        }
689    
690                        if ( matchingRule != null )
691                        {
692                            ((ExtensibleMatchFilter)filter).setMatchingRule( matchingRule );
693                        }
694    
695                        ((ExtensibleMatchFilter)filter).setMatchValue( value );
696                        ((ExtensibleMatchFilter)filter).setDnAttributes( dnAttributes );
697                    }
698                }
699    
700                return filter;
701            }
702            else
703            {
704                // We have found nothing to transform. Return null then.
705                return null;
706            }
707        }
708    
709    
710        /**
711         * Transform a SearchRequest message from a CodecMessage to a InternalMessage
712         * 
713         * @param searchRequest The message to transform
714         * @param messageId The message Id
715         * @return A Internal SearchRequestImpl
716         */
717        private static InternalMessage transformSearchRequest( SearchRequestCodec searchRequest, int messageId )
718        {
719            SearchRequestImpl internalMessage = new SearchRequestImpl( messageId );
720    
721            // Codec : DN baseObject -> Internal : String baseDn
722            internalMessage.setBase( searchRequest.getBaseObject() );
723    
724            // Codec : int scope -> Internal : ScopeEnum scope
725            internalMessage.setScope( searchRequest.getScope() );
726    
727            // Codec : int derefAliases -> Internal : AliasDerefMode derefAliases
728            switch ( searchRequest.getDerefAliases() )
729            {
730                case LdapConstants.DEREF_ALWAYS:
731                    internalMessage.setDerefAliases( AliasDerefMode.DEREF_ALWAYS );
732                    break;
733    
734                case LdapConstants.DEREF_FINDING_BASE_OBJ:
735                    internalMessage.setDerefAliases( AliasDerefMode.DEREF_FINDING_BASE_OBJ );
736                    break;
737    
738                case LdapConstants.DEREF_IN_SEARCHING:
739                    internalMessage.setDerefAliases( AliasDerefMode.DEREF_IN_SEARCHING );
740                    break;
741    
742                case LdapConstants.NEVER_DEREF_ALIASES:
743                    internalMessage.setDerefAliases( AliasDerefMode.NEVER_DEREF_ALIASES );
744                    break;
745            }
746    
747            // Codec : int sizeLimit -> Internal : int sizeLimit
748            internalMessage.setSizeLimit( searchRequest.getSizeLimit() );
749    
750            // Codec : int timeLimit -> Internal : int timeLimit
751            internalMessage.setTimeLimit( searchRequest.getTimeLimit() );
752    
753            // Codec : boolean typesOnly -> Internal : boolean typesOnly
754            internalMessage.setTypesOnly( searchRequest.isTypesOnly() );
755    
756            // Codec : Filter filter -> Internal : ExprNode filter
757            Filter codecFilter = searchRequest.getFilter();
758    
759            internalMessage.setFilter( transformFilter( codecFilter ) );
760    
761            // Codec : ArrayList attributes -> Internal : ArrayList attributes
762            if ( searchRequest.getAttributes() != null )
763            {
764                List<EntryAttribute> attributes = searchRequest.getAttributes();
765    
766                if ( ( attributes != null ) && ( attributes.size() != 0 ) )
767                {
768                    for ( EntryAttribute attribute:attributes )
769                    {
770                        if ( attribute != null )
771                        {
772                            internalMessage.addAttribute( attribute.getId() );
773                        }
774                    }
775                }
776            }
777    
778            return internalMessage;
779        }
780    
781    
782        /**
783         * Transform an UnBindRequest message from a CodecMessage to a
784         * InternalMessage
785         * 
786         * @param codecMessage The message to transform
787         * @param messageId The message Id
788         * @return A Internal UnBindRequestImpl
789         */
790        private static InternalMessage transformUnBindRequest( LdapMessageCodec codecMessage, int messageId )
791        {
792            return new UnbindRequestImpl( messageId );
793        }
794    
795    
796        /**
797         * Transform the Codec message to a internal message.
798         * 
799         * @param obj the object to transform
800         * @return the object transformed
801         */
802        public static InternalMessage transform( Object obj )
803        {
804            LdapMessageCodec codecMessage = ( LdapMessageCodec ) obj;
805            int messageId = codecMessage.getMessageId();
806    
807            if ( IS_DEBUG )
808            {
809                LOG.debug( "Transforming LdapMessage <" + messageId + ", " + codecMessage.getMessageTypeName()
810                    + "> from Codec to nternal." );
811            }
812    
813            InternalMessage internalMessage = null;
814    
815            MessageTypeEnum messageType = codecMessage.getMessageType();
816    
817            switch ( messageType )
818            {
819                case BIND_REQUEST :
820                    internalMessage = transformBindRequest( (BindRequestCodec)codecMessage, messageId );
821                    break;
822    
823                case UNBIND_REQUEST :
824                    internalMessage = transformUnBindRequest( (UnBindRequestCodec)codecMessage, messageId );
825                    break;
826    
827                case SEARCH_REQUEST :
828                    internalMessage = transformSearchRequest( (SearchRequestCodec)codecMessage, messageId );
829                    break;
830    
831                case MODIFY_REQUEST :
832                    internalMessage = transformModifyRequest( (ModifyRequestCodec)codecMessage, messageId );
833                    break;
834    
835                case ADD_REQUEST :
836                    internalMessage = transformAddRequest( (AddRequestCodec)codecMessage, messageId );
837                    break;
838    
839                case DEL_REQUEST :
840                    internalMessage = transformDelRequest( (DelRequestCodec)codecMessage, messageId );
841                    break;
842    
843                case MODIFYDN_REQUEST :
844                    internalMessage = transformModifyDNRequest( (ModifyDNRequestCodec)codecMessage, messageId );
845                    break;
846    
847                case COMPARE_REQUEST :
848                    internalMessage = transformCompareRequest( (CompareRequestCodec)codecMessage, messageId );
849                    break;
850    
851                case ABANDON_REQUEST :
852                    internalMessage = transformAbandonRequest( (AbandonRequestCodec)codecMessage, messageId );
853                    break;
854    
855                case EXTENDED_REQUEST :
856                    internalMessage = transformExtendedRequest( (ExtendedRequestCodec)codecMessage, messageId );
857                    break;
858                    
859                case BIND_RESPONSE :
860                    internalMessage = transformBindResponse( (BindResponseCodec)codecMessage, messageId );
861                    break;
862    
863                case SEARCH_RESULT_ENTRY :
864                case SEARCH_RESULT_DONE :
865                case SEARCH_RESULT_REFERENCE :
866                case MODIFY_RESPONSE :
867                case ADD_RESPONSE :
868                case DEL_RESPONSE :
869                case MODIFYDN_RESPONSE :
870                case COMPARE_RESPONSE :
871                case EXTENDED_RESPONSE :
872                case INTERMEDIATE_RESPONSE :
873                    // Nothing to do !
874                    break;
875    
876    
877                default:
878                    throw new IllegalStateException( I18n.err( I18n.ERR_04113 ) );
879            }
880    
881            // Transform the controls, too
882            transformControlsCodecToInternal( codecMessage, internalMessage );
883    
884            return internalMessage;
885        }
886    
887    
888        /**
889         * Transform a Ldapresult part of a Internal Response to a Codec LdapResult
890         * 
891         * @param InternalLdapResult the Internal LdapResult to transform
892         * @return A Codec LdapResult
893         */
894        private static LdapResultCodec transformLdapResult( LdapResultImpl internalLdapResult )
895        {
896            LdapResultCodec codecLdapResult = new LdapResultCodec();
897    
898            // Internal : ResultCodeEnum resultCode -> Codec : int resultCode
899            codecLdapResult.setResultCode( internalLdapResult.getResultCode() );
900    
901            // Internal : String errorMessage -> Codec : LdapString errorMessage
902            String errorMessage = internalLdapResult.getErrorMessage();
903            
904            codecLdapResult.setErrorMessage( StringTools.isEmpty( errorMessage ) ? "" : errorMessage );
905    
906            // Internal : String matchedDn -> Codec : DN matchedDN
907            codecLdapResult.setMatchedDN( internalLdapResult.getMatchedDn() );
908    
909            // Internal : Referral referral -> Codec : ArrayList referrals
910            ReferralImpl internalReferrals = ( ReferralImpl ) internalLdapResult.getReferral();
911    
912            if ( internalReferrals != null )
913            {
914                codecLdapResult.initReferrals();
915    
916                for ( String referral:internalReferrals.getLdapUrls() )
917                {
918                    try
919                    {
920                        LdapURL ldapUrl = new LdapURL( referral.getBytes() );
921                        codecLdapResult.addReferral( ldapUrl );
922                    }
923                    catch ( LdapURLEncodingException lude )
924                    {
925                        LOG.warn( "The referral " + referral + " is invalid : " + lude.getMessage() );
926                        codecLdapResult.addReferral( LdapURL.EMPTY_URL );
927                    }
928                }
929            }
930    
931            return codecLdapResult;
932        }
933    
934    
935        /**
936         * Transform a Internal AddResponse to a Codec AddResponse
937         * 
938         * @param internalMessage The incoming Internal AddResponse
939         * @return The AddResponseCodec instance
940         */
941        private static LdapMessageCodec transformAddResponse( InternalMessage internalMessage )
942        {
943            AddResponseImpl internalAddResponse = ( AddResponseImpl ) internalMessage;
944    
945            AddResponseCodec addResponse = new AddResponseCodec();
946    
947            // Transform the ldapResult
948            addResponse.setLdapResult( transformLdapResult( ( LdapResultImpl ) internalAddResponse.getLdapResult() ) );
949    
950            return addResponse;
951        }
952    
953    
954        /**
955         * Transform a Internal BindResponse to a Codec BindResponse
956         * 
957         * @param internalMessage The incoming Internal BindResponse
958         * @return The BindResponseCodec instance
959         */
960        private static LdapMessageCodec transformBindResponse( InternalMessage internalMessage )
961        {
962            BindResponseImpl internalBindResponse = ( BindResponseImpl ) internalMessage;
963    
964            BindResponseCodec bindResponseCodec = new BindResponseCodec();
965    
966            // Internal : byte [] serverSaslCreds -> Codec : OctetString
967            // serverSaslCreds
968            byte[] serverSaslCreds = internalBindResponse.getServerSaslCreds();
969    
970            if ( serverSaslCreds != null )
971            {
972                bindResponseCodec.setServerSaslCreds( serverSaslCreds );
973            }
974    
975            // Transform the ldapResult
976            bindResponseCodec.setLdapResult( transformLdapResult( ( LdapResultImpl ) internalBindResponse.getLdapResult() ) );
977    
978            return bindResponseCodec;
979        }
980    
981    
982        /**
983         * Transform a Internal BindRequest to a Codec BindRequest
984         * 
985         * @param internalMessage The incoming Internal BindRequest
986         * @return The BindRequestCodec instance
987         */
988        private static LdapMessageCodec transformBindRequest( InternalMessage internalMessage )
989        {
990            BindRequestImpl internalBindRequest = ( BindRequestImpl ) internalMessage;
991    
992            BindRequestCodec bindRequest = new BindRequestCodec();
993    
994            if ( internalBindRequest.isSimple() )
995            {
996                SimpleAuthentication simple = new SimpleAuthentication();
997                simple.setSimple( internalBindRequest.getCredentials() );
998                bindRequest.setAuthentication( simple );
999            }
1000            else
1001            {
1002                SaslCredentials sasl = new SaslCredentials();
1003                sasl.setCredentials( internalBindRequest.getCredentials() );
1004                sasl.setMechanism( internalBindRequest.getSaslMechanism() );
1005                bindRequest.setAuthentication( sasl );
1006            }
1007            
1008            bindRequest.setMessageId( internalBindRequest.getMessageId() );
1009            bindRequest.setName( internalBindRequest.getName() );
1010            bindRequest.setVersion( internalBindRequest.isVersion3() ? 3 : 2 );
1011            
1012            return bindRequest;
1013        }
1014    
1015    
1016        /**
1017         * Transform a Internal CompareResponse to a Codec CompareResponse
1018         * 
1019         * @param internalMessage The incoming Internal CompareResponse
1020         * @return The CompareResponseCodec instance
1021         */
1022        private static LdapMessageCodec transformCompareResponse( InternalMessage internalMessage )
1023        {
1024            CompareResponseImpl internalCompareResponse = ( CompareResponseImpl ) internalMessage;
1025    
1026            CompareResponseCodec compareResponse = new CompareResponseCodec();
1027    
1028            // Transform the ldapResult
1029            compareResponse
1030                .setLdapResult( transformLdapResult( ( LdapResultImpl ) internalCompareResponse.getLdapResult() ) );
1031    
1032            return compareResponse;
1033        }
1034    
1035    
1036        /**
1037         * Transform a Internal DelResponse to a Codec DelResponse
1038         * 
1039         * @param internalMessage The incoming Internal DelResponse
1040         * @return The DelResponseCodec instance
1041         */
1042        private static LdapMessageCodec transformDelResponse( InternalMessage internalMessage )
1043        {
1044            DeleteResponseImpl internalDelResponse = ( DeleteResponseImpl ) internalMessage;
1045    
1046            DelResponseCodec delResponse = new DelResponseCodec();
1047    
1048            // Transform the ldapResult
1049            delResponse.setLdapResult( transformLdapResult( ( LdapResultImpl ) internalDelResponse.getLdapResult() ) );
1050    
1051            return delResponse;
1052        }
1053    
1054    
1055        /**
1056         * Transform a Internal ExtendedResponse to a Codec ExtendedResponse
1057         * 
1058         * @param internalMessage The incoming Internal ExtendedResponse
1059         * @return The ExtendedResponseCodec instance
1060         */
1061        private static LdapMessageCodec transformExtendedResponse( InternalMessage internalMessage )
1062        {
1063            ExtendedResponseImpl internalExtendedResponse = ( ExtendedResponseImpl ) internalMessage;
1064            ExtendedResponseCodec extendedResponse = new ExtendedResponseCodec();
1065    
1066            // Internal : String oid -> Codec : OID responseName
1067            try
1068            {
1069                extendedResponse.setResponseName( new OID( internalExtendedResponse.getResponseName() ) );
1070            }
1071            catch ( DecoderException de )
1072            {
1073                LOG.warn( "The OID " + internalExtendedResponse.getResponseName() + " is invalid : " + de.getMessage() );
1074                extendedResponse.setResponseName( null );
1075            }
1076    
1077            // Internal : byte [] value -> Codec : Object response
1078            extendedResponse.setResponse( internalExtendedResponse.getResponse() );
1079    
1080            // Transform the ldapResult
1081            extendedResponse.setLdapResult( transformLdapResult( ( LdapResultImpl ) internalExtendedResponse
1082                .getLdapResult() ) );
1083    
1084            return extendedResponse;
1085        }
1086    
1087    
1088        /**
1089         * Transform a Internal IntermediateResponse to a Codec IntermediateResponse
1090         * 
1091         * @param internalMessage The incoming Internal IntermediateResponse
1092         * @return The IntermediateResponseCodec instance
1093         */
1094        private static LdapMessageCodec transformIntermediateResponse( InternalMessage internalMessage )
1095        {
1096            IntermediateResponseImpl internalIntermediateResponse = (IntermediateResponseImpl) internalMessage;
1097            IntermediateResponseCodec intermediateResponse = new IntermediateResponseCodec();
1098    
1099            // Internal : String oid -> Codec : String responseName
1100            try
1101            {
1102                intermediateResponse.setResponseName( new OID( internalIntermediateResponse.getResponseName() ) );
1103            }
1104            catch ( DecoderException de )
1105            {
1106                LOG.warn( "The OID " + internalIntermediateResponse.getResponseName() + " is invalid : " + de.getMessage() );
1107                intermediateResponse.setResponseName( null );
1108            }
1109    
1110            // Internal : byte [] value -> Codec : byte[] value
1111            intermediateResponse.setResponseValue( internalIntermediateResponse.getResponseValue() );
1112    
1113            // Transform the ldapResult
1114            intermediateResponse.setLdapResult( transformLdapResult( ( LdapResultImpl ) internalIntermediateResponse
1115                .getLdapResult() ) );
1116    
1117            return intermediateResponse;
1118        }
1119    
1120    
1121        /**
1122         * Transform a Internal ModifyResponse to a Codec ModifyResponse
1123         * 
1124         * @param internalMessage The incoming Internal ModifyResponse
1125         * @return The ModifyResponseCodec instance
1126         */
1127        private static LdapMessageCodec transformModifyResponse( InternalMessage internalMessage )
1128        {
1129            ModifyResponseImpl internalModifyResponse = ( ModifyResponseImpl ) internalMessage;
1130    
1131            ModifyResponseCodec modifyResponse = new ModifyResponseCodec();
1132    
1133            // Transform the ldapResult
1134            modifyResponse.setLdapResult( transformLdapResult( ( LdapResultImpl ) internalModifyResponse.getLdapResult() ) );
1135    
1136            return modifyResponse;
1137        }
1138    
1139    
1140        /**
1141         * Transform a Internal ModifyDNResponse to a Codec ModifyDNResponse
1142         * 
1143         * @param internalMessage The incoming Internal ModifyDNResponse
1144         * @return The ModifyDnResponseCodec instance
1145         */
1146        private static LdapMessageCodec transformModifyDNResponse( InternalMessage internalMessage )
1147        {
1148            ModifyDnResponseImpl internalModifyDNResponse = ( ModifyDnResponseImpl ) internalMessage;
1149    
1150            ModifyDNResponseCodec modifyDNResponse = new ModifyDNResponseCodec();
1151    
1152            // Transform the ldapResult
1153            modifyDNResponse.setLdapResult( transformLdapResult( ( LdapResultImpl ) internalModifyDNResponse
1154                .getLdapResult() ) );
1155    
1156            return modifyDNResponse;
1157        }
1158    
1159    
1160        /**
1161         * Transform a Internal SearchResponseDone to a Codec SearchResultDone
1162         * 
1163         * @param internalMessage The incoming Internal SearchResponseDone
1164         * @return The SearchResultDone instance
1165         */
1166        private static LdapMessageCodec transformSearchResultDone( InternalMessage internalMessage )
1167        {
1168            SearchResponseDoneImpl internalSearchResponseDone = ( SearchResponseDoneImpl ) internalMessage;
1169            SearchResultDoneCodec searchResultDone = new SearchResultDoneCodec();
1170    
1171            // Transform the ldapResult
1172            searchResultDone.setLdapResult( transformLdapResult( ( LdapResultImpl ) internalSearchResponseDone
1173                .getLdapResult() ) );
1174    
1175            // Set the operation into the LdapMessage
1176            return searchResultDone;
1177        }
1178    
1179    
1180        /**
1181         * Transform a Internal SearchResponseEntry to a Codec SearchResultEntry
1182         * 
1183         * @param internalMessage The incoming Internal SearchResponseEntry
1184         */
1185        private static LdapMessageCodec transformSearchResultEntry( InternalMessage internalMessage )
1186        {
1187            SearchResponseEntryImpl internalSearchResultResponse = ( SearchResponseEntryImpl ) internalMessage;
1188            SearchResultEntryCodec searchResultEntry = new SearchResultEntryCodec();
1189    
1190            // Internal : DN dn -> Codec : DN objectName
1191            searchResultEntry.setObjectName( internalSearchResultResponse.getObjectName() );
1192    
1193            // Internal : Attributes attributes -> Codec : ArrayList
1194            // partialAttributeList
1195            searchResultEntry.setEntry( internalSearchResultResponse.getEntry() );
1196    
1197            return searchResultEntry;
1198        }
1199    
1200    
1201        /**
1202         * Transform a Internal SearchResponseReference to a Codec
1203         * SearchResultReference
1204         * 
1205         * @param internalMessage The incoming Internal SearchResponseReference
1206         */
1207        private static LdapMessageCodec transformSearchResultReference( InternalMessage internalMessage )
1208        {
1209            SearchResponseReferenceImpl internalSearchResponseReference = ( SearchResponseReferenceImpl ) internalMessage;
1210            SearchResultReferenceCodec searchResultReference = new SearchResultReferenceCodec();
1211    
1212            // Internal : Referral m_referral -> Codec: ArrayList
1213            // searchResultReferences
1214            InternalReferral referrals = internalSearchResponseReference.getReferral();
1215    
1216            // Loop on all referals
1217            if ( referrals != null )
1218            {
1219                Collection<String> urls = referrals.getLdapUrls();
1220    
1221                if ( urls != null )
1222                {
1223                    for ( String url:urls)
1224                    {
1225                        try
1226                        {
1227                            searchResultReference.addSearchResultReference( new LdapURL( url ) );
1228                        }
1229                        catch ( LdapURLEncodingException luee )
1230                        {
1231                            LOG.warn( "The LdapURL " + url + " is incorrect : " + luee.getMessage() );
1232                        }
1233                    }
1234                }
1235            }
1236    
1237            return searchResultReference;
1238        }
1239    
1240    
1241        /**
1242         * Transform the internal message to a codec message.
1243         * 
1244         * @param msg the message to transform
1245         * @return the msg transformed
1246         */
1247        public static Object transform( InternalMessage msg )
1248        {
1249            if ( IS_DEBUG )
1250            {
1251                LOG.debug( "Transforming message type " + msg.getType() );
1252            }
1253    
1254            LdapMessageCodec codecMessage = null;
1255    
1256            switch ( msg.getType() )
1257            {
1258                case SEARCH_RESULT_ENTRY :
1259                    codecMessage = transformSearchResultEntry( msg );
1260                    break;
1261                    
1262                case SEARCH_RESULT_DONE :
1263                    codecMessage = transformSearchResultDone( msg );
1264                    break;
1265                    
1266                case SEARCH_RESULT_REFERENCE :
1267                    codecMessage = transformSearchResultReference( msg );
1268                    break;
1269                    
1270                case BIND_RESPONSE :
1271                    codecMessage = transformBindResponse( msg );
1272                    break;
1273                    
1274                case BIND_REQUEST :
1275                    codecMessage = transformBindRequest( msg );
1276                    break;
1277                    
1278                case ADD_RESPONSE :
1279                    codecMessage = transformAddResponse( msg );
1280                    break;
1281                    
1282                case COMPARE_RESPONSE :
1283                    codecMessage = transformCompareResponse( msg );
1284                    break;
1285                    
1286                case DEL_RESPONSE :
1287                    codecMessage = transformDelResponse( msg );
1288                    break;
1289             
1290                case MODIFY_RESPONSE :
1291                    codecMessage = transformModifyResponse( msg );
1292                    break;
1293    
1294                case MODIFYDN_RESPONSE :
1295                    codecMessage = transformModifyDNResponse( msg );
1296                    break;
1297                    
1298                case EXTENDED_RESPONSE :
1299                    codecMessage = transformExtendedResponse( msg );
1300                    break;
1301                    
1302                case INTERMEDIATE_RESPONSE :
1303                    codecMessage = transformIntermediateResponse( msg );
1304                    break;
1305            }
1306    
1307            codecMessage.setMessageId( msg.getMessageId() );
1308    
1309            // We also have to transform the controls...
1310            if ( !msg.getControls().isEmpty() )
1311            {
1312                transformControlsInternalToCodec( codecMessage, msg );
1313            }
1314    
1315            if ( IS_DEBUG )
1316            {
1317                LOG.debug( "Transformed message : " + codecMessage );
1318            }
1319    
1320            return codecMessage;
1321        }
1322    
1323    
1324        /**
1325         * TODO finish this implementation. Takes Codec Controls, transforming 
1326         * them to Internal Controls and populates the Internal message with them.
1327         *
1328         * @param codecMessage the Codec message
1329         * @param msg the Internal message
1330         */
1331        private static void transformControlsCodecToInternal( LdapMessageCodec codecMessage, InternalMessage internalMessage )
1332        {
1333            if ( codecMessage.getControls() == null )
1334            {
1335                return;
1336            }
1337            
1338            for ( final Control codecControl:codecMessage.getControls() )
1339            {
1340                internalMessage.add( codecControl );
1341            }
1342        }
1343        
1344        
1345        /**
1346         * Transforms the controls
1347         * @param codecMessage The Codec SearchResultReference to produce
1348         * @param msg The incoming Internal Message
1349         */
1350        private static void transformControlsInternalToCodec( LdapMessageCodec codecMessage, InternalMessage internalMessage )
1351        {
1352            if ( internalMessage.getControls() == null )
1353            {
1354                return;
1355            }
1356            
1357            for ( Control control:internalMessage.getControls().values() )
1358            {
1359                codecMessage.addControl( control );
1360            }
1361        }
1362    }