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;
031:
032: import com.caucho.iiop.marshal.AnyMarshal;
033: import com.caucho.iiop.marshal.Marshal;
034: import com.caucho.iiop.orb.EjbSessionObjectMarshal;
035: import com.caucho.iiop.orb.MarshalFactory;
036:
037: import java.lang.reflect.InvocationTargetException;
038: import java.lang.reflect.Method;
039: import java.util.logging.Logger;
040: import java.rmi.RemoteException;
041:
042: public class SkeletonMethod {
043: private static final Logger log = Logger
044: .getLogger(SkeletonMethod.class.getName());
045:
046: private IiopSkeleton _skeleton;
047: private Method _method;
048:
049: private Marshal[] _marshalArgs;
050: private Marshal _marshalReturn;
051:
052: private Class[] _exnTypes;
053:
054: SkeletonMethod(IiopSkeleton skeleton, Method method, boolean isJava) {
055: _skeleton = skeleton;
056: _method = method;
057:
058: MarshalFactory factory = MarshalFactory.create();
059:
060: // System.out.println("M: " + method);
061:
062: Class[] paramTypes = method.getParameterTypes();
063:
064: _marshalArgs = new Marshal[paramTypes.length];
065:
066: for (int i = 0; i < _marshalArgs.length; i++)
067: _marshalArgs[i] = factory.create(paramTypes[i], !isJava);
068:
069: _marshalReturn = factory
070: .create(method.getReturnType(), !isJava);
071:
072: _exnTypes = method.getExceptionTypes();
073: }
074:
075: void service(Object object, IiopReader reader, IiopWriter writer)
076: throws Throwable {
077: Object[] args = new Object[_marshalArgs.length];
078:
079: // ejb/1231
080: if (args.length > 0)
081: reader.alignMethodArgs();
082:
083: Class paramTypes[] = _method.getParameterTypes();
084:
085: for (int i = 0; i < args.length; i++) {
086: if (_marshalArgs[i] instanceof AnyMarshal) {
087: _marshalArgs[i] = new com.caucho.iiop.marshal.RemoteMarshal(
088: paramTypes[i]);
089: }
090:
091: args[i] = _marshalArgs[i].unmarshal(reader);
092: }
093:
094: try {
095: Object result = _method.invoke(object, args);
096:
097: writer.startReplyOk(reader.getRequestId());
098:
099: // XXX
100: // If the method return type is a EJB 3.0 remote interface, it is difficult to
101: // find the correct marshaller. Since EJB 3.0 remote interfaces do not need to
102: // have well-known superinterfaces, the method return type might not help.
103: // For now, we rely on the result object type.
104:
105: // See RemoteMarshal. The following breaks several TCK
106: // TCK: ejb30/bb/session/stateful/sessioncontext/annotated/getBusinessObjectRemote1 and
107: // TCK: ejb30/bb/session/stateless/sessioncontext/annotated/getBusinessObjectRemote1
108: if (result != null
109: && (result instanceof com.caucho.ejb.AbstractEJBObject)) {
110: //_marshalReturn = new com.caucho.iiop.marshal.RemoteMarshal(_method.getReturnType());
111: _marshalReturn = new EjbSessionObjectMarshal(_method
112: .getReturnType(), _skeleton);
113: }
114:
115: _marshalReturn.marshal(writer, result);
116: } catch (InvocationTargetException e) {
117: Throwable cause = e.getCause();
118:
119: if (cause instanceof RemoteException)
120: throw cause;
121:
122: for (int i = 0; i < _exnTypes.length; i++) {
123: if (_exnTypes[i].isAssignableFrom(cause.getClass()))
124: throw cause;
125: }
126:
127: throw new RemoteException(cause.toString(), cause);
128: }
129: }
130: }
|