ExceptionMapper.java revision 820:9205e980062a
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 26package com.sun.jndi.cosnaming; 27 28import javax.naming.*; 29import javax.naming.directory.*; 30import javax.naming.spi.*; 31 32import org.omg.CosNaming.*; 33import org.omg.CosNaming.NamingContextPackage.*; 34import org.omg.CORBA.*; 35 36/** 37 * A convenience class to map the COS Naming exceptions to the JNDI exceptions. 38 * @author Raj Krishnamurthy 39 */ 40 41public final class ExceptionMapper { 42 private ExceptionMapper() {} // ensure no instance 43 private static final boolean debug = false; 44 45 public static final NamingException mapException(Exception e, 46 CNCtx ctx, NameComponent[] inputName) throws NamingException { 47 if (e instanceof NamingException) { 48 return (NamingException)e; 49 } 50 51 if (e instanceof RuntimeException) { 52 throw (RuntimeException)e; 53 } 54 55 NamingException ne; 56 if (e instanceof NotFound) { 57 if (ctx.federation) { 58 return tryFed((NotFound)e, ctx, inputName); 59 60 } else { 61 ne = new NameNotFoundException(); 62 } 63 64 } else if (e instanceof CannotProceed) { 65 66 ne = new CannotProceedException(); 67 NamingContext nc = ((CannotProceed) e).cxt; 68 NameComponent[] rest = ((CannotProceed) e).rest_of_name; 69 70 // %%% We assume that rest returns *all* unprocessed components. 71 // Don't' know if that is a good assumption, given 72 // NotFound doesn't set rest as expected. -RL 73 if (inputName != null && (inputName.length > rest.length)) { 74 NameComponent[] resolvedName = 75 new NameComponent[inputName.length - rest.length]; 76 System.arraycopy(inputName, 0, resolvedName, 0, resolvedName.length); 77 // Wrap resolved NamingContext inside a CNCtx 78 // Guess that its name (which is relative to ctx) 79 // is the part of inputName minus rest_of_name 80 ne.setResolvedObj(new CNCtx(ctx._orb, ctx.orbTracker, nc, 81 ctx._env, 82 ctx.makeFullName(resolvedName))); 83 } else { 84 ne.setResolvedObj(ctx); 85 } 86 87 ne.setRemainingName(CNNameParser.cosNameToName(rest)); 88 89 } else if (e instanceof InvalidName) { 90 ne = new InvalidNameException(); 91 } else if (e instanceof AlreadyBound) { 92 ne = new NameAlreadyBoundException(); 93 } else if (e instanceof NotEmpty) { 94 ne = new ContextNotEmptyException(); 95 } else { 96 ne = new NamingException("Unknown reasons"); 97 } 98 99 ne.setRootCause(e); 100 return ne; 101 } 102 103 private static final NamingException tryFed(NotFound e, CNCtx ctx, 104 NameComponent[] inputName) throws NamingException { 105 NameComponent[] rest = e.rest_of_name; 106 107 if (debug) { 108 System.out.println(e.why.value()); 109 System.out.println(rest.length); 110 } 111 112 // %%% Using 1.2 & 1.3 Sun's tnameserv, 'rest' contains only the first 113 // component that failed, not *rest* as advertized. This is useless 114 // because what if you have something like aa/aa/aa/aa/aa. 115 // If one of those is not found, you get "aa" as 'rest'. 116 if (rest.length == 1 && inputName != null) { 117 // Check that we're not talking to 1.2/1.3 Sun tnameserv 118 NameComponent lastIn = inputName[inputName.length-1]; 119 if (rest[0].id.equals(lastIn.id) && 120 rest[0].kind != null && 121 rest[0].kind.equals(lastIn.kind)) { 122 // Might be legit 123 ; 124 } else { 125 // Due to 1.2/1.3 bug that always returns single-item 'rest' 126 NamingException ne = new NameNotFoundException(); 127 ne.setRemainingName(CNNameParser.cosNameToName(rest)); 128 ne.setRootCause(e); 129 throw ne; 130 } 131 } 132 // Fixed in 1.4; perform calculations based on correct (1.4) behavior 133 134 // Calculate the components of the name that has been resolved 135 NameComponent[] resolvedName = null; 136 int len = 0; 137 if (inputName != null && (inputName.length >= rest.length)) { 138 139 if (e.why == NotFoundReason.not_context) { 140 // First component of rest is found but not a context; keep it 141 // as part of resolved name 142 len = inputName.length - (rest.length - 1); 143 144 // Remove resolved component from rest 145 if (rest.length == 1) { 146 // No more remaining 147 rest = null; 148 } else { 149 NameComponent[] tmp = new NameComponent[rest.length-1]; 150 System.arraycopy(rest, 1, tmp, 0, tmp.length); 151 rest = tmp; 152 } 153 } else { 154 len = inputName.length - rest.length; 155 } 156 157 if (len > 0) { 158 resolvedName = new NameComponent[len]; 159 System.arraycopy(inputName, 0, resolvedName, 0, len); 160 } 161 } 162 163 // Create CPE and set common fields 164 CannotProceedException cpe = new CannotProceedException(); 165 cpe.setRootCause(e); 166 if (rest != null && rest.length > 0) { 167 cpe.setRemainingName(CNNameParser.cosNameToName(rest)); 168 } 169 cpe.setEnvironment(ctx._env); 170 171 if (debug) { 172 System.out.println("rest of name: " + cpe.getRemainingName()); 173 } 174 175 // Lookup resolved name to get resolved object 176 final java.lang.Object resolvedObj = 177 (resolvedName != null) ? ctx.callResolve(resolvedName) : ctx; 178 179 if (resolvedObj instanceof javax.naming.Context) { 180 // obj is a context and child is not found 181 // try getting its nns dynamically by constructing 182 // a Reference containing obj. 183 RefAddr addr = new RefAddr("nns") { 184 public java.lang.Object getContent() { 185 return resolvedObj; 186 } 187 private static final long serialVersionUID = 188 669984699392133792L; 189 }; 190 Reference ref = new Reference("java.lang.Object", addr); 191 192 // Resolved name has trailing slash to indicate nns 193 CompositeName cname = new CompositeName(); 194 cname.add(""); // add trailing slash 195 196 cpe.setResolvedObj(ref); 197 cpe.setAltName(cname); 198 cpe.setAltNameCtx((javax.naming.Context)resolvedObj); 199 200 return cpe; 201 } else { 202 // Not a context, use object factory to transform object. 203 204 Name cname = CNNameParser.cosNameToName(resolvedName); 205 java.lang.Object resolvedObj2; 206 try { 207 resolvedObj2 = NamingManager.getObjectInstance(resolvedObj, 208 cname, ctx, ctx._env); 209 } catch (NamingException ge) { 210 throw ge; 211 } catch (Exception ge) { 212 NamingException ne = new NamingException( 213 "problem generating object using object factory"); 214 ne.setRootCause(ge); 215 throw ne; 216 } 217 218 // If a context, continue operation with context 219 if (resolvedObj2 instanceof javax.naming.Context) { 220 cpe.setResolvedObj(resolvedObj2); 221 } else { 222 // Add trailing slash 223 cname.add(""); 224 cpe.setAltName(cname); 225 226 // Create nns reference 227 final java.lang.Object rf2 = resolvedObj2; 228 RefAddr addr = new RefAddr("nns") { 229 public java.lang.Object getContent() { 230 return rf2; 231 } 232 private static final long serialVersionUID = 233 -785132553978269772L; 234 }; 235 Reference ref = new Reference("java.lang.Object", addr); 236 cpe.setResolvedObj(ref); 237 cpe.setAltNameCtx(ctx); 238 } 239 return cpe; 240 } 241 } 242} 243