1 /* 2 * Copyright (c) 1999, 2011, 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 /** 27 * Given an enumeration of candidates, check whether each 28 * item in enumeration satifies the given filter. 29 * Each item is a Binding and the following is used to get its 30 * attributes for used by the filter: 31 * 32 * ((DirContext)item.getObject()).getAttributes(""). 33 * If item.getObject() is not an DirContext, the item is skipped 34 * 35 * The items in the enumeration are obtained one at a time as 36 * items from the search enumeration are requested. 37 * 38 * @author Rosanna Lee 39 */ 40 41 package com.sun.jndi.toolkit.dir; 42 43 import javax.naming.*; 44 import javax.naming.directory.*; 45 import javax.naming.spi.DirectoryManager; 46 47 import java.util.NoSuchElementException; 48 import java.util.Hashtable; 49 50 final public class LazySearchEnumerationImpl 51 implements NamingEnumeration<SearchResult> { 52 private NamingEnumeration<Binding> candidates; 53 private SearchResult nextMatch = null; 54 private SearchControls cons; 55 private AttrFilter filter; 56 private Context context; 57 private Hashtable<String, Object> env; 58 private boolean useFactory = true; 59 60 public LazySearchEnumerationImpl(NamingEnumeration<Binding> candidates, 61 AttrFilter filter, SearchControls cons) throws NamingException { 62 this.candidates = candidates; 63 this.filter = filter; 64 65 if(cons == null) { 66 this.cons = new SearchControls(); 67 } else { 68 this.cons = cons; 69 } 70 } 71 72 @SuppressWarnings("unchecked") // For Hashtable clone: env.clone() 73 public LazySearchEnumerationImpl(NamingEnumeration<Binding> candidates, 74 AttrFilter filter, SearchControls cons, 75 Context ctx, Hashtable<String, Object> env, boolean useFactory) 76 throws NamingException { 77 78 this.candidates = candidates; 79 this.filter = filter; 80 this.env = (Hashtable<String, Object>) 81 ((env == null) ? null : env.clone()); 82 this.context = ctx; 83 this.useFactory = useFactory; 84 85 if(cons == null) { 86 this.cons = new SearchControls(); 87 } else { 88 this.cons = cons; 89 } 90 } 91 92 93 public LazySearchEnumerationImpl(NamingEnumeration<Binding> candidates, 94 AttrFilter filter, SearchControls cons, 95 Context ctx, Hashtable<String, Object> env) throws NamingException { 96 this(candidates, filter, cons, ctx, env, true); 97 } 98 99 public boolean hasMore() throws NamingException { 100 // find and do not remove from list 101 return findNextMatch(false) != null; 102 } 103 104 public boolean hasMoreElements() { 105 try { 106 return hasMore(); 107 } catch (NamingException e) { 108 return false; 109 } 110 } 111 112 public SearchResult nextElement() { 113 try { 114 return findNextMatch(true); 115 } catch (NamingException e) { 116 throw new NoSuchElementException(e.toString()); 117 } 118 } 119 120 public SearchResult next() throws NamingException { 121 // find and remove from list 122 return (findNextMatch(true)); 123 } 124 125 public void close() throws NamingException { 126 if (candidates != null) { 127 candidates.close(); 128 } 129 } 130 131 private SearchResult findNextMatch(boolean remove) throws NamingException { 132 SearchResult answer; 133 if (nextMatch != null) { 134 answer = nextMatch; 135 if (remove) { 136 nextMatch = null; 137 } 138 return answer; 139 } else { 140 // need to find next match 141 Binding next; 142 Object obj; 143 Attributes targetAttrs; 144 while (candidates.hasMore()) { 145 next = candidates.next(); 146 obj = next.getObject(); 147 if (obj instanceof DirContext) { 148 targetAttrs = ((DirContext)(obj)).getAttributes(""); 149 if (filter.check(targetAttrs)) { 150 if (!cons.getReturningObjFlag()) { 151 obj = null; 152 } else if (useFactory) { 153 try { 154 // Give name only if context non-null, 155 // otherewise, name will be interpreted relative 156 // to initial context (not what we want) 157 Name nm = (context != null ? 158 new CompositeName(next.getName()) : null); 159 obj = DirectoryManager.getObjectInstance(obj, 160 nm, context, env, targetAttrs); 161 } catch (NamingException e) { 162 throw e; 163 } catch (Exception e) { 164 NamingException e2 = new NamingException( 165 "problem generating object using object factory"); 166 e2.setRootCause(e); 167 throw e2; 168 } 169 } 170 answer = new SearchResult(next.getName(), 171 next.getClassName(), obj, 172 SearchFilter.selectAttributes(targetAttrs, 173 cons.getReturningAttributes()), 174 true); 175 if (!remove) 176 nextMatch = answer; 177 return answer; 178 } 179 } 180 } 181 return null; 182 } 183 } 184 }