001 /*
002 * Copyright 2009-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2009-2014 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.ldap.sdk.migrate.jndi;
022
023
024
025 import java.util.Collection;
026 import javax.naming.NamingEnumeration;
027 import javax.naming.NamingException;
028 import javax.naming.directory.Attributes;
029 import javax.naming.directory.BasicAttribute;
030 import javax.naming.directory.BasicAttributes;
031 import javax.naming.directory.DirContext;
032 import javax.naming.directory.ModificationItem;
033 import javax.naming.directory.SearchResult;
034 import javax.naming.ldap.BasicControl;
035 import javax.naming.ldap.ExtendedResponse;
036
037 import com.unboundid.asn1.ASN1Exception;
038 import com.unboundid.asn1.ASN1OctetString;
039 import com.unboundid.ldap.sdk.Attribute;
040 import com.unboundid.ldap.sdk.Control;
041 import com.unboundid.ldap.sdk.Entry;
042 import com.unboundid.ldap.sdk.ExtendedRequest;
043 import com.unboundid.ldap.sdk.ExtendedResult;
044 import com.unboundid.ldap.sdk.Modification;
045 import com.unboundid.ldap.sdk.ModificationType;
046 import com.unboundid.util.NotMutable;
047 import com.unboundid.util.ThreadSafety;
048 import com.unboundid.util.ThreadSafetyLevel;
049
050 import static com.unboundid.util.StaticUtils.*;
051
052
053
054 /**
055 * This utility class provides a set of methods that may be used to convert
056 * between data structures in the Java Naming and Directory Interface (JNDI)
057 * and the corresponding data structures in the UnboundID LDAP SDK for Java.
058 */
059 @NotMutable()
060 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
061 public final class JNDIConverter
062 {
063 /**
064 * An empty array of attributes.
065 */
066 private static final Attribute[] NO_ATTRIBUTES = new Attribute[0];
067
068
069
070
071 /**
072 * An empty array of JNDI controls.
073 */
074 private static final javax.naming.ldap.Control[] NO_JNDI_CONTROLS =
075 new javax.naming.ldap.Control[0];
076
077
078
079 /**
080 * An empty array of SDK modifications.
081 */
082 private static final Modification[] NO_MODIFICATIONS = new Modification[0];
083
084
085
086 /**
087 * An empty array of JNDI modification items.
088 */
089 private static final ModificationItem[] NO_MODIFICATION_ITEMS =
090 new ModificationItem[0];
091
092
093
094
095 /**
096 * An empty array of SDK controls.
097 */
098 private static final Control[] NO_SDK_CONTROLS = new Control[0];
099
100
101
102
103 /**
104 * Prevent this utility class from being instantiated.
105 */
106 private JNDIConverter()
107 {
108 // No implementation required.
109 }
110
111
112
113 /**
114 * Converts the provided JNDI attribute to an LDAP SDK attribute.
115 *
116 * @param a The attribute to be converted.
117 *
118 * @return The LDAP SDK attribute that corresponds to the provided JNDI
119 * attribute.
120 *
121 * @throws NamingException If a problem is encountered during the conversion
122 * process.
123 */
124 public static Attribute convertAttribute(
125 final javax.naming.directory.Attribute a)
126 throws NamingException
127 {
128 if (a == null)
129 {
130 return null;
131 }
132
133 final String name = a.getID();
134 final ASN1OctetString[] values = new ASN1OctetString[a.size()];
135
136 for (int i=0; i < values.length; i++)
137 {
138 final Object value = a.get(i);
139 if (value instanceof byte[])
140 {
141 values[i] = new ASN1OctetString((byte[]) value);
142 }
143 else
144 {
145 values[i] = new ASN1OctetString(String.valueOf(value));
146 }
147 }
148
149 return new Attribute(name, values);
150 }
151
152
153
154 /**
155 * Converts the provided LDAP SDK attribute to a JNDI attribute.
156 *
157 * @param a The attribute to be converted.
158 *
159 * @return The JNDI attribute that corresponds to the provided LDAP SDK
160 * attribute.
161 */
162 public static javax.naming.directory.Attribute convertAttribute(
163 final Attribute a)
164 {
165 if (a == null)
166 {
167 return null;
168 }
169
170 final BasicAttribute attr = new BasicAttribute(a.getName(), true);
171 for (final String v : a.getValues())
172 {
173 attr.add(v);
174 }
175
176 return attr;
177 }
178
179
180
181 /**
182 * Converts the provided JNDI attributes to an array of LDAP SDK attributes.
183 *
184 * @param a The attributes to be converted.
185 *
186 * @return The array of LDAP SDK attributes that corresponds to the
187 * provided JNDI attributes.
188 *
189 * @throws NamingException If a problem is encountered during the conversion
190 * process.
191 */
192 public static Attribute[] convertAttributes(final Attributes a)
193 throws NamingException
194 {
195 if (a == null)
196 {
197 return NO_ATTRIBUTES;
198 }
199
200 int i=0;
201 final Attribute[] attributes = new Attribute[a.size()];
202 final NamingEnumeration<? extends javax.naming.directory.Attribute> e =
203 a.getAll();
204
205 try
206 {
207 while (e.hasMoreElements())
208 {
209 attributes[i++] = convertAttribute(e.next());
210 }
211 }
212 finally
213 {
214 e.close();
215 }
216
217 return attributes;
218 }
219
220
221
222 /**
223 * Converts the provided array of LDAP SDK attributes to a set of JNDI
224 * attributes.
225 *
226 * @param a The array of attributes to be converted.
227 *
228 * @return The JNDI attributes that corresponds to the provided LDAP SDK
229 * attributes.
230 */
231 public static Attributes convertAttributes(final Attribute... a)
232 {
233 final BasicAttributes attrs = new BasicAttributes(true);
234 if (a == null)
235 {
236 return attrs;
237 }
238
239 for (final Attribute attr : a)
240 {
241 attrs.put(convertAttribute(attr));
242 }
243
244 return attrs;
245 }
246
247
248
249 /**
250 * Converts the provided collection of LDAP SDK attributes to a set of JNDI
251 * attributes.
252 *
253 * @param a The collection of attributes to be converted.
254 *
255 * @return The JNDI attributes that corresponds to the provided LDAP SDK
256 * attributes.
257 */
258 public static Attributes convertAttributes(final Collection<Attribute> a)
259 {
260 final BasicAttributes attrs = new BasicAttributes(true);
261 if (a == null)
262 {
263 return attrs;
264 }
265
266 for (final Attribute attr : a)
267 {
268 attrs.put(convertAttribute(attr));
269 }
270
271 return attrs;
272 }
273
274
275
276 /**
277 * Converts the provided JNDI control to an LDAP SDK control.
278 *
279 * @param c The control to be converted.
280 *
281 * @return The LDAP SDK control that corresponds to the provided JNDI
282 * control.
283 *
284 * @throws NamingException If a problem is encountered during the conversion
285 * process.
286 */
287 public static Control convertControl(final javax.naming.ldap.Control c)
288 throws NamingException
289 {
290 if (c == null)
291 {
292 return null;
293 }
294
295 final ASN1OctetString value;
296 final byte[] valueBytes = c.getEncodedValue();
297 if ((valueBytes == null) || (valueBytes.length == 0))
298 {
299 value = null;
300 }
301 else
302 {
303 try
304 {
305 value = ASN1OctetString.decodeAsOctetString(valueBytes);
306 }
307 catch (ASN1Exception ae)
308 {
309 throw new NamingException(getExceptionMessage(ae));
310 }
311 }
312
313 return new Control(c.getID(), c.isCritical(), value);
314 }
315
316
317
318 /**
319 * Converts the provided LDAP SDK control to a JNDI control.
320 *
321 * @param c The control to be converted.
322 *
323 * @return The JNDI control that corresponds to the provided LDAP SDK
324 * control.
325 */
326 public static javax.naming.ldap.Control convertControl(final Control c)
327 {
328 if (c == null)
329 {
330 return null;
331 }
332
333 final ASN1OctetString value = c.getValue();
334 if (value == null)
335 {
336 return new BasicControl(c.getOID(), c.isCritical(), null);
337 }
338 else
339 {
340 return new BasicControl(c.getOID(), c.isCritical(), value.encode());
341 }
342 }
343
344
345
346 /**
347 * Converts the provided array of JNDI controls to an array of LDAP SDK
348 * controls.
349 *
350 * @param c The array of JNDI controls to be converted.
351 *
352 * @return The array of LDAP SDK controls that corresponds to the provided
353 * array of JNDI controls.
354 *
355 * @throws NamingException If a problem is encountered during the conversion
356 * process.
357 */
358 public static Control[] convertControls(final javax.naming.ldap.Control... c)
359 throws NamingException
360 {
361 if (c == null)
362 {
363 return NO_SDK_CONTROLS;
364 }
365
366 final Control[] controls = new Control[c.length];
367 for (int i=0; i < controls.length; i++)
368 {
369 controls[i] = convertControl(c[i]);
370 }
371
372 return controls;
373 }
374
375
376
377 /**
378 * Converts the provided array of LDAP SDK controls to an array of JNDI
379 * controls.
380 *
381 * @param c The array of LDAP SDK controls to be converted.
382 *
383 * @return The array of JNDI controls that corresponds to the provided array
384 * of LDAP SDK controls.
385 */
386 public static javax.naming.ldap.Control[] convertControls(final Control... c)
387 {
388 if (c == null)
389 {
390 return NO_JNDI_CONTROLS;
391 }
392
393 final javax.naming.ldap.Control[] controls =
394 new javax.naming.ldap.Control[c.length];
395 for (int i=0; i < controls.length; i++)
396 {
397 controls[i] = convertControl(c[i]);
398 }
399
400 return controls;
401 }
402
403
404
405 /**
406 * Converts the provided JNDI extended request to an LDAP SDK extended
407 * request.
408 *
409 * @param r The request to be converted.
410 *
411 * @return The LDAP SDK extended request that corresponds to the provided
412 * JNDI extended request.
413 *
414 * @throws NamingException If a problem is encountered during the conversion
415 * process.
416 */
417 public static ExtendedRequest convertExtendedRequest(
418 final javax.naming.ldap.ExtendedRequest r)
419 throws NamingException
420 {
421 if (r == null)
422 {
423 return null;
424 }
425
426 return JNDIExtendedRequest.toSDKExtendedRequest(r);
427 }
428
429
430
431 /**
432 * Converts the provided LDAP SDK extended request to a JNDI extended request.
433 *
434 * @param r The request to be converted.
435 *
436 * @return The JNDI extended request that corresponds to the provided LDAP
437 * SDK extended request.
438 */
439 public static javax.naming.ldap.ExtendedRequest convertExtendedRequest(
440 final ExtendedRequest r)
441 {
442 if (r == null)
443 {
444 return null;
445 }
446
447 return new JNDIExtendedRequest(r);
448 }
449
450
451
452 /**
453 * Converts the provided JNDI extended response to an LDAP SDK extended
454 * result.
455 *
456 * @param r The response to be converted.
457 *
458 * @return The LDAP SDK extended result that corresponds to the provided
459 * JNDI extended response.
460 *
461 * @throws NamingException If a problem is encountered during the conversion
462 * process.
463 */
464 public static ExtendedResult convertExtendedResponse(final ExtendedResponse r)
465 throws NamingException
466 {
467 if (r == null)
468 {
469 return null;
470 }
471
472 return JNDIExtendedResponse.toSDKExtendedResult(r);
473 }
474
475
476
477 /**
478 * Converts the provided LDAP SDK extended result to a JNDI extended response.
479 *
480 * @param r The result to be converted.
481 *
482 * @return The JNDI extended response that corresponds to the provided LDAP
483 * SDK extended result.
484 */
485 public static ExtendedResponse convertExtendedResult(final ExtendedResult r)
486 {
487 if (r == null)
488 {
489 return null;
490 }
491
492 return new JNDIExtendedResponse(r);
493 }
494
495
496
497 /**
498 * Converts the provided JNDI modification item to an LDAP SDK modification.
499 *
500 * @param m The JNDI modification item to be converted.
501 *
502 * @return The LDAP SDK modification that corresponds to the provided JNDI
503 * modification item.
504 *
505 * @throws NamingException If a problem is encountered during the conversion
506 * process.
507 */
508 public static Modification convertModification(final ModificationItem m)
509 throws NamingException
510 {
511 if (m == null)
512 {
513 return null;
514 }
515
516 final ModificationType modType;
517 switch (m.getModificationOp())
518 {
519 case DirContext.ADD_ATTRIBUTE:
520 modType = ModificationType.ADD;
521 break;
522 case DirContext.REMOVE_ATTRIBUTE:
523 modType = ModificationType.DELETE;
524 break;
525 case DirContext.REPLACE_ATTRIBUTE:
526 modType = ModificationType.REPLACE;
527 break;
528 default:
529 throw new NamingException("Unsupported modification type " + m);
530 }
531
532 final Attribute a = convertAttribute(m.getAttribute());
533
534 return new Modification(modType, a.getName(), a.getRawValues());
535 }
536
537
538
539 /**
540 * Converts the provided LDAP SDK modification to a JNDI modification item.
541 *
542 * @param m The LDAP SDK modification to be converted.
543 *
544 * @return The JNDI modification item that corresponds to the provided LDAP
545 * SDK modification.
546 *
547 * @throws NamingException If a problem is encountered during the conversion
548 * process.
549 */
550 public static ModificationItem convertModification(final Modification m)
551 throws NamingException
552 {
553 if (m == null)
554 {
555 return null;
556 }
557
558 final int modType;
559 switch (m.getModificationType().intValue())
560 {
561 case ModificationType.ADD_INT_VALUE:
562 modType = DirContext.ADD_ATTRIBUTE;
563 break;
564 case ModificationType.DELETE_INT_VALUE:
565 modType = DirContext.REMOVE_ATTRIBUTE;
566 break;
567 case ModificationType.REPLACE_INT_VALUE:
568 modType = DirContext.REPLACE_ATTRIBUTE;
569 break;
570 default:
571 throw new NamingException("Unsupported modification type " + m);
572 }
573
574 return new ModificationItem(modType, convertAttribute(m.getAttribute()));
575 }
576
577
578
579 /**
580 * Converts the provided array of JNDI modification items to an array of LDAP
581 * SDK modifications.
582 *
583 * @param m The array of JNDI modification items to be converted.
584 *
585 * @return The array of LDAP SDK modifications that corresponds to the
586 * provided array of JNDI modification items.
587 *
588 * @throws NamingException If a problem is encountered during the conversion
589 * process.
590 */
591 public static Modification[] convertModifications(final ModificationItem... m)
592 throws NamingException
593 {
594 if (m == null)
595 {
596 return NO_MODIFICATIONS;
597 }
598
599 final Modification[] mods = new Modification[m.length];
600 for (int i=0; i < m.length; i++)
601 {
602 mods[i] = convertModification(m[i]);
603 }
604
605 return mods;
606 }
607
608
609
610 /**
611 * Converts the provided array of LDAP SDK modifications to an array of JNDI
612 * modification items.
613 *
614 * @param m The array of LDAP SDK modifications to be converted.
615 *
616 * @return The array of JNDI modification items that corresponds to the
617 * provided array of LDAP SDK modifications.
618 *
619 * @throws NamingException If a problem is encountered during the conversion
620 * process.
621 */
622 public static ModificationItem[] convertModifications(final Modification... m)
623 throws NamingException
624 {
625 if (m == null)
626 {
627 return NO_MODIFICATION_ITEMS;
628 }
629
630 final ModificationItem[] mods = new ModificationItem[m.length];
631 for (int i=0; i < m.length; i++)
632 {
633 mods[i] = convertModification(m[i]);
634 }
635
636 return mods;
637 }
638
639
640
641 /**
642 * Converts the provided JNDI search result object to an LDAP SDK entry.
643 *
644 * @param r The JNDI search result object to be converted.
645 *
646 * @return The LDAP SDK entry that corresponds to the provided JNDI search
647 * result.
648 *
649 * @throws NamingException If a problem is encountered during the conversion
650 * process.
651 */
652 public static Entry convertSearchEntry(final SearchResult r)
653 throws NamingException
654 {
655 if (r == null)
656 {
657 return null;
658 }
659
660 return new Entry(r.getName(), convertAttributes(r.getAttributes()));
661 }
662
663
664
665 /**
666 * Converts the provided LDAP SDK entry to a JNDI search result.
667 *
668 * @param e The entry to be converted to a JNDI search result.
669 *
670 * @return The JNDI search result that corresponds to the provided LDAP SDK
671 * entry.
672 */
673 public static SearchResult convertSearchEntry(final Entry e)
674 {
675 if (e == null)
676 {
677 return null;
678 }
679
680 final Collection<Attribute> attrs = e.getAttributes();
681 final Attribute[] attributes = new Attribute[attrs.size()];
682 attrs.toArray(attributes);
683
684 return new SearchResult(e.getDN(), null, convertAttributes(attributes));
685 }
686 }