001 /* 002 * The Apache Software License, Version 1.1 003 * 004 * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved. 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 "Burlap", "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.burlap.client; 050 051 import com.caucho.burlap.io.AbstractBurlapInput; 052 import com.caucho.burlap.io.BurlapOutput; 053 054 import java.io.FileNotFoundException; 055 import java.io.IOException; 056 import java.io.InputStream; 057 import java.io.OutputStream; 058 import java.lang.reflect.InvocationHandler; 059 import java.lang.reflect.Method; 060 import java.lang.reflect.Proxy; 061 import java.net.HttpURLConnection; 062 import java.net.URL; 063 import java.net.URLConnection; 064 import java.util.logging.*; 065 066 /** 067 * Proxy implementation for Burlap clients. Applications will generally 068 * use BurlapProxyFactory to create proxy clients. 069 */ 070 public class BurlapProxy implements InvocationHandler { 071 private static final Logger log 072 = Logger.getLogger(BurlapProxy.class.getName()); 073 074 private BurlapProxyFactory _factory; 075 private URL _url; 076 077 BurlapProxy(BurlapProxyFactory factory, URL url) 078 { 079 _factory = factory; 080 _url = url; 081 } 082 083 /** 084 * Returns the proxy's URL. 085 */ 086 public URL getURL() 087 { 088 return _url; 089 } 090 091 /** 092 * Handles the object invocation. 093 * 094 * @param proxy the proxy object to invoke 095 * @param method the method to call 096 * @param args the arguments to the proxy object 097 */ 098 public Object invoke(Object proxy, Method method, Object []args) 099 throws Throwable 100 { 101 String methodName = method.getName(); 102 Class []params = method.getParameterTypes(); 103 104 // equals and hashCode are special cased 105 if (methodName.equals("equals") && 106 params.length == 1 && params[0].equals(Object.class)) { 107 Object value = args[0]; 108 if (value == null || ! Proxy.isProxyClass(value.getClass())) 109 return new Boolean(false); 110 111 BurlapProxy handler = (BurlapProxy) Proxy.getInvocationHandler(value); 112 113 return new Boolean(_url.equals(handler.getURL())); 114 } 115 else if (methodName.equals("hashCode") && params.length == 0) 116 return new Integer(_url.hashCode()); 117 else if (methodName.equals("getBurlapType")) 118 return proxy.getClass().getInterfaces()[0].getName(); 119 else if (methodName.equals("getBurlapURL")) 120 return _url.toString(); 121 else if (methodName.equals("toString") && params.length == 0) 122 return getClass().getSimpleName() + "[" + _url + "]"; 123 124 InputStream is = null; 125 126 URLConnection conn = null; 127 HttpURLConnection httpConn = null; 128 try { 129 conn = _factory.openConnection(_url); 130 131 httpConn = (HttpURLConnection) conn; 132 133 httpConn.setRequestMethod("POST"); 134 conn.setRequestProperty("Content-Type", "text/xml"); 135 136 OutputStream os; 137 138 try { 139 os = conn.getOutputStream(); 140 } catch (Exception e) { 141 throw new BurlapRuntimeException(e); 142 } 143 144 BurlapOutput out = _factory.getBurlapOutput(os); 145 146 if (! _factory.isOverloadEnabled()) { 147 } 148 else if (args != null) 149 methodName = methodName + "__" + args.length; 150 else 151 methodName = methodName + "__0"; 152 153 if (log.isLoggable(Level.FINE)) 154 log.fine(this + " calling " + methodName + " (" + method + ")"); 155 156 out.call(methodName, args); 157 158 try { 159 os.flush(); 160 } catch (Exception e) { 161 throw new BurlapRuntimeException(e); 162 } 163 164 if (conn instanceof HttpURLConnection) { 165 httpConn = (HttpURLConnection) conn; 166 int code = 500; 167 168 try { 169 code = httpConn.getResponseCode(); 170 } catch (Exception e) { 171 } 172 173 if (code != 200) { 174 StringBuffer sb = new StringBuffer(); 175 int ch; 176 177 try { 178 is = httpConn.getInputStream(); 179 180 if (is != null) { 181 while ((ch = is.read()) >= 0) 182 sb.append((char) ch); 183 184 is.close(); 185 } 186 187 is = httpConn.getErrorStream(); 188 if (is != null) { 189 while ((ch = is.read()) >= 0) 190 sb.append((char) ch); 191 } 192 } catch (FileNotFoundException e) { 193 throw new BurlapRuntimeException(code + ": " + String.valueOf(e)); 194 } catch (IOException e) { 195 } 196 197 if (is != null) 198 is.close(); 199 200 throw new BurlapProtocolException(code + ": " + sb.toString()); 201 } 202 } 203 204 is = conn.getInputStream(); 205 206 AbstractBurlapInput in = _factory.getBurlapInput(is); 207 208 return in.readReply(method.getReturnType()); 209 } catch (BurlapProtocolException e) { 210 throw new BurlapRuntimeException(e); 211 } finally { 212 try { 213 if (is != null) 214 is.close(); 215 } catch (IOException e) { 216 } 217 218 if (httpConn != null) 219 httpConn.disconnect(); 220 } 221 } 222 223 public String toString() 224 { 225 return getClass().getSimpleName() + "[" + _url + "]"; 226 } 227 }