001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.iiop.orb;
031:
032: import java.util.ArrayList;
033: import java.lang.reflect.Method;
034:
035: import com.caucho.iiop.*;
036: import com.caucho.iiop.orb.EjbSessionObjectMarshal;
037: import com.caucho.iiop.marshal.AnyMarshal;
038: import com.caucho.iiop.marshal.Marshal;
039: import com.caucho.iiop.RemoteUserException;
040:
041: /**
042: * Proxy implementation for ORB clients.
043: */
044: public class MethodMarshal {
045: private String _name;
046: private String _overloadName;
047: private Marshal[] _args;
048: private Marshal _ret;
049:
050: private Class[] _exceptionTypes;
051: private Method _method;
052:
053: MethodMarshal(MarshalFactory factory, Method method, Class cl) {
054: _method = method;
055: _name = method.getName();
056:
057: if (isOverload(method, cl))
058: _overloadName = IiopSkeleton.mangle(method);
059: else
060: _overloadName = _name;
061:
062: Class[] params = method.getParameterTypes();
063:
064: boolean isIdl = false;
065:
066: _args = new Marshal[params.length];
067:
068: for (int i = 0; i < params.length; i++)
069: _args[i] = factory.create(params[i], isIdl);
070:
071: _ret = factory.create(method.getReturnType(), isIdl);
072:
073: ArrayList<Class> exnList = new ArrayList<Class>();
074:
075: for (Class exn : method.getExceptionTypes()) {
076: if (RuntimeException.class.isAssignableFrom(exn))
077: continue;
078: if (Error.class.isAssignableFrom(exn))
079: continue;
080:
081: exnList.add(exn);
082: }
083:
084: _exceptionTypes = new Class[exnList.size()];
085: exnList.toArray(_exceptionTypes);
086: }
087:
088: private boolean isOverload(Method method, Class cl) {
089: for (Method declMethod : cl.getMethods()) {
090: if (method.getName().equals(declMethod.getName())
091: && !method.equals(declMethod))
092: return true;
093: }
094:
095: return false;
096: }
097:
098: public Object invoke(org.omg.CORBA.portable.ObjectImpl obj,
099: Object[] args) throws Throwable {
100: org.omg.CORBA_2_3.portable.InputStream is = null;
101:
102: try {
103: org.omg.CORBA_2_3.portable.OutputStream os = ((org.omg.CORBA_2_3.portable.OutputStream) obj
104: ._request(_overloadName, true));
105:
106: // ejb/1331
107: if (_args.length > 0)
108: ((IiopWriter) os).alignMethodArgs();
109:
110: for (int i = 0; i < _args.length; i++) {
111: // XXX TCK: ejb30/bb/session/stateful/sessioncontext/annotated/passBusinessObjectRemote1
112: if (_args[i] instanceof AnyMarshal) {
113: Class type = null;
114:
115: if (args[i] != null) {
116: type = args[i].getClass();
117:
118: _args[i] = new com.caucho.iiop.marshal.RemoteMarshal(
119: type);
120: }
121: }
122:
123: _args[i].marshal(os, args[i]);
124: }
125:
126: is = ((org.omg.CORBA_2_3.portable.InputStream) obj
127: ._invoke(os));
128:
129: // XXX TCK: ejb30/bb/session/stateful/sessioncontext/annotated/getBusinessObjectRemote1
130: // See also: SkeletonMethod.service()
131: if (_ret instanceof AnyMarshal) {
132: // XXX TCK: ejb30/bb/session/stateless/callback/defaultinterceptor/descriptor/defaultInterceptorsForCallbackBean1
133: if (!_method.getReturnType().getName().startsWith(
134: "java."))
135: _ret = new EjbSessionObjectMarshal(_method
136: .getReturnType(), null);
137: }
138:
139: return _ret.unmarshal(is);
140: } catch (RemoteUserException e) {
141: // unwrap remote exceptions
142:
143: Throwable cause = e.getCause();
144:
145: if (cause instanceof RuntimeException)
146: throw cause;
147:
148: for (int i = 0; i < _exceptionTypes.length; i++) {
149: if (_exceptionTypes[i].isAssignableFrom(cause
150: .getClass()))
151: throw cause;
152: }
153:
154: throw e;
155: } finally {
156: if (is != null)
157: is.close();
158: }
159: }
160: }
|