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 *     https://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 request 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 request control
148     * @throws DecoderException If the conversion failed
149     * @deprecated We don't use JNDI anymore
150     */
151    @Deprecated
152    public static Control fromJndiRequestControl( LdapApiService codec, javax.naming.ldap.Control jndiControl )
153        throws DecoderException
154    {
155        return codec.fromJndiRequestControl( jndiControl );
156    }
157
158
159    /**
160     * Convert a JNDI response control to a LDAP API control
161     * @param codec The LDAP API service to use
162     * @param jndiControl The control to convert
163     * @return A LDAP API response control
164     * @throws DecoderException If the conversion failed
165     * @deprecated We don't use JNDI anymore
166     */
167    @Deprecated
168    public static Control fromJndiResponseControl( LdapApiService codec, javax.naming.ldap.Control jndiControl )
169        throws DecoderException
170    {
171        return codec.fromJndiResponseControl( jndiControl );
172    }
173
174
175    /**
176     * Convert some JNDI controls to LDAP API controls
177     * @param codec The LDAP API service to use
178     * @param jndiControls The controls to convert
179     * @return An array of LDAP API control
180     * @throws DecoderException If the conversion failed
181     * @deprecated We don't use JNDI anymore
182     */
183    @Deprecated
184    public static Control[] fromJndiRequestControls( LdapApiService codec, javax.naming.ldap.Control... jndiControls )
185        throws DecoderException
186    {
187        if ( jndiControls != null )
188        {
189            Control[] controls = new Control[jndiControls.length];
190            int i = 0;
191
192            for ( javax.naming.ldap.Control jndiControl : jndiControls )
193            {
194                controls[i++] = fromJndiRequestControl( codec, jndiControl );
195            }
196
197            return controls;
198        }
199        else
200        {
201            return null;
202        }
203    }
204
205
206    /**
207     * Wraps a LDAP exception into a NaingException
208     * 
209     * @param t The original exception
210     * @throws NamingException The wrapping JNDI exception
211     */
212    public static void wrap( Throwable t ) throws NamingException
213    {
214        if ( t instanceof NamingException )
215        {
216            throw ( NamingException ) t;
217        }
218
219        NamingException ne;
220
221        if ( ( t instanceof LdapAffectMultipleDsaException )
222            || ( t instanceof LdapAliasDereferencingException )
223            || ( t instanceof LdapLoopDetectedException )
224            || ( t instanceof LdapAliasException ) 
225            || ( t instanceof LdapOperationErrorException ) 
226            || ( t instanceof LdapOtherException ) )
227        {
228            ne = new NamingException( t.getLocalizedMessage() );
229        }
230        else if ( t instanceof LdapAttributeInUseException )
231        {
232            ne = new AttributeInUseException( t.getLocalizedMessage() );
233        }
234        else if ( t instanceof LdapAuthenticationException )
235        {
236            ne = new AuthenticationException( t.getLocalizedMessage() );
237        }
238        else if ( t instanceof LdapAuthenticationNotSupportedException )
239        {
240            ne = new AuthenticationNotSupportedException( t.getLocalizedMessage() );
241        }
242        else if ( t instanceof LdapContextNotEmptyException )
243        {
244            ne = new ContextNotEmptyException( t.getLocalizedMessage() );
245        }
246        else if ( t instanceof LdapEntryAlreadyExistsException )
247        {
248            ne = new NameAlreadyBoundException( t.getLocalizedMessage() );
249        }
250        else if ( t instanceof LdapInvalidAttributeTypeException )
251        {
252            ne = new InvalidAttributeIdentifierException( t.getLocalizedMessage() );
253        }
254        else if ( t instanceof LdapInvalidAttributeValueException )
255        {
256            ne = new InvalidAttributeValueException( t.getLocalizedMessage() );
257        }
258        else if ( t instanceof LdapInvalidDnException )
259        {
260            ne = new InvalidNameException( t.getLocalizedMessage() );
261        }
262        else if ( t instanceof LdapInvalidSearchFilterException )
263        {
264            ne = new InvalidSearchFilterException( t.getLocalizedMessage() );
265        }
266        else if ( t instanceof LdapNoPermissionException )
267        {
268            ne = new NoPermissionException( t.getLocalizedMessage() );
269        }
270        else if ( t instanceof LdapNoSuchAttributeException )
271        {
272            ne = new NoSuchAttributeException( t.getLocalizedMessage() );
273        }
274        else if ( t instanceof LdapNoSuchObjectException )
275        {
276            ne = new NameNotFoundException( t.getLocalizedMessage() );
277        }
278        else if ( t instanceof LdapProtocolErrorException )
279        {
280            ne = new CommunicationException( t.getLocalizedMessage() );
281        }
282        else if ( t instanceof LdapReferralException )
283        {
284            ne = new WrappedReferralException( ( LdapReferralException ) t );
285        }
286        else if ( t instanceof LdapPartialResultException )
287        {
288            ne = new WrappedPartialResultException( ( LdapPartialResultException ) t );
289        }
290        else if ( t instanceof LdapSchemaViolationException )
291        {
292            ne = new SchemaViolationException( t.getLocalizedMessage() );
293        }
294        else if ( t instanceof LdapServiceUnavailableException )
295        {
296            ne = new ServiceUnavailableException( t.getLocalizedMessage() );
297        }
298        else if ( t instanceof LdapTimeLimitExceededException )
299        {
300            ne = new TimeLimitExceededException( t.getLocalizedMessage() );
301        }
302        else if ( t instanceof LdapUnwillingToPerformException )
303        {
304            ne = new OperationNotSupportedException( t.getLocalizedMessage() );
305        }
306        else
307        {
308            ne = new NamingException( t.getLocalizedMessage() );
309        }
310
311        ne.setRootCause( t );
312
313        throw ne;
314    }
315
316
317    /**
318     * Convert a Dn to a {@link javax.naming.Name}
319     *
320     * @param dn The Dn to convert
321     * @return A Name
322     */
323    public static Name toName( Dn dn )
324    {
325        try
326        {
327            return new LdapName( dn.toString() );
328        }
329        catch ( InvalidNameException ine )
330        {
331            // TODO : check if we must throw an exception.
332            // Logically, the Dn must be valid.
333            return null;
334        }
335    }
336
337
338    /**
339     * Convert a {@link javax.naming.Name} to a Dn
340     *
341     * @param name The Name to convert
342     * @return A Dn
343     */
344    public static Dn fromName( Name name )
345    {
346        try
347        {
348            return new Dn( name.toString() );
349        }
350        catch ( LdapInvalidDnException lide )
351        {
352            // TODO : check if we must throw an exception.
353            // Logically, the Name must be valid.
354            return null;
355        }
356    }
357}
358
359// a ReferralException around the LdapReferralException to be used in tests
360class WrappedReferralException extends ReferralException
361{
362    private static final long serialVersionUID = 1L;
363
364    private LdapReferralException lre;
365
366
367    WrappedReferralException( LdapReferralException lre )
368    {
369        this.lre = lre;
370    }
371
372
373    /**
374     * {@inheritDoc}
375     */
376    @Override
377    public boolean skipReferral()
378    {
379        return lre.skipReferral();
380    }
381
382
383    /**
384     * {@inheritDoc}
385     */
386    @Override
387    public void retryReferral()
388    {
389        lre.retryReferral();
390    }
391
392
393    /**
394     * {@inheritDoc}
395     */
396    @Override
397    public Object getReferralInfo()
398    {
399        return lre.getReferralInfo();
400    }
401
402
403    /**
404     * {@inheritDoc}
405     */
406    @Override
407    public Context getReferralContext( Hashtable<?, ?> env ) throws NamingException
408    {
409        return lre.getReferralContext( env );
410    }
411
412
413    /**
414     * {@inheritDoc}
415     */
416    @Override
417    public Context getReferralContext() throws NamingException
418    {
419        return lre.getReferralContext();
420    }
421
422
423    /**
424     * {@inheritDoc}
425     */
426    @Override
427    public Name getRemainingName()
428    {
429        return JndiUtils.toName( lre.getRemainingDn() );
430    }
431
432
433    /**
434     * {@inheritDoc}
435     */
436    @Override
437    public Object getResolvedObj()
438    {
439        return lre.getResolvedObject();
440    }
441
442
443    /**
444     * {@inheritDoc}
445     */
446    @Override
447    public Name getResolvedName()
448    {
449        return JndiUtils.toName( lre.getResolvedDn() );
450    }
451}
452
453// a PartialResultException around the LdapPartialResultException to be used in tests
454class WrappedPartialResultException extends PartialResultException
455{
456    private static final long serialVersionUID = 1L;
457
458    private LdapPartialResultException lpre;
459
460
461    WrappedPartialResultException( LdapPartialResultException lpre )
462    {
463        this.lpre = lpre;
464    }
465
466
467    /**
468     * {@inheritDoc}
469     */
470    @Override
471    public Name getRemainingName()
472    {
473        return JndiUtils.toName( lpre.getRemainingDn() );
474    }
475
476
477    /**
478     * {@inheritDoc}
479     */
480    @Override
481    public Object getResolvedObj()
482    {
483        return lpre.getResolvedObject();
484    }
485
486
487    /**
488     * {@inheritDoc}
489     */
490    @Override
491    public Name getResolvedName()
492    {
493        return JndiUtils.toName( lpre.getResolvedDn() );
494    }
495}