001: /*
002: * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.jndi.ldap;
027:
028: import java.util.Vector;
029: import javax.naming.*;
030: import javax.naming.directory.*;
031: import javax.naming.spi.*;
032: import javax.naming.ldap.*;
033: import javax.naming.ldap.LdapName;
034:
035: import com.sun.jndi.toolkit.ctx.Continuation;
036:
037: final class LdapSearchEnumeration extends LdapNamingEnumeration {
038:
039: private Name startName; // prefix of names of search results
040: private LdapCtx.SearchArgs searchArgs = null;
041:
042: LdapSearchEnumeration(LdapCtx homeCtx, LdapResult search_results,
043: String starter, LdapCtx.SearchArgs args, Continuation cont)
044: throws NamingException {
045:
046: super (homeCtx, search_results, args.name, /* listArg */
047: cont);
048:
049: // fully qualified name of starting context of search
050: startName = new LdapName(starter);
051: searchArgs = args;
052: }
053:
054: protected NameClassPair createItem(String dn, Attributes attrs,
055: Vector respCtls) throws NamingException {
056:
057: Object obj = null;
058:
059: String relStart; // name relative to starting search context
060: String relHome; // name relative to homeCtx.currentDN
061: boolean relative = true; // whether relative to currentDN
062:
063: // need to strip off all but lowest component of dn
064: // so that is relative to current context (currentDN)
065:
066: try {
067: Name parsed = new LdapName(dn);
068: // System.err.println("dn string: " + dn);
069: // System.err.println("dn name: " + parsed);
070:
071: if (startName != null && parsed.startsWith(startName)) {
072: relStart = parsed.getSuffix(startName.size())
073: .toString();
074: relHome = parsed.getSuffix(
075: homeCtx.currentParsedDN.size()).toString();
076: } else {
077: relative = false;
078: relHome = relStart = LdapURL.toUrlString(
079: homeCtx.hostname, homeCtx.port_number, dn,
080: homeCtx.hasLdapsScheme);
081: }
082: } catch (NamingException e) {
083: // could not parse name
084: relative = false;
085: relHome = relStart = LdapURL.toUrlString(homeCtx.hostname,
086: homeCtx.port_number, dn, homeCtx.hasLdapsScheme);
087: }
088:
089: // Name relative to search context
090: CompositeName cn = new CompositeName();
091: if (!relStart.equals("")) {
092: cn.add(relStart);
093: }
094:
095: // Name relative to homeCtx
096: CompositeName rcn = new CompositeName();
097: if (!relHome.equals("")) {
098: rcn.add(relHome);
099: }
100: //System.err.println("relStart: " + cn);
101: //System.err.println("relHome: " + rcn);
102:
103: // Fix attributes to be able to get schema
104: homeCtx.setParents(attrs, rcn);
105:
106: // only generate object when requested
107: if (searchArgs.cons.getReturningObjFlag()) {
108:
109: if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) {
110: // Entry contains Java-object attributes (ser/ref object)
111: // serialized object or object reference
112: obj = Obj.decodeObject(attrs);
113:
114: }
115: if (obj == null) {
116: obj = new LdapCtx(homeCtx, dn);
117: }
118:
119: // Call getObjectInstance before removing unrequested attributes
120: try {
121: // rcn is either relative to homeCtx or a fully qualified DN
122: obj = DirectoryManager.getObjectInstance(obj, rcn,
123: (relative ? homeCtx : null), homeCtx.envprops,
124: attrs);
125: } catch (NamingException e) {
126: throw e;
127: } catch (Exception e) {
128: NamingException ne = new NamingException(
129: "problem generating object using object factory");
130: ne.setRootCause(e);
131: throw ne;
132: }
133:
134: // remove Java attributes from result, if necessary
135: // Even if CLASSNAME attr not there, there might be some
136: // residual attributes
137:
138: String[] reqAttrs;
139: if ((reqAttrs = searchArgs.reqAttrs) != null) {
140: // create an attribute set for those requested
141: Attributes rattrs = new BasicAttributes(true); // caseignore
142: for (int i = 0; i < reqAttrs.length; i++) {
143: rattrs.put(reqAttrs[i], null);
144: }
145: for (int i = 0; i < Obj.JAVA_ATTRIBUTES.length; i++) {
146: // Remove Java-object attributes if not requested
147: if (rattrs.get(Obj.JAVA_ATTRIBUTES[i]) == null) {
148: attrs.remove(Obj.JAVA_ATTRIBUTES[i]);
149: }
150: }
151: }
152:
153: }
154:
155: /*
156: * name in search result is either the stringified composite name
157: * relative to the search context that can be passed directly to
158: * methods of the search context, or the fully qualified DN
159: * which can be used with the initial context.
160: */
161: SearchResult sr;
162: if (respCtls != null) {
163: sr = new SearchResultWithControls((relative ? cn.toString()
164: : relStart), obj, attrs, relative, homeCtx
165: .convertControls(respCtls));
166: } else {
167: sr = new SearchResult(
168: (relative ? cn.toString() : relStart), obj, attrs,
169: relative);
170: }
171: sr.setNameInNamespace(dn);
172: return sr;
173: }
174:
175: public void appendUnprocessedReferrals(LdapReferralException ex) {
176:
177: // a referral has been followed so do not create relative names
178: startName = null;
179: super .appendUnprocessedReferrals(ex);
180: }
181:
182: protected LdapNamingEnumeration getReferredResults(
183: LdapReferralContext refCtx) throws NamingException {
184: // repeat the original operation at the new context
185: return (LdapSearchEnumeration) refCtx.search(searchArgs.name,
186: searchArgs.filter, searchArgs.cons);
187: }
188:
189: protected void update(LdapNamingEnumeration ne) {
190: super .update(ne);
191:
192: // Update search-specific variables
193: LdapSearchEnumeration se = (LdapSearchEnumeration) ne;
194: startName = se.startName;
195: //VR - keep original args, don't overwite with current args
196: // searchArgs = se.searchArgs;
197: }
198:
199: void setStartName(Name nm) {
200: startName = nm;
201: }
202: }
|