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.api.ldap.util;
021
022
023import java.util.Hashtable;
024
025import javax.naming.AuthenticationException;
026import javax.naming.AuthenticationNotSupportedException;
027import javax.naming.CommunicationException;
028import javax.naming.Context;
029import javax.naming.ContextNotEmptyException;
030import javax.naming.InvalidNameException;
031import javax.naming.Name;
032import javax.naming.NameAlreadyBoundException;
033import javax.naming.NameNotFoundException;
034import javax.naming.NamingException;
035import javax.naming.NoPermissionException;
036import javax.naming.OperationNotSupportedException;
037import javax.naming.PartialResultException;
038import javax.naming.ReferralException;
039import javax.naming.ServiceUnavailableException;
040import javax.naming.TimeLimitExceededException;
041import javax.naming.directory.AttributeInUseException;
042import javax.naming.directory.InvalidAttributeIdentifierException;
043import javax.naming.directory.InvalidAttributeValueException;
044import javax.naming.directory.InvalidSearchFilterException;
045import javax.naming.directory.NoSuchAttributeException;
046import javax.naming.directory.SchemaViolationException;
047import javax.naming.ldap.LdapName;
048
049import org.apache.directory.api.asn1.DecoderException;
050import org.apache.directory.api.asn1.EncoderException;
051import org.apache.directory.api.ldap.codec.api.LdapApiService;
052import org.apache.directory.api.ldap.model.exception.LdapAffectMultipleDsaException;
053import org.apache.directory.api.ldap.model.exception.LdapAliasDereferencingException;
054import org.apache.directory.api.ldap.model.exception.LdapAliasException;
055import org.apache.directory.api.ldap.model.exception.LdapAttributeInUseException;
056import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
057import org.apache.directory.api.ldap.model.exception.LdapAuthenticationNotSupportedException;
058import org.apache.directory.api.ldap.model.exception.LdapContextNotEmptyException;
059import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
060import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeTypeException;
061import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
062import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
063import org.apache.directory.api.ldap.model.exception.LdapInvalidSearchFilterException;
064import org.apache.directory.api.ldap.model.exception.LdapLoopDetectedException;
065import org.apache.directory.api.ldap.model.exception.LdapNoPermissionException;
066import org.apache.directory.api.ldap.model.exception.LdapNoSuchAttributeException;
067import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
068import org.apache.directory.api.ldap.model.exception.LdapOperationErrorException;
069import org.apache.directory.api.ldap.model.exception.LdapOtherException;
070import org.apache.directory.api.ldap.model.exception.LdapPartialResultException;
071import org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException;
072import org.apache.directory.api.ldap.model.exception.LdapReferralException;
073import org.apache.directory.api.ldap.model.exception.LdapSchemaViolationException;
074import org.apache.directory.api.ldap.model.exception.LdapServiceUnavailableException;
075import org.apache.directory.api.ldap.model.exception.LdapTimeLimitExceededException;
076import org.apache.directory.api.ldap.model.exception.LdapUnwillingToPerformException;
077import org.apache.directory.api.ldap.model.message.Control;
078import org.apache.directory.api.ldap.model.name.Dn;
079
080
081/**
082 * An utility class to convert back and forth JNDI classes to ADS classes.
083 * 
084 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
085 */
086public final class JndiUtils
087{
088    /**
089     * Private constructor.
090     */
091    private JndiUtils()
092    {
093    }
094
095
096   /**
097    * Convert a LDAP API control to a JNDI control
098    * @param codec The LDAP API service to use
099    * @param control The control to convert
100    * @return A JNDI control
101    * @throws EncoderException If the conversion failed
102     * @deprecated We don't use JNDI anymore
103    */
104    @Deprecated
105    public static javax.naming.ldap.Control toJndiControl( LdapApiService codec, Control control )
106        throws EncoderException
107    {
108        return codec.toJndiControl( control );
109    }
110
111
112    /**
113     * Convert some LDAP API controls to JNDI controls
114     * @param codec The LDAP API service to use
115     * @param controls The controls to convert
116     * @return Array of JNDI control
117     * @throws EncoderException If the conversion failed
118     * @deprecated We don't use JNDI anymore
119     */
120    @Deprecated
121    public static javax.naming.ldap.Control[] toJndiControls( LdapApiService codec, Control... controls )
122        throws EncoderException
123    {
124        if ( controls != null )
125        {
126            javax.naming.ldap.Control[] jndiControls = new javax.naming.ldap.Control[controls.length];
127            int i = 0;
128
129            for ( Control control : controls )
130            {
131                jndiControls[i++] = toJndiControl( codec, control );
132            }
133
134            return jndiControls;
135        }
136        else
137        {
138            return null;
139        }
140    }
141
142
143    /**
144     * Convert a JNDI control to a LDAP API control
145     * @param codec The LDAP API service to use
146     * @param jndiControl The control to convert
147     * @return A LDAP API control
148     * @throws DecoderException If the conversion failed
149     * @deprecated We don't use JNDI anymore
150     */
151    @Deprecated
152    public static Control fromJndiControl( LdapApiService codec, javax.naming.ldap.Control jndiControl )
153        throws DecoderException
154    {
155        return codec.fromJndiControl( jndiControl );
156    }
157
158
159    /**
160     * Convert some JNDI controls to LDAP API controls
161     * @param codec The LDAP API service to use
162     * @param jndiControls The controls to convert
163     * @return An array of LDAP API control
164     * @throws DecoderException If the conversion failed
165     * @deprecated We don't use JNDI anymore
166     */
167    @Deprecated
168    public static Control[] fromJndiControls( LdapApiService codec, javax.naming.ldap.Control... jndiControls )
169        throws DecoderException
170    {
171        if ( jndiControls != null )
172        {
173            Control[] controls = new Control[jndiControls.length];
174            int i = 0;
175
176            for ( javax.naming.ldap.Control jndiControl : jndiControls )
177            {
178                controls[i++] = fromJndiControl( codec, jndiControl );
179            }
180
181            return controls;
182        }
183        else
184        {
185            return null;
186        }
187    }
188
189
190    /**
191     * Wraps a LDAP exception into a NaingException
192     * 
193     * @param t The original exception
194     * @throws NamingException The wrapping JNDI exception
195     */
196    public static void wrap( Throwable t ) throws NamingException
197    {
198        if ( t instanceof NamingException )
199        {
200            throw ( NamingException ) t;
201        }
202
203        NamingException ne = null;
204
205        if ( t instanceof LdapAffectMultipleDsaException )
206        {
207            ne = new NamingException( t.getLocalizedMessage() );
208        }
209        else if ( t instanceof LdapAliasDereferencingException )
210        {
211            ne = new NamingException( t.getLocalizedMessage() );
212        }
213        else if ( t instanceof LdapAliasException )
214        {
215            ne = new NamingException( t.getLocalizedMessage() );
216        }
217        else if ( t instanceof LdapAttributeInUseException )
218        {
219            ne = new AttributeInUseException( t.getLocalizedMessage() );
220        }
221        else if ( t instanceof LdapAuthenticationException )
222        {
223            ne = new AuthenticationException( t.getLocalizedMessage() );
224        }
225        else if ( t instanceof LdapAuthenticationNotSupportedException )
226        {
227            ne = new AuthenticationNotSupportedException( t.getLocalizedMessage() );
228        }
229        else if ( t instanceof LdapContextNotEmptyException )
230        {
231            ne = new ContextNotEmptyException( t.getLocalizedMessage() );
232        }
233        else if ( t instanceof LdapEntryAlreadyExistsException )
234        {
235            ne = new NameAlreadyBoundException( t.getLocalizedMessage() );
236        }
237        else if ( t instanceof LdapInvalidAttributeTypeException )
238        {
239            ne = new InvalidAttributeIdentifierException( t.getLocalizedMessage() );
240        }
241        else if ( t instanceof LdapInvalidAttributeValueException )
242        {
243            ne = new InvalidAttributeValueException( t.getLocalizedMessage() );
244        }
245        else if ( t instanceof LdapInvalidDnException )
246        {
247            ne = new InvalidNameException( t.getLocalizedMessage() );
248        }
249        else if ( t instanceof LdapInvalidSearchFilterException )
250        {
251            ne = new InvalidSearchFilterException( t.getLocalizedMessage() );
252        }
253        else if ( t instanceof LdapLoopDetectedException )
254        {
255            ne = new NamingException( t.getLocalizedMessage() );
256        }
257        else if ( t instanceof LdapNoPermissionException )
258        {
259            ne = new NoPermissionException( t.getLocalizedMessage() );
260        }
261        else if ( t instanceof LdapNoSuchAttributeException )
262        {
263            ne = new NoSuchAttributeException( t.getLocalizedMessage() );
264        }
265        else if ( t instanceof LdapNoSuchObjectException )
266        {
267            ne = new NameNotFoundException( t.getLocalizedMessage() );
268        }
269        else if ( t instanceof LdapOperationErrorException )
270        {
271            ne = new NamingException( t.getLocalizedMessage() );
272        }
273        else if ( t instanceof LdapOtherException )
274        {
275            ne = new NamingException( t.getLocalizedMessage() );
276        }
277        else if ( t instanceof LdapProtocolErrorException )
278        {
279            ne = new CommunicationException( t.getLocalizedMessage() );
280        }
281        else if ( t instanceof LdapReferralException )
282        {
283            ne = new WrappedReferralException( ( LdapReferralException ) t );
284        }
285        else if ( t instanceof LdapPartialResultException )
286        {
287            ne = new WrappedPartialResultException( ( LdapPartialResultException ) t );
288        }
289        else if ( t instanceof LdapSchemaViolationException )
290        {
291            ne = new SchemaViolationException( t.getLocalizedMessage() );
292        }
293        else if ( t instanceof LdapServiceUnavailableException )
294        {
295            ne = new ServiceUnavailableException( t.getLocalizedMessage() );
296        }
297        else if ( t instanceof LdapTimeLimitExceededException )
298        {
299            ne = new TimeLimitExceededException( t.getLocalizedMessage() );
300        }
301        else if ( t instanceof LdapUnwillingToPerformException )
302        {
303            ne = new OperationNotSupportedException( t.getLocalizedMessage() );
304        }
305        else
306        {
307            ne = new NamingException( t.getLocalizedMessage() );
308        }
309
310        ne.setRootCause( t );
311
312        throw ne;
313    }
314
315
316    /**
317     * Convert a Dn to a {@link javax.naming.Name}
318     *
319     * @param dn The Dn to convert
320     * @return A Name
321     */
322    public static Name toName( Dn dn )
323    {
324        try
325        {
326            return new LdapName( dn.toString() );
327        }
328        catch ( InvalidNameException ine )
329        {
330            // TODO : check if we must throw an exception.
331            // Logically, the Dn must be valid.
332            return null;
333        }
334    }
335
336
337    /**
338     * Convert a {@link javax.naming.Name} to a Dn
339     *
340     * @param name The Name to convert
341     * @return A Dn
342     */
343    public static Dn fromName( Name name )
344    {
345        try
346        {
347            Dn dn = new Dn( name.toString() );
348
349            return dn;
350        }
351        catch ( LdapInvalidDnException lide )
352        {
353            // TODO : check if we must throw an exception.
354            // Logically, the Name must be valid.
355            return null;
356        }
357    }
358}
359
360// a ReferralException around the LdapReferralException to be used in tests
361class WrappedReferralException extends ReferralException
362{
363    private static final long serialVersionUID = 1L;
364
365    private LdapReferralException lre;
366
367
368    WrappedReferralException( LdapReferralException lre )
369    {
370        this.lre = lre;
371    }
372
373
374    @Override
375    public boolean skipReferral()
376    {
377        return lre.skipReferral();
378    }
379
380
381    @Override
382    public void retryReferral()
383    {
384        lre.retryReferral();
385    }
386
387
388    @Override
389    public Object getReferralInfo()
390    {
391        return lre.getReferralInfo();
392    }
393
394
395    @Override
396    public Context getReferralContext( Hashtable<?, ?> env ) throws NamingException
397    {
398        return lre.getReferralContext( env );
399    }
400
401
402    @Override
403    public Context getReferralContext() throws NamingException
404    {
405        return lre.getReferralContext();
406    }
407
408
409    @Override
410    public Name getRemainingName()
411    {
412        return JndiUtils.toName( lre.getRemainingDn() );
413    }
414
415
416    @Override
417    public Object getResolvedObj()
418    {
419        return lre.getResolvedObject();
420    }
421
422
423    @Override
424    public Name getResolvedName()
425    {
426        return JndiUtils.toName( lre.getResolvedDn() );
427    }
428}
429
430// a PartialResultException around the LdapPartialResultException to be used in tests
431class WrappedPartialResultException extends PartialResultException
432{
433    private static final long serialVersionUID = 1L;
434
435    private LdapPartialResultException lpre;
436
437
438    WrappedPartialResultException( LdapPartialResultException lpre )
439    {
440        this.lpre = lpre;
441    }
442
443
444    @Override
445    public Name getRemainingName()
446    {
447        return JndiUtils.toName( lpre.getRemainingDn() );
448    }
449
450
451    @Override
452    public Object getResolvedObj()
453    {
454        return lpre.getResolvedObject();
455    }
456
457
458    @Override
459    public Name getResolvedName()
460    {
461        return JndiUtils.toName( lpre.getResolvedDn() );
462    }
463}