1 /*
   2  * Copyright (c) 1999, 2004, 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 javax.naming.spi;
  27 
  28 import java.util.Hashtable;
  29 
  30 import javax.naming.Name;
  31 import javax.naming.NamingEnumeration;
  32 import javax.naming.CompositeName;
  33 import javax.naming.NamingException;
  34 import javax.naming.CannotProceedException;
  35 import javax.naming.OperationNotSupportedException;
  36 import javax.naming.Context;
  37 
  38 import javax.naming.directory.DirContext;
  39 import javax.naming.directory.Attributes;
  40 import javax.naming.directory.SearchControls;
  41 import javax.naming.directory.SearchResult;
  42 import javax.naming.directory.ModificationItem;
  43 
  44 /**
  45   * This class is the continuation context for invoking DirContext methods.
  46   *
  47   * @author Rosanna Lee
  48   * @author Scott Seligman
  49   * @since 1.3
  50   */
  51 
  52 class ContinuationDirContext extends ContinuationContext implements DirContext {
  53 
  54     ContinuationDirContext(CannotProceedException cpe, Hashtable<?,?> env) {
  55         super(cpe, env);
  56     }
  57 
  58     protected DirContextNamePair getTargetContext(Name name)
  59             throws NamingException {
  60 
  61         if (cpe.getResolvedObj() == null)
  62             throw (NamingException)cpe.fillInStackTrace();
  63 
  64         Context ctx = NamingManager.getContext(cpe.getResolvedObj(),
  65                                                cpe.getAltName(),
  66                                                cpe.getAltNameCtx(),
  67                                                env);
  68         if (ctx == null)
  69             throw (NamingException)cpe.fillInStackTrace();
  70 
  71         if (ctx instanceof DirContext)
  72             return new DirContextNamePair((DirContext)ctx, name);
  73 
  74         if (ctx instanceof Resolver) {
  75             Resolver res = (Resolver)ctx;
  76             ResolveResult rr = res.resolveToClass(name, DirContext.class);
  77 
  78             // Reached a DirContext; return result.
  79             DirContext dctx = (DirContext)rr.getResolvedObj();
  80             return (new DirContextNamePair(dctx, rr.getRemainingName()));
  81         }
  82 
  83         // Resolve all the way using lookup().  This may allow the operation
  84         // to succeed if it doesn't require the penultimate context.
  85         Object ultimate = ctx.lookup(name);
  86         if (ultimate instanceof DirContext) {
  87             return (new DirContextNamePair((DirContext)ultimate,
  88                                           new CompositeName()));
  89         }
  90 
  91         throw (NamingException)cpe.fillInStackTrace();
  92     }
  93 
  94     protected DirContextStringPair getTargetContext(String name)
  95             throws NamingException {
  96 
  97         if (cpe.getResolvedObj() == null)
  98             throw (NamingException)cpe.fillInStackTrace();
  99 
 100         Context ctx = NamingManager.getContext(cpe.getResolvedObj(),
 101                                                cpe.getAltName(),
 102                                                cpe.getAltNameCtx(),
 103                                                env);
 104 
 105         if (ctx instanceof DirContext)
 106             return new DirContextStringPair((DirContext)ctx, name);
 107 
 108         if (ctx instanceof Resolver) {
 109             Resolver res = (Resolver)ctx;
 110             ResolveResult rr = res.resolveToClass(name, DirContext.class);
 111 
 112             // Reached a DirContext; return result.
 113             DirContext dctx = (DirContext)rr.getResolvedObj();
 114             Name tmp = rr.getRemainingName();
 115             String remains = (tmp != null) ? tmp.toString() : "";
 116             return (new DirContextStringPair(dctx, remains));
 117         }
 118 
 119         // Resolve all the way using lookup().  This may allow the operation
 120         // to succeed if it doesn't require the penultimate context.
 121         Object ultimate = ctx.lookup(name);
 122         if (ultimate instanceof DirContext) {
 123             return (new DirContextStringPair((DirContext)ultimate, ""));
 124         }
 125 
 126         throw (NamingException)cpe.fillInStackTrace();
 127     }
 128 
 129     public Attributes getAttributes(String name) throws NamingException {
 130         DirContextStringPair res = getTargetContext(name);
 131         return res.getDirContext().getAttributes(res.getString());
 132     }
 133 
 134     public Attributes getAttributes(String name, String[] attrIds)
 135         throws NamingException {
 136             DirContextStringPair res = getTargetContext(name);
 137             return res.getDirContext().getAttributes(res.getString(), attrIds);
 138         }
 139 
 140     public Attributes getAttributes(Name name) throws NamingException {
 141         DirContextNamePair res = getTargetContext(name);
 142         return res.getDirContext().getAttributes(res.getName());
 143     }
 144 
 145     public Attributes getAttributes(Name name, String[] attrIds)
 146         throws NamingException {
 147             DirContextNamePair res = getTargetContext(name);
 148             return res.getDirContext().getAttributes(res.getName(), attrIds);
 149         }
 150 
 151     public void modifyAttributes(Name name, int mod_op, Attributes attrs)
 152         throws NamingException  {
 153             DirContextNamePair res = getTargetContext(name);
 154             res.getDirContext().modifyAttributes(res.getName(), mod_op, attrs);
 155         }
 156     public void modifyAttributes(String name, int mod_op, Attributes attrs)
 157         throws NamingException  {
 158             DirContextStringPair res = getTargetContext(name);
 159             res.getDirContext().modifyAttributes(res.getString(), mod_op, attrs);
 160         }
 161 
 162     public void modifyAttributes(Name name, ModificationItem[] mods)
 163         throws NamingException  {
 164             DirContextNamePair res = getTargetContext(name);
 165             res.getDirContext().modifyAttributes(res.getName(), mods);
 166         }
 167     public void modifyAttributes(String name, ModificationItem[] mods)
 168         throws NamingException  {
 169             DirContextStringPair res = getTargetContext(name);
 170             res.getDirContext().modifyAttributes(res.getString(), mods);
 171         }
 172 
 173     public void bind(Name name, Object obj, Attributes attrs)
 174         throws NamingException  {
 175             DirContextNamePair res = getTargetContext(name);
 176             res.getDirContext().bind(res.getName(), obj, attrs);
 177         }
 178     public void bind(String name, Object obj, Attributes attrs)
 179         throws NamingException  {
 180             DirContextStringPair res = getTargetContext(name);
 181             res.getDirContext().bind(res.getString(), obj, attrs);
 182         }
 183 
 184     public void rebind(Name name, Object obj, Attributes attrs)
 185                 throws NamingException {
 186             DirContextNamePair res = getTargetContext(name);
 187             res.getDirContext().rebind(res.getName(), obj, attrs);
 188         }
 189     public void rebind(String name, Object obj, Attributes attrs)
 190                 throws NamingException {
 191             DirContextStringPair res = getTargetContext(name);
 192             res.getDirContext().rebind(res.getString(), obj, attrs);
 193         }
 194 
 195     public DirContext createSubcontext(Name name, Attributes attrs)
 196                 throws NamingException  {
 197             DirContextNamePair res = getTargetContext(name);
 198             return res.getDirContext().createSubcontext(res.getName(), attrs);
 199         }
 200 
 201     public DirContext createSubcontext(String name, Attributes attrs)
 202                 throws NamingException  {
 203             DirContextStringPair res = getTargetContext(name);
 204             return
 205                 res.getDirContext().createSubcontext(res.getString(), attrs);
 206         }
 207 
 208     public NamingEnumeration<SearchResult> search(Name name,
 209                                     Attributes matchingAttributes,
 210                                     String[] attributesToReturn)
 211         throws NamingException  {
 212             DirContextNamePair res = getTargetContext(name);
 213             return res.getDirContext().search(res.getName(), matchingAttributes,
 214                                              attributesToReturn);
 215         }
 216 
 217     public NamingEnumeration<SearchResult> search(String name,
 218                                     Attributes matchingAttributes,
 219                                     String[] attributesToReturn)
 220         throws NamingException  {
 221             DirContextStringPair res = getTargetContext(name);
 222             return res.getDirContext().search(res.getString(),
 223                                              matchingAttributes,
 224                                              attributesToReturn);
 225         }
 226 
 227     public NamingEnumeration<SearchResult> search(Name name,
 228                                     Attributes matchingAttributes)
 229         throws NamingException  {
 230             DirContextNamePair res = getTargetContext(name);
 231             return res.getDirContext().search(res.getName(), matchingAttributes);
 232         }
 233     public NamingEnumeration<SearchResult> search(String name,
 234                                     Attributes matchingAttributes)
 235         throws NamingException  {
 236             DirContextStringPair res = getTargetContext(name);
 237             return res.getDirContext().search(res.getString(),
 238                                              matchingAttributes);
 239         }
 240 
 241     public NamingEnumeration<SearchResult> search(Name name,
 242                                     String filter,
 243                                     SearchControls cons)
 244         throws NamingException {
 245             DirContextNamePair res = getTargetContext(name);
 246             return res.getDirContext().search(res.getName(), filter, cons);
 247         }
 248 
 249     public NamingEnumeration<SearchResult> search(String name,
 250                                     String filter,
 251                                     SearchControls cons)
 252         throws NamingException {
 253             DirContextStringPair res = getTargetContext(name);
 254             return res.getDirContext().search(res.getString(), filter, cons);
 255         }
 256 
 257     public NamingEnumeration<SearchResult> search(Name name,
 258                                     String filterExpr,
 259                                     Object[] args,
 260                                     SearchControls cons)
 261         throws NamingException {
 262             DirContextNamePair res = getTargetContext(name);
 263             return res.getDirContext().search(res.getName(), filterExpr, args,
 264                                              cons);
 265         }
 266 
 267     public NamingEnumeration<SearchResult> search(String name,
 268                                     String filterExpr,
 269                                     Object[] args,
 270                                     SearchControls cons)
 271         throws NamingException {
 272             DirContextStringPair res = getTargetContext(name);
 273             return res.getDirContext().search(res.getString(), filterExpr, args,
 274                                              cons);
 275         }
 276 
 277     public DirContext getSchema(String name) throws NamingException {
 278         DirContextStringPair res = getTargetContext(name);
 279         return res.getDirContext().getSchema(res.getString());
 280     }
 281 
 282     public DirContext getSchema(Name name) throws NamingException  {
 283         DirContextNamePair res = getTargetContext(name);
 284         return res.getDirContext().getSchema(res.getName());
 285     }
 286 
 287     public DirContext getSchemaClassDefinition(String name)
 288             throws NamingException  {
 289         DirContextStringPair res = getTargetContext(name);
 290         return res.getDirContext().getSchemaClassDefinition(res.getString());
 291     }
 292 
 293     public DirContext getSchemaClassDefinition(Name name)
 294             throws NamingException  {
 295         DirContextNamePair res = getTargetContext(name);
 296         return res.getDirContext().getSchemaClassDefinition(res.getName());
 297     }
 298 }
 299 
 300 class DirContextNamePair {
 301         DirContext ctx;
 302         Name name;
 303 
 304         DirContextNamePair(DirContext ctx, Name name) {
 305             this.ctx = ctx;
 306             this.name = name;
 307         }
 308 
 309         DirContext getDirContext() {
 310             return ctx;
 311         }
 312 
 313         Name getName() {
 314             return name;
 315         }
 316 }
 317 
 318 class DirContextStringPair {
 319         DirContext ctx;
 320         String str;
 321 
 322         DirContextStringPair(DirContext ctx, String str) {
 323             this.ctx = ctx;
 324             this.str = str;
 325         }
 326 
 327         DirContext getDirContext() {
 328             return ctx;
 329         }
 330 
 331         String getString() {
 332             return str;
 333         }
 334 }