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.util.L10N;
033:
034: import org.omg.CORBA.NO_IMPLEMENT;
035:
036: import java.lang.reflect.Method;
037: import java.util.HashMap;
038: import java.util.ArrayList;
039: import java.util.logging.Level;
040: import java.util.logging.Logger;
041:
042: public class IiopSkeleton extends DummyObjectImpl {
043: private static final L10N L = new L10N(IiopSkeleton.class);
044: private static final Logger log = Logger
045: .getLogger(IiopSkeleton.class.getName());
046:
047: private static HashMap<String, String> _knownClasses;
048:
049: private ClassLoader _loader;
050: private Class _remoteClass;
051: private ArrayList<Class> _apiList;
052: private HashMap<String, SkeletonMethod> _methodMap = new HashMap<String, SkeletonMethod>();
053:
054: private Object _obj;
055:
056: public IiopSkeleton(Object obj, ArrayList<Class> apiList,
057: ClassLoader loader, String host, int port, String oid) {
058: super (new IOR(apiList.get(0), host, port, oid));
059:
060: if (obj == null)
061: throw new NullPointerException();
062:
063: _obj = obj;
064: _apiList = apiList;
065: _remoteClass = _apiList.get(0);
066: _loader = loader;
067:
068: introspectMethods();
069: }
070:
071: Object getObject() {
072: return _obj;
073: }
074:
075: ArrayList<Class> getApiList() {
076: return _apiList;
077: }
078:
079: void service(Object obj, IiopReader reader, IiopWriter writer)
080: throws Throwable {
081: String op = reader.getOperation().toString();
082:
083: Method method = null;
084: SkeletonMethod skelMethod = null;
085:
086: if (log.isLoggable(Level.FINE))
087: log.fine("IIOP-call: " + _remoteClass.getName() + "." + op);
088:
089: skelMethod = _methodMap.get(op);
090:
091: if (skelMethod != null) {
092: Thread thread = Thread.currentThread();
093: ClassLoader oldLoader = thread.getContextClassLoader();
094: try {
095: thread.setContextClassLoader(_loader);
096:
097: skelMethod.service(obj, reader, writer);
098: } finally {
099: thread.setContextClassLoader(oldLoader);
100: }
101: } else if (serviceSystemMethod(obj, op, reader, writer)) {
102: } else {
103: throw new NO_IMPLEMENT(L.l(
104: "{0}: '{1}' is an unknown method.", _remoteClass
105: .getName(), op));
106: }
107: }
108:
109: Method getMethod(String name) {
110: for (int j = 0; j < _apiList.size(); j++) {
111: Method[] methods = _apiList.get(j).getMethods();
112:
113: for (int i = 0; i < methods.length; i++)
114: if (methods[i].getName().equals(name))
115: return methods[i];
116: }
117:
118: return null;
119: }
120:
121: private void introspectMethods() {
122: for (int j = 0; j < _apiList.size(); j++) {
123: Method[] methods = _apiList.get(j).getMethods();
124:
125: for (int i = 0; i < methods.length; i++) {
126: introspectMethod(methods[i]);
127: }
128: }
129: }
130:
131: private void introspectMethod(Method method) {
132: boolean isJava = !_remoteClass.getName().startsWith(
133: "com.caucho.iiop");
134:
135: SkeletonMethod skelMethod = new SkeletonMethod(this , method,
136: isJava);
137:
138: _methodMap.put(method.getName(), skelMethod);
139: _methodMap.put(mangle(method), skelMethod);
140: }
141:
142: public static String mangle(Method method) {
143: StringBuilder sb = new StringBuilder();
144:
145: sb.append(method.getName());
146: sb.append("__");
147:
148: Class[] args = method.getParameterTypes();
149: for (int i = 0; i < args.length; i++) {
150: Class arg = args[i];
151:
152: if (i > 0)
153: sb.append("__");
154:
155: if (String.class.equals(arg))
156: sb.append("CORBA_WStringValue");
157: else if (int.class.equals(arg))
158: sb.append("long");
159: else if (long.class.equals(arg))
160: sb.append("longlong");
161: else
162: sb.append(arg.getName().replace('.', '_'));
163: }
164:
165: return sb.toString();
166: }
167:
168: boolean serviceSystemMethod(Object obj, String op,
169: IiopReader reader, IiopWriter writer) throws Exception {
170: if (op.equals("_is_a")) {
171: String name = reader.read_string();
172:
173: String className = _knownClasses.get(name);
174:
175: if (className != null) {
176: } else if (name.startsWith("RMI:")) {
177: className = name.substring(4);
178: int p = className.indexOf(':');
179: if (p > 0)
180: className = className.substring(0, p);
181: } else
182: className = name;
183:
184: Class cl = obj.getClass();
185:
186: boolean value = isA(cl, className);
187:
188: if (log.isLoggable(Level.FINE))
189: log.fine("IIOP _is_a: " + obj.getClass() + " "
190: + className + " " + value);
191:
192: writer.startReplyOk(reader.getRequestId());
193: writer.write_boolean(value);
194:
195: return true;
196: } else
197: return false;
198: }
199:
200: private boolean isA(Class cl, String className) {
201: for (; cl != null; cl = cl.getSuperclass()) {
202: if (cl.getName().equals(className))
203: return true;
204:
205: Class[] ifs = cl.getInterfaces();
206: for (int i = 0; i < ifs.length; i++) {
207: if (isA(ifs[i], className))
208: return true;
209: }
210: }
211:
212: return false;
213: }
214:
215: public String toString() {
216: return "IiopSkeleton[" + _remoteClass.getName() + "]";
217: }
218:
219: static {
220: _knownClasses = new HashMap<String, String>();
221: _knownClasses.put("IDL:omg.org/CosNaming/NamingContext:1.0",
222: "org.omg.CosNaming.NamingContext");
223: }
224: }
|