001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package javax.naming.spi;
019:
020: import java.net.URL;
021: import java.net.URLClassLoader;
022: import java.security.AccessController;
023: import java.security.PrivilegedAction;
024: import java.util.Enumeration;
025: import java.util.Hashtable;
026: import java.util.StringTokenizer;
027:
028: import javax.naming.Binding;
029: import javax.naming.CannotProceedException;
030: import javax.naming.Context;
031: import javax.naming.Name;
032: import javax.naming.NameClassPair;
033: import javax.naming.NameParser;
034: import javax.naming.NamingEnumeration;
035: import javax.naming.NamingException;
036: import javax.naming.RefAddr;
037: import javax.naming.Reference;
038: import javax.naming.Referenceable;
039: import javax.naming.StringRefAddr;
040: import javax.naming.directory.Attributes;
041: import javax.naming.directory.DirContext;
042: import javax.naming.directory.ModificationItem;
043: import javax.naming.directory.SearchControls;
044: import javax.naming.directory.SearchResult;
045: import javax.naming.spi.DirStateFactory.Result;
046:
047: import org.apache.harmony.jndi.internal.EnvironmentReader;
048: import org.apache.harmony.jndi.internal.UrlParser;
049: import org.apache.harmony.jndi.internal.nls.Messages;
050:
051: /**
052: * The <code>DirectoryManager</code> class cannot be instantiated. All its
053: * methods are static. The methods are used by service providers for accessing
054: * object and state factories and for determining continuation contexts.
055: * <p>
056: * The <code>Name</code> and <code>Hashtable</code> arguments passed to the
057: * <code>DirectoryManager</code> methods remain owned purely by the calling
058: * method. They must not be changed or referenced.
059: * </p>
060: * <p>
061: * Multithreaded access to this class must be safe.
062: * </p>
063: */
064: public class DirectoryManager extends NamingManager {
065:
066: // Private to prevent it being instanced
067: private DirectoryManager() {
068: }
069:
070: /**
071: * Create an object using an object factory. Returns a new
072: * <code>Object</code> or the supplied <code>Object o</code> if one
073: * cannot be created.
074: *
075: * The behaviour is like that for the <code>getObjectInstance</code>
076: * method of <code>NamingManager</code> however it should be noted that
077: * the intermediate object factory may be either of type
078: * <code>DirObjectFactory</code> or of type <code>ObjectFactory</code>;
079: * in the former case, the supplied <code>Attributes</code> must be passed
080: * when getting the object, otherwise the supplied <code>Attributes</code>
081: * are ignored.
082: *
083: * @param o
084: * An object which may provide reference or location information.
085: * May be null.
086: * @param n
087: * The name of the <code>Object</code> relative to the default
088: * initial context (or relative to the Context c if it is
089: * supplied)
090: * @param c
091: * The <code>Context</code> to which the Name is relative
092: * @param h
093: * a <code>Hashtable</code> containing environment properties
094: * and values - may be null
095: * @param a
096: * <code>Attributes</code> - if some or all of the attributes
097: * of <code>Object o</code> are already known they can be
098: * supplied so that the factory does not have to do the work of
099: * looking them up.
100: * @return the created object
101: * @throws NamingException
102: * if one is encountered
103: * @throws Exception
104: * if any other exception is encountered
105: */
106: public static Object getObjectInstance(Object o, Name n, Context c,
107: Hashtable<?, ?> h, Attributes a) throws Exception {
108:
109: // 1. try ObjectFactoryBuilder, if it is set
110: if (null != ofb) {
111: // use the builder to create an object factory
112: ObjectFactory factory = ofb.createObjectFactory(o, h);
113: // get object instance using the factory and return
114: return getObjectInstanceFromGivenFactory(factory, o, n, c,
115: h, a);
116: }
117:
118: // 2. see whether o is a Referenceable or a Reference
119: Reference ref = null;
120: if (o instanceof Referenceable) {
121: ref = ((Referenceable) o).getReference();
122: }
123: if (o instanceof Reference) {
124: ref = (Reference) o;
125: }
126: // if o is a Referenceable or a Reference
127: if (null != ref) {
128: // if a factory class name is supplied by the reference, use it to
129: // create
130: if (null != ref.getFactoryClassName()) {
131: return getObjectInstanceByFactoryInReference(ref, o, n,
132: c, h, a);
133: }
134: // see if ref has any StringRefAddrs of address type URL,
135: Object result = getObjectInstanceByUrlRefAddr(n, c, h, ref);
136: // if success, return it
137: if (null != result) {
138: return result;
139: }
140: }
141:
142: // 3. try Context.OBJECT_FACTORIES
143: Object result = getObjectInstanceByObjectFactory(o, n, c, h, a);
144: if (null != result) {
145: return result;
146: }
147:
148: // all failed, just return o
149: return o;
150: }
151:
152: /**
153: * Check the type of factory, DirObjectFactory or ObjectFactory, and call
154: * getObjectInstance() on the property type.
155: */
156: private static Object getObjectInstanceFromGivenFactory(
157: ObjectFactory factory, Object o, Name n, Context c,
158: Hashtable<?, ?> h, Attributes a) throws Exception {
159: if (factory instanceof DirObjectFactory) {
160: return ((DirObjectFactory) factory).getObjectInstance(o, n,
161: c, h, a);
162: }
163: return factory.getObjectInstance(o, n, c, h);
164: }
165:
166: private static Object getObjectInstanceByObjectFactory(Object o,
167: Name n, Context c, Hashtable<?, ?> h, Attributes a)
168: throws NamingException, Exception {
169: // obtain object factories from hashtable and service provider resource
170: // file
171: String fnames[] = EnvironmentReader
172: .getFactoryNamesFromEnvironmentAndProviderResource(h,
173: c, Context.OBJECT_FACTORIES);
174: for (String element : fnames) {
175: // new factory instance by its class name
176: ObjectFactory factory = null;
177: try {
178: factory = (ObjectFactory) classForName(element)
179: .newInstance();
180: } catch (Exception e) {
181: continue;
182: }
183: // create object using factory
184: Object obj = getObjectInstanceFromGivenFactory(factory, o,
185: n, c, h, a);
186: if (null != obj) {
187: return obj;
188: }
189: }
190: // no object factory succeeded, return null
191: return null;
192: }
193:
194: private static Object getObjectInstanceByUrlRefAddr(Name n,
195: Context c, Hashtable<?, ?> h, Reference ref)
196: throws NamingException {
197: // obtain pkg prefixes from hashtable and service provider resource file
198: String pkgPrefixes[] = EnvironmentReader
199: .getFactoryNamesFromEnvironmentAndProviderResource(h,
200: c, Context.URL_PKG_PREFIXES);
201: // for each RefAddr
202: Enumeration<RefAddr> enumeration = ref.getAll();
203: while (enumeration.hasMoreElements()) {
204: RefAddr addr = enumeration.nextElement();
205: // if it is StringRefAddr and type is URL
206: if (addr instanceof StringRefAddr
207: && addr.getType().equalsIgnoreCase("URL")) { //$NON-NLS-1$
208: // get the url address
209: String url = (String) ((StringRefAddr) addr)
210: .getContent();
211: // try create using url context factory
212: Object obj = getObjectInstanceByUrlContextFactory(url,
213: n, c, h, pkgPrefixes, UrlParser.getScheme(url));
214: // if success, return the created obj
215: if (null != obj) {
216: return obj;
217: }
218: }
219: }
220: // failed to create using any StringRefAddr of address type URL, return
221: // null
222: return null;
223: }
224:
225: private static Object getObjectInstanceByUrlContextFactory(
226: String url, Name n, Context c, Hashtable<?, ?> h,
227: String pkgPrefixes[], String schema) throws NamingException {
228: // if schema is empty or null, fail, return null
229: if (null == schema || 0 == schema.length()) {
230: return null;
231: }
232:
233: for (String element : pkgPrefixes) {
234: ObjectFactory factory = null;
235: try {
236: // create url context factory instance
237: String clsName = element
238: + "." + schema + "." + schema + "URLContextFactory"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
239: factory = (ObjectFactory) classForName(clsName)
240: .newInstance();
241: } catch (Exception e) {
242: // failed to create factory, continue trying
243: continue;
244: }
245: try {
246: // create obj using url context factory
247: /*
248: * Unit test shows it is ObjectFactory here, not
249: * DirObjectFactory // Object obj =
250: * factory.getObjectInstance(url, n, c, h, a);
251: */
252: Object obj = factory.getObjectInstance(url, n, c, h);
253: // if create success, return it
254: if (null != obj) {
255: return obj;
256: }
257: } catch (Exception e) {
258: // throw NamingException, if factory fails
259: if (e instanceof NamingException) {
260: throw (NamingException) e;
261: }
262: // jndi.21=Failed to create object instance
263: NamingException nex = new NamingException(Messages
264: .getString("jndi.21")); //$NON-NLS-1$
265: nex.setRootCause(e);
266: throw nex;
267: }
268: }
269: // fail to create using url context factory, return null
270: return null;
271: }
272:
273: private static Object getObjectInstanceByFactoryInReference(
274: Reference ref, Object o, Name n, Context c,
275: Hashtable<?, ?> h, Attributes a) throws Exception {
276: ObjectFactory factory = null;
277:
278: // try load the factory by its class name
279: try {
280: factory = (ObjectFactory) classForName(
281: ref.getFactoryClassName()).newInstance();
282: } catch (ClassNotFoundException e) {
283: // Ignored.
284: }
285:
286: // try load the factory from its class location
287: if (null == factory && null != ref.getFactoryClassLocation()) {
288: factory = (ObjectFactory) loadFactoryFromLocation(ref
289: .getFactoryClassName(), ref
290: .getFactoryClassLocation());
291: }
292: // if factory cannot be loaded
293: if (null == factory) {
294: // return o
295: return o;
296: }
297:
298: // get object instance using the factory and return it
299: return getObjectInstanceFromGivenFactory(factory, ref, n, c, h,
300: a);
301: }
302:
303: /*
304: * If cannot load class, return null. Throws any exceptions except
305: * ClassNotFoundException
306: */
307: private static Object loadFactoryFromLocation(String clsName,
308: String location) throws Exception {
309:
310: // convert location into an array of URL, separated by ' '
311: StringTokenizer st = new StringTokenizer(location, " "); //$NON-NLS-1$
312: URL urls[] = new URL[st.countTokens()];
313: for (int i = 0; i < urls.length; i++) {
314: urls[i] = new URL(st.nextToken());
315: }
316:
317: // new a URLClassLoader from the URLs
318: URLClassLoader l = new URLClassLoader(urls);
319:
320: // try load factory by URLClassLoader
321: try {
322: // return the new instance
323: return l.loadClass(clsName).newInstance();
324: } catch (ClassNotFoundException e) {
325: // return null if class loading failed
326: return null;
327: }
328: }
329:
330: /**
331: * Get the state of an Object. Returns a <code>DirStateFactory</code>.
332: * Result which cannot be null. It contains the attributes and object to be
333: * bound, either of which may be null. Once returned the caller is the owner
334: * of it. The behaviour is like that for the <code>getStateToBind</code>
335: * method of <code>NamingManager</code> however it should be noted that
336: * the intermediate state factory may be of type
337: * <code>DirStateFactory</code> rather than just <code>StateFactory</code>
338: * in which case it should also use the supplied <code>Attributes</code>
339: * when getting the state.
340: *
341: * @param o
342: * An object which may provide reference or location information.
343: * May be null.
344: * @param n
345: * The name of the <code>Object</code> relative to the default
346: * initial context (or relative to the Context c if it is
347: * supplied)
348: * @param c
349: * The <code>Context</code> to which the <code>Name</code> is
350: * relative
351: * @param h
352: * a <code>Hashtable</code> containing environment properties
353: * and values - may be null
354: * @param a
355: * <code>Attributes</code> - if some or all of the attributes
356: * of <code>Object o</code> are already known they can be
357: * supplied so that the factory does not have to do the work of
358: * looking them up.
359: * @return the state of the object
360: * @throws NamingException
361: * if one is encountered
362: */
363: public static DirStateFactory.Result getStateToBind(Object o,
364: Name n, Context c, Hashtable<?, ?> h, Attributes a)
365: throws NamingException {
366:
367: // obtain state factories from hashtable and service provider resource
368: // file
369: String fnames[] = EnvironmentReader
370: .getFactoryNamesFromEnvironmentAndProviderResource(h,
371: c, Context.STATE_FACTORIES);
372:
373: for (String element : fnames) {
374: // new factory instance by its class name
375: StateFactory factory = null;
376: try {
377: factory = (StateFactory) classForName(element)
378: .newInstance();
379: } catch (Exception e) {
380: continue;
381: }
382: if (factory instanceof DirStateFactory) {
383: // try obtain state using the DirStateFactory
384: Result r = ((DirStateFactory) factory).getStateToBind(
385: o, n, c, h, a);
386: // if the result is not null, return it
387: if (null != r) {
388: return r;
389: }
390: } else {
391: // try obtain state using the StateFactory
392: Object state = factory.getStateToBind(o, n, c, h);
393: // if a state obtained successfully, return it
394: if (null != state) {
395: return new Result(state, a);
396: }
397: }
398: }
399:
400: // all factories failed, return the input argument o
401: return new Result(o, a);
402: }
403:
404: /**
405: * Create the next <code>DirContext</code> when using federation so that
406: * the <code>DirContext</code> operation can be reinvoked. This should
407: * work similarly to <code>NamingManager.getContinuationContext</code>
408: * except that a reference to a <code>DirContext</code> is returned.
409: * <p>
410: * This method is also responsible for setting the property denoted by the
411: * <code>CPE</code> string to be the supplied
412: * <code>CannotProceedException</code> for that environment.
413: * </p>
414: *
415: * @param cpe
416: * the <code>CannotProceedException</code> generated by the
417: * <code>DirContext</code> of the previous naming system when
418: * it can proceed no further.
419: * @return the next <code>DirContext</code> when using federation
420: * @throws NamingException
421: * if the resolved object is not set or if a
422: * <code>DirContext</code> cannot be obtained from it either
423: * directly or indirectly.
424: */
425: public static DirContext getContinuationDirContext(
426: CannotProceedException cpe) throws NamingException {
427: // obtain next context using NamingManager
428: Context nextContext = null;
429: try {
430: nextContext = NamingManager.getContinuationContext(cpe);
431: } catch (CannotProceedException e) {
432: // tolerate CannotProceedException here
433: }
434:
435: // if it is a DirContext
436: if (nextContext instanceof DirContext) {
437: // return as DirContext
438: return (DirContext) nextContext;
439: }
440: // in case it's Context but not DirContext, wrap it as DirContext
441: // and return
442: return new Context2DirContextWrapper(nextContext, cpe);
443: }
444:
445: private static Class<?> classForName(final String className)
446: throws ClassNotFoundException {
447:
448: Class<?> cls = AccessController
449: .doPrivileged(new PrivilegedAction<Class<?>>() {
450: public Class<?> run() {
451: // try thread context class loader first
452: try {
453: return Class.forName(className, true,
454: Thread.currentThread()
455: .getContextClassLoader());
456: } catch (ClassNotFoundException e) {
457: // Could happen.
458: }
459: // try system class loader second
460: try {
461: return Class.forName(className, true,
462: ClassLoader.getSystemClassLoader());
463: } catch (ClassNotFoundException e1) {
464: // Not found here either.
465: }
466: // return null, if fail to load class
467: return null;
468: }
469: });
470:
471: if (cls == null) {
472: // jndi.1C=class {0} not found
473: throw new ClassNotFoundException(Messages.getString(
474: "jndi.1C", className)); //$NON-NLS-1$
475: }
476:
477: return cls;
478:
479: }
480:
481: /**
482: * An inner class that transforms a Context instance into DirContext.
483: */
484: private static class Context2DirContextWrapper implements
485: DirContext {
486: private Context ctx;
487:
488: private CannotProceedException cpe;
489:
490: public Context2DirContextWrapper(Context ctx,
491: CannotProceedException cpe) {
492: this .ctx = ctx;
493: this .cpe = cpe;
494: }
495:
496: private Context getContext() throws CannotProceedException {
497: if (ctx != null) {
498: return ctx;
499: }
500: cpe.fillInStackTrace();
501: throw cpe;
502: }
503:
504: private DirContext getDirContext()
505: throws CannotProceedException {
506: if (ctx instanceof DirContext) {
507: return (DirContext) ctx;
508: }
509: cpe.fillInStackTrace();
510: throw cpe;
511: }
512:
513: public NamingEnumeration<Binding> listBindings(String s)
514: throws NamingException {
515: return getContext().listBindings(s);
516: }
517:
518: public Object removeFromEnvironment(String s)
519: throws NamingException {
520: return getContext().removeFromEnvironment(s);
521: }
522:
523: public Object lookupLink(String s) throws NamingException {
524: return getContext().lookupLink(s);
525: }
526:
527: public NamingEnumeration<NameClassPair> list(Name n)
528: throws NamingException {
529: return getContext().list(n);
530: }
531:
532: public Object lookup(String s) throws NamingException {
533: return getContext().lookup(s);
534: }
535:
536: public Object addToEnvironment(String s, Object o)
537: throws NamingException {
538: return getContext().addToEnvironment(s, o);
539: }
540:
541: @Override
542: public String toString() {
543: try {
544: return getContext().toString();
545: } catch (CannotProceedException e) {
546: return super .toString();
547: }
548: }
549:
550: public Context createSubcontext(String s)
551: throws NamingException {
552: return getContext().createSubcontext(s);
553: }
554:
555: public void rename(Name nOld, Name nNew) throws NamingException {
556: getContext().rename(nOld, nNew);
557: }
558:
559: @Override
560: public int hashCode() {
561: try {
562: return getContext().hashCode();
563: } catch (CannotProceedException e) {
564: return super .hashCode();
565: }
566: }
567:
568: public void rebind(Name n, Object o) throws NamingException {
569: getContext().rebind(n, o);
570: }
571:
572: public void rename(String sOld, String sNew)
573: throws NamingException {
574: getContext().rename(sOld, sNew);
575: }
576:
577: public Context createSubcontext(Name n) throws NamingException {
578: return getContext().createSubcontext(n);
579: }
580:
581: public NameParser getNameParser(String s)
582: throws NamingException {
583: return getContext().getNameParser(s);
584: }
585:
586: public void rebind(String s, Object o) throws NamingException {
587: getContext().rebind(s, o);
588: }
589:
590: public NamingEnumeration<Binding> listBindings(Name n)
591: throws NamingException {
592: return getContext().listBindings(n);
593: }
594:
595: public NameParser getNameParser(Name n) throws NamingException {
596: return getContext().getNameParser(n);
597: }
598:
599: public NamingEnumeration<NameClassPair> list(String s)
600: throws NamingException {
601: return getContext().list(s);
602: }
603:
604: public String getNameInNamespace() throws NamingException {
605: return getContext().getNameInNamespace();
606: }
607:
608: public void unbind(Name n) throws NamingException {
609: getContext().unbind(n);
610: }
611:
612: public Name composeName(Name n, Name pfx)
613: throws NamingException {
614: return getContext().composeName(n, pfx);
615: }
616:
617: public void bind(Name n, Object o) throws NamingException {
618: getContext().bind(n, o);
619: }
620:
621: public void unbind(String s) throws NamingException {
622: getContext().unbind(s);
623: }
624:
625: public void close() throws NamingException {
626: getContext().close();
627: }
628:
629: public Object lookupLink(Name n) throws NamingException {
630: return getContext().lookupLink(n);
631: }
632:
633: public void destroySubcontext(Name n) throws NamingException {
634: getContext().destroySubcontext(n);
635: }
636:
637: public String composeName(String s, String pfx)
638: throws NamingException {
639: return getContext().composeName(s, pfx);
640: }
641:
642: public void bind(String s, Object o) throws NamingException {
643: getContext().bind(s, o);
644: }
645:
646: public Object lookup(Name n) throws NamingException {
647: return getContext().lookup(n);
648: }
649:
650: @Override
651: public boolean equals(Object arg0) {
652: try {
653: return getContext().equals(arg0);
654: } catch (CannotProceedException e) {
655: return super .equals(arg0);
656: }
657: }
658:
659: public void destroySubcontext(String s) throws NamingException {
660: getContext().destroySubcontext(s);
661: }
662:
663: public Hashtable<?, ?> getEnvironment() throws NamingException {
664: return getContext().getEnvironment();
665: }
666:
667: public void bind(Name name, Object obj, Attributes attributes)
668: throws NamingException {
669: getDirContext().bind(name, obj, attributes);
670: }
671:
672: public void bind(String s, Object obj, Attributes attributes)
673: throws NamingException {
674: getDirContext().bind(s, obj, attributes);
675: }
676:
677: public DirContext createSubcontext(Name name,
678: Attributes attributes) throws NamingException {
679: return getDirContext().createSubcontext(name, attributes);
680: }
681:
682: public DirContext createSubcontext(String s,
683: Attributes attributes) throws NamingException {
684: return getDirContext().createSubcontext(s, attributes);
685: }
686:
687: public Attributes getAttributes(Name name)
688: throws NamingException {
689: return getDirContext().getAttributes(name);
690: }
691:
692: public Attributes getAttributes(Name name, String[] as)
693: throws NamingException {
694: return getDirContext().getAttributes(name, as);
695: }
696:
697: public Attributes getAttributes(String s)
698: throws NamingException {
699: return getDirContext().getAttributes(s);
700: }
701:
702: public Attributes getAttributes(String s, String[] as)
703: throws NamingException {
704: return getDirContext().getAttributes(s, as);
705: }
706:
707: public DirContext getSchema(Name name) throws NamingException {
708: return getDirContext().getSchema(name);
709: }
710:
711: public DirContext getSchema(String s) throws NamingException {
712: return getDirContext().getSchema(s);
713: }
714:
715: public DirContext getSchemaClassDefinition(Name name)
716: throws NamingException {
717: return getDirContext().getSchemaClassDefinition(name);
718: }
719:
720: public DirContext getSchemaClassDefinition(String s)
721: throws NamingException {
722: return getDirContext().getSchemaClassDefinition(s);
723: }
724:
725: public void modifyAttributes(Name name, int i,
726: Attributes attributes) throws NamingException {
727: getDirContext().modifyAttributes(name, i, attributes);
728: }
729:
730: public void modifyAttributes(Name name,
731: ModificationItem[] modificationItems)
732: throws NamingException {
733: getDirContext().modifyAttributes(name, modificationItems);
734: }
735:
736: public void modifyAttributes(String s, int i,
737: Attributes attributes) throws NamingException {
738: getDirContext().modifyAttributes(s, i, attributes);
739: }
740:
741: public void modifyAttributes(String s,
742: ModificationItem[] modificationItems)
743: throws NamingException {
744: getDirContext().modifyAttributes(s, modificationItems);
745: }
746:
747: public void rebind(Name name, Object obj, Attributes attributes)
748: throws NamingException {
749: getDirContext().rebind(name, obj, attributes);
750: }
751:
752: public void rebind(String s, Object obj, Attributes attributes)
753: throws NamingException {
754: getDirContext().rebind(s, obj, attributes);
755: }
756:
757: public NamingEnumeration<SearchResult> search(Name name,
758: Attributes attributes) throws NamingException {
759: return getDirContext().search(name, attributes);
760: }
761:
762: public NamingEnumeration<SearchResult> search(Name name,
763: Attributes attributes, String[] as)
764: throws NamingException {
765: return getDirContext().search(name, attributes, as);
766: }
767:
768: public NamingEnumeration<SearchResult> search(Name name,
769: String filter, Object[] objs,
770: SearchControls searchControls) throws NamingException {
771: return getDirContext().search(name, filter, objs,
772: searchControls);
773: }
774:
775: public NamingEnumeration<SearchResult> search(Name name,
776: String filter, SearchControls searchControls)
777: throws NamingException {
778: return getDirContext().search(name, filter, searchControls);
779: }
780:
781: public NamingEnumeration<SearchResult> search(String name,
782: Attributes attributes) throws NamingException {
783: return getDirContext().search(name, attributes);
784: }
785:
786: public NamingEnumeration<SearchResult> search(String name,
787: Attributes attributes, String[] as)
788: throws NamingException {
789: return getDirContext().search(name, attributes, as);
790: }
791:
792: public NamingEnumeration<SearchResult> search(String name,
793: String filter, Object[] objs,
794: SearchControls searchControls) throws NamingException {
795: return getDirContext().search(name, filter, objs,
796: searchControls);
797: }
798:
799: public NamingEnumeration<SearchResult> search(String name,
800: String filter, SearchControls searchControls)
801: throws NamingException {
802: return getDirContext().search(name, filter, searchControls);
803: }
804: }
805:
806: }
|