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