001 /*
002 * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
003 *
004 * The Apache Software License, Version 1.1
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions
008 * are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright
011 * notice, this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright
014 * notice, this list of conditions and the following disclaimer in
015 * the documentation and/or other materials provided with the
016 * distribution.
017 *
018 * 3. The end-user documentation included with the redistribution, if
019 * any, must include the following acknowlegement:
020 * "This product includes software developed by the
021 * Caucho Technology (http://www.caucho.com/)."
022 * Alternately, this acknowlegement may appear in the software itself,
023 * if and wherever such third-party acknowlegements normally appear.
024 *
025 * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
026 * endorse or promote products derived from this software without prior
027 * written permission. For written permission, please contact
028 * info@caucho.com.
029 *
030 * 5. Products derived from this software may not be called "Resin"
031 * nor may "Resin" appear in their names without prior written
032 * permission of Caucho Technology.
033 *
034 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
035 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
036 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
037 * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
038 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
039 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
040 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
041 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
042 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
043 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
044 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
045 *
046 * @author Scott Ferguson
047 */
048
049 package com.caucho.services.server;
050
051 import java.io.InputStream;
052 import java.lang.reflect.Method;
053 import java.util.HashMap;
054
055 /**
056 * Proxy class for Hessian services.
057 */
058 abstract public class AbstractSkeleton {
059 private Class _apiClass;
060 private Class _homeClass;
061 private Class _objectClass;
062
063 private HashMap _methodMap = new HashMap();
064
065 /**
066 * Create a new hessian skeleton.
067 *
068 * @param apiClass the API interface
069 */
070 protected AbstractSkeleton(Class apiClass)
071 {
072 _apiClass = apiClass;
073
074 Method []methodList = apiClass.getMethods();
075
076 for (int i = 0; i < methodList.length; i++) {
077 Method method = methodList[i];
078
079 if (_methodMap.get(method.getName()) == null)
080 _methodMap.put(method.getName(), methodList[i]);
081
082 Class []param = method.getParameterTypes();
083 String mangledName = method.getName() + "__" + param.length;
084 _methodMap.put(mangledName, methodList[i]);
085
086 _methodMap.put(mangleName(method, false), methodList[i]);
087 }
088 }
089
090 /**
091 * Returns the API class of the current object.
092 */
093 public String getAPIClassName()
094 {
095 return _apiClass.getName();
096 }
097
098 /**
099 * Returns the API class of the factory/home.
100 */
101 public String getHomeClassName()
102 {
103 if (_homeClass != null)
104 return _homeClass.getName();
105 else
106 return getAPIClassName();
107 }
108
109 /**
110 * Sets the home API class.
111 */
112 public void setHomeClass(Class homeAPI)
113 {
114 _homeClass = homeAPI;
115 }
116
117 /**
118 * Returns the API class of the object URLs
119 */
120 public String getObjectClassName()
121 {
122 if (_objectClass != null)
123 return _objectClass.getName();
124 else
125 return getAPIClassName();
126 }
127
128 /**
129 * Sets the object API class.
130 */
131 public void setObjectClass(Class objectAPI)
132 {
133 _objectClass = objectAPI;
134 }
135
136 /**
137 * Returns the method by the mangled name.
138 *
139 * @param mangledName the name passed by the protocol
140 */
141 protected Method getMethod(String mangledName)
142 {
143 return (Method) _methodMap.get(mangledName);
144 }
145
146 /**
147 * Creates a unique mangled method name based on the method name and
148 * the method parameters.
149 *
150 * @param method the method to mangle
151 * @param isFull if true, mangle the full classname
152 *
153 * @return a mangled string.
154 */
155 public static String mangleName(Method method, boolean isFull)
156 {
157 StringBuffer sb = new StringBuffer();
158
159 sb.append(method.getName());
160
161 Class []params = method.getParameterTypes();
162 for (int i = 0; i < params.length; i++) {
163 sb.append('_');
164 sb.append(mangleClass(params[i], isFull));
165 }
166
167 return sb.toString();
168 }
169
170 /**
171 * Mangles a classname.
172 */
173 public static String mangleClass(Class cl, boolean isFull)
174 {
175 String name = cl.getName();
176
177 if (name.equals("boolean") || name.equals("java.lang.Boolean"))
178 return "boolean";
179 else if (name.equals("int") || name.equals("java.lang.Integer")
180 || name.equals("short") || name.equals("java.lang.Short")
181 || name.equals("byte") || name.equals("java.lang.Byte"))
182 return "int";
183 else if (name.equals("long") || name.equals("java.lang.Long"))
184 return "long";
185 else if (name.equals("float") || name.equals("java.lang.Float")
186 || name.equals("double") || name.equals("java.lang.Double"))
187 return "double";
188 else if (name.equals("java.lang.String")
189 || name.equals("com.caucho.util.CharBuffer")
190 || name.equals("char") || name.equals("java.lang.Character")
191 || name.equals("java.io.Reader"))
192 return "string";
193 else if (name.equals("java.util.Date")
194 || name.equals("com.caucho.util.QDate"))
195 return "date";
196 else if (InputStream.class.isAssignableFrom(cl)
197 || name.equals("[B"))
198 return "binary";
199 else if (cl.isArray()) {
200 return "[" + mangleClass(cl.getComponentType(), isFull);
201 }
202 else if (name.equals("org.w3c.dom.Node")
203 || name.equals("org.w3c.dom.Element")
204 || name.equals("org.w3c.dom.Document"))
205 return "xml";
206 else if (isFull)
207 return name;
208 else {
209 int p = name.lastIndexOf('.');
210 if (p > 0)
211 return name.substring(p + 1);
212 else
213 return name;
214 }
215 }
216
217 public String toString()
218 {
219 return getClass().getSimpleName() + "[" + _apiClass.getName() + "]";
220 }
221 }