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    // @TODO not really needed and can be moved out
097    public static javax.naming.ldap.Control toJndiControl( LdapApiService codec, Control control )
098        throws EncoderException
099    {
100        return codec.toJndiControl( control );
101    }
102
103
104    // @TODO not really needed and can be moved out
105    public static javax.naming.ldap.Control[] toJndiControls( LdapApiService codec, Control... controls )
106        throws EncoderException
107    {
108        if ( controls != null )
109        {
110            javax.naming.ldap.Control[] jndiControls = new javax.naming.ldap.Control[controls.length];
111            int i = 0;
112
113            for ( Control control : controls )
114            {
115                jndiControls[i++] = toJndiControl( codec, control );
116            }
117
118            return jndiControls;
119        }
120        else
121        {
122            return null;
123        }
124    }
125
126
127    // @TODO not really needed and can be moved out
128    public static Control fromJndiControl( LdapApiService codec, javax.naming.ldap.Control jndiControl )
129        throws DecoderException
130    {
131        return codec.fromJndiControl( jndiControl );
132    }
133
134
135    // @TODO not really needed and can be moved out
136    public static Control[] fromJndiControls( LdapApiService codec, javax.naming.ldap.Control... jndiControls )
137        throws DecoderException
138    {
139        if ( jndiControls != null )
140        {
141            Control[] controls = new Control[jndiControls.length];
142            int i = 0;
143
144            for ( javax.naming.ldap.Control jndiControl : jndiControls )
145            {
146                controls[i++] = fromJndiControl( codec, jndiControl );
147            }
148
149            return controls;
150        }
151        else
152        {
153            return null;
154        }
155    }
156
157
158    public static void wrap( Throwable t ) throws NamingException
159    {
160        if ( t instanceof NamingException )
161        {
162            throw ( NamingException ) t;
163        }
164
165        NamingException ne = null;
166
167        if ( t instanceof LdapAffectMultipleDsaException )
168        {
169            ne = new NamingException( t.getLocalizedMessage() );
170        }
171        else if ( t instanceof LdapAliasDereferencingException )
172        {
173            ne = new NamingException( t.getLocalizedMessage() );
174        }
175        else if ( t instanceof LdapAliasException )
176        {
177            ne = new NamingException( t.getLocalizedMessage() );
178        }
179        else if ( t instanceof LdapAttributeInUseException )
180        {
181            ne = new AttributeInUseException( t.getLocalizedMessage() );
182        }
183        else if ( t instanceof LdapAuthenticationException )
184        {
185            ne = new AuthenticationException( t.getLocalizedMessage() );
186        }
187        else if ( t instanceof LdapAuthenticationNotSupportedException )
188        {
189            ne = new AuthenticationNotSupportedException( t.getLocalizedMessage() );
190        }
191        else if ( t instanceof LdapContextNotEmptyException )
192        {
193            ne = new ContextNotEmptyException( t.getLocalizedMessage() );
194        }
195        else if ( t instanceof LdapEntryAlreadyExistsException )
196        {
197            ne = new NameAlreadyBoundException( t.getLocalizedMessage() );
198        }
199        else if ( t instanceof LdapInvalidAttributeTypeException )
200        {
201            ne = new InvalidAttributeIdentifierException( t.getLocalizedMessage() );
202        }
203        else if ( t instanceof LdapInvalidAttributeValueException )
204        {
205            ne = new InvalidAttributeValueException( t.getLocalizedMessage() );
206        }
207        else if ( t instanceof LdapInvalidDnException )
208        {
209            ne = new InvalidNameException( t.getLocalizedMessage() );
210        }
211        else if ( t instanceof LdapInvalidSearchFilterException )
212        {
213            ne = new InvalidSearchFilterException( t.getLocalizedMessage() );
214        }
215        else if ( t instanceof LdapLoopDetectedException )
216        {
217            ne = new NamingException( t.getLocalizedMessage() );
218        }
219        else if ( t instanceof LdapNoPermissionException )
220        {
221            ne = new NoPermissionException( t.getLocalizedMessage() );
222        }
223        else if ( t instanceof LdapNoSuchAttributeException )
224        {
225            ne = new NoSuchAttributeException( t.getLocalizedMessage() );
226        }
227        else if ( t instanceof LdapNoSuchObjectException )
228        {
229            ne = new NameNotFoundException( t.getLocalizedMessage() );
230        }
231        else if ( t instanceof LdapOperationErrorException )
232        {
233            ne = new NamingException( t.getLocalizedMessage() );
234        }
235        else if ( t instanceof LdapOtherException )
236        {
237            ne = new NamingException( t.getLocalizedMessage() );
238        }
239        else if ( t instanceof LdapProtocolErrorException )
240        {
241            ne = new CommunicationException( t.getLocalizedMessage() );
242        }
243        else if ( t instanceof LdapReferralException )
244        {
245            ne = new WrappedReferralException( ( LdapReferralException ) t );
246        }
247        else if ( t instanceof LdapPartialResultException )
248        {
249            ne = new WrappedPartialResultException( ( LdapPartialResultException ) t );
250        }
251        else if ( t instanceof LdapSchemaViolationException )
252        {
253            ne = new SchemaViolationException( t.getLocalizedMessage() );
254        }
255        else if ( t instanceof LdapServiceUnavailableException )
256        {
257            ne = new ServiceUnavailableException( t.getLocalizedMessage() );
258        }
259        else if ( t instanceof LdapTimeLimitExceededException )
260        {
261            ne = new TimeLimitExceededException( t.getLocalizedMessage() );
262        }
263        else if ( t instanceof LdapUnwillingToPerformException )
264        {
265            ne = new OperationNotSupportedException( t.getLocalizedMessage() );
266        }
267        else
268        {
269            ne = new NamingException( t.getLocalizedMessage() );
270        }
271
272        ne.setRootCause( t );
273
274        throw ne;
275    }
276
277
278    /**
279     * Convert a Dn to a {@link javax.naming.Name}
280     *
281     * @param name The Dn to convert
282     * @return A Name
283     */
284    public static Name toName( Dn dn )
285    {
286        try
287        {
288            Name name = new LdapName( dn.toString() );
289
290            return name;
291        }
292        catch ( InvalidNameException ine )
293        {
294            // TODO : check if we must throw an exception.
295            // Logically, the Dn must be valid.
296            return null;
297        }
298    }
299
300
301    /**
302     * Convert a {@link javax.naming.Name} to a Dn
303     *
304     * @param name The Name to convert
305     * @return A Dn
306     */
307    public static Dn fromName( Name name )
308    {
309        try
310        {
311            Dn dn = new Dn( name.toString() );
312
313            return dn;
314        }
315        catch ( LdapInvalidDnException lide )
316        {
317            // TODO : check if we must throw an exception.
318            // Logically, the Name must be valid.
319            return null;
320        }
321    }
322}
323
324// a ReferralException around the LdapReferralException to be used in tests
325class WrappedReferralException extends ReferralException
326{
327    private static final long serialVersionUID = 1L;
328
329    private LdapReferralException lre;
330
331
332    public WrappedReferralException( LdapReferralException lre )
333    {
334        this.lre = lre;
335    }
336
337
338    @Override
339    public boolean skipReferral()
340    {
341        return lre.skipReferral();
342    }
343
344
345    @Override
346    public void retryReferral()
347    {
348        lre.retryReferral();
349    }
350
351
352    @Override
353    public Object getReferralInfo()
354    {
355        return lre.getReferralInfo();
356    }
357
358
359    @Override
360    public Context getReferralContext( Hashtable<?, ?> env ) throws NamingException
361    {
362        return lre.getReferralContext( env );
363    }
364
365
366    @Override
367    public Context getReferralContext() throws NamingException
368    {
369        return lre.getReferralContext();
370    }
371
372
373    @Override
374    public Name getRemainingName()
375    {
376        return JndiUtils.toName( lre.getRemainingDn() );
377    }
378
379
380    @Override
381    public Object getResolvedObj()
382    {
383        return lre.getResolvedObject();
384    }
385
386
387    @Override
388    public Name getResolvedName()
389    {
390        return JndiUtils.toName( lre.getResolvedDn() );
391    }
392}
393
394// a PartialResultException around the LdapPartialResultException to be used in tests
395class WrappedPartialResultException extends PartialResultException
396{
397    private static final long serialVersionUID = 1L;
398
399    private LdapPartialResultException lpre;
400
401
402    public WrappedPartialResultException( LdapPartialResultException lpre )
403    {
404        this.lpre = lpre;
405    }
406
407
408    @Override
409    public Name getRemainingName()
410    {
411        return JndiUtils.toName( lpre.getRemainingDn() );
412    }
413
414
415    @Override
416    public Object getResolvedObj()
417    {
418        return lpre.getResolvedObject();
419    }
420
421
422    @Override
423    public Name getResolvedName()
424    {
425        return JndiUtils.toName( lpre.getResolvedDn() );
426    }
427}