1 /* 2 * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.jndi.ldap; 27 28 import java.util.Vector; 29 import javax.naming.*; 30 import javax.naming.directory.*; 31 import javax.naming.spi.*; 32 import javax.naming.ldap.*; 33 import javax.naming.ldap.LdapName; 34 35 import com.sun.jndi.toolkit.ctx.Continuation; 36 37 final class LdapSearchEnumeration extends LdapNamingEnumeration { 38 39 private Name startName; // prefix of names of search results 40 private LdapCtx.SearchArgs searchArgs = null; 41 42 LdapSearchEnumeration(LdapCtx homeCtx, LdapResult search_results, 43 String starter, LdapCtx.SearchArgs args, Continuation cont) 44 throws NamingException { 45 46 super(homeCtx, search_results, 47 args.name, /* listArg */ 48 cont); 49 50 // fully qualified name of starting context of search 51 startName = new LdapName(starter); 52 searchArgs = args; 53 } 54 55 protected NameClassPair 56 createItem(String dn, Attributes attrs, Vector respCtls) 57 throws NamingException { 58 59 Object obj = null; 60 61 String relStart; // name relative to starting search context 62 String relHome; // name relative to homeCtx.currentDN 63 boolean relative = true; // whether relative to currentDN 64 65 // need to strip off all but lowest component of dn 66 // so that is relative to current context (currentDN) 67 68 try { 69 Name parsed = new LdapName(dn); 70 // System.err.println("dn string: " + dn); 71 // System.err.println("dn name: " + parsed); 72 73 if (startName != null && parsed.startsWith(startName)) { 74 relStart = parsed.getSuffix(startName.size()).toString(); 75 relHome = parsed.getSuffix(homeCtx.currentParsedDN.size()).toString(); 76 } else { 77 relative = false; 78 relHome = relStart = 79 LdapURL.toUrlString(homeCtx.hostname, homeCtx.port_number, 80 dn, homeCtx.hasLdapsScheme); 81 } 82 } catch (NamingException e) { 83 // could not parse name 84 relative = false; 85 relHome = relStart = 86 LdapURL.toUrlString(homeCtx.hostname, homeCtx.port_number, 87 dn, homeCtx.hasLdapsScheme); 88 } 89 90 // Name relative to search context 91 CompositeName cn = new CompositeName(); 92 if (!relStart.equals("")) { 93 cn.add(relStart); 94 } 95 96 // Name relative to homeCtx 97 CompositeName rcn = new CompositeName(); 98 if (!relHome.equals("")) { 99 rcn.add(relHome); 100 } 101 //System.err.println("relStart: " + cn); 102 //System.err.println("relHome: " + rcn); 103 104 // Fix attributes to be able to get schema 105 homeCtx.setParents(attrs, rcn); 106 107 // only generate object when requested 108 if (searchArgs.cons.getReturningObjFlag()) { 109 110 if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) { 111 // Entry contains Java-object attributes (ser/ref object) 112 // serialized object or object reference 113 obj = Obj.decodeObject(attrs); 114 115 } 116 if (obj == null) { 117 obj = new LdapCtx(homeCtx, dn); 118 } 119 120 // Call getObjectInstance before removing unrequested attributes 121 try { 122 // rcn is either relative to homeCtx or a fully qualified DN 123 obj = DirectoryManager.getObjectInstance( 124 obj, rcn, (relative ? homeCtx : null), 125 homeCtx.envprops, attrs); 126 } catch (NamingException e) { 127 throw e; 128 } catch (Exception e) { 129 NamingException ne = 130 new NamingException( 131 "problem generating object using object factory"); 132 ne.setRootCause(e); 133 throw ne; 134 } 135 136 // remove Java attributes from result, if necessary 137 // Even if CLASSNAME attr not there, there might be some 138 // residual attributes 139 140 String[] reqAttrs; 141 if ((reqAttrs = searchArgs.reqAttrs) != null) { 142 // create an attribute set for those requested 143 Attributes rattrs = new BasicAttributes(true); // caseignore 144 for (int i = 0; i < reqAttrs.length; i++) { 145 rattrs.put(reqAttrs[i], null); 146 } 147 for (int i = 0; i < Obj.JAVA_ATTRIBUTES.length; i++) { 148 // Remove Java-object attributes if not requested 149 if (rattrs.get(Obj.JAVA_ATTRIBUTES[i]) == null) { 150 attrs.remove(Obj.JAVA_ATTRIBUTES[i]); 151 } 152 } 153 } 154 155 } 156 157 /* 158 * name in search result is either the stringified composite name 159 * relative to the search context that can be passed directly to 160 * methods of the search context, or the fully qualified DN 161 * which can be used with the initial context. 162 */ 163 SearchResult sr; 164 if (respCtls != null) { 165 sr = new SearchResultWithControls( 166 (relative ? cn.toString() : relStart), obj, attrs, 167 relative, homeCtx.convertControls(respCtls)); 168 } else { 169 sr = new SearchResult( 170 (relative ? cn.toString() : relStart), 171 obj, attrs, relative); 172 } 173 sr.setNameInNamespace(dn); 174 return sr; 175 } 176 177 public void appendUnprocessedReferrals(LdapReferralException ex) { 178 179 // a referral has been followed so do not create relative names 180 startName = null; 181 super.appendUnprocessedReferrals(ex); 182 } 183 184 protected LdapNamingEnumeration 185 getReferredResults(LdapReferralContext refCtx) throws NamingException { 186 // repeat the original operation at the new context 187 return (LdapSearchEnumeration) 188 refCtx.search(searchArgs.name, searchArgs.filter, searchArgs.cons); 189 } 190 191 protected void update(LdapNamingEnumeration ne) { 192 super.update(ne); 193 194 // Update search-specific variables 195 LdapSearchEnumeration se = (LdapSearchEnumeration)ne; 196 startName = se.startName; 197 //VR - keep original args, don't overwite with current args 198 // searchArgs = se.searchArgs; 199 } 200 201 void setStartName(Name nm) { 202 startName = nm; 203 } 204 }