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 }