Projects
Mega:24.03:SP1:Everything
hessian
_service:tar_scm:hessian-20230907.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:hessian-20230907.patch of Package hessian
diff -Npur hessian-4.0.65-src/META-INF/hessian/deserializers hessian-4.0.65-fix/META-INF/hessian/deserializers --- hessian-4.0.65-src/META-INF/hessian/deserializers 1970-01-01 08:00:00.000000000 +0800 +++ hessian-4.0.65-fix/META-INF/hessian/deserializers 2023-08-15 18:39:22.000000000 +0800 @@ -0,0 +1,3 @@ +java.io.File=com.caucho.hessian.io.FileDeserializer +java.math.BigDecimal=com.caucho.hessian.io.BigDecimalDeserializer +javax.management.ObjectName=com.caucho.hessian.io.ObjectNameDeserializer diff -Npur hessian-4.0.65-src/META-INF/hessian/serializers hessian-4.0.65-fix/META-INF/hessian/serializers --- hessian-4.0.65-src/META-INF/hessian/serializers 1970-01-01 08:00:00.000000000 +0800 +++ hessian-4.0.65-fix/META-INF/hessian/serializers 2023-08-15 18:39:22.000000000 +0800 @@ -0,0 +1,6 @@ +com.caucho.hessian.io.HessianRemoteObject=com.caucho.hessian.io.RemoteSerializer +com.caucho.burlap.io.BurlapRemoteObject=com.caucho.hessian.io.RemoteSerializer +java.io.File=com.caucho.hessian.io.StringValueSerializer +java.math.BigDecimal=com.caucho.hessian.io.StringValueSerializer +java.util.Locale=com.caucho.hessian.io.LocaleSerializer +javax.management.ObjectName=com.caucho.hessian.io.StringValueSerializer diff -Npur hessian-4.0.65-src/com/caucho/hessian/client/HessianProxy.java hessian-4.0.65-fix/com/caucho/hessian/client/HessianProxy.java --- hessian-4.0.65-src/com/caucho/hessian/client/HessianProxy.java 2020-07-23 12:51:28.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/hessian/client/HessianProxy.java 2023-08-15 18:39:22.000000000 +0800 @@ -1,483 +1,483 @@ -/* - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Caucho Technology (http://www.caucho.com/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "Hessian", "Resin", and "Caucho" must not be used to - * endorse or promote products derived from this software without prior - * written permission. For written permission, please contact - * info@caucho.com. - * - * 5. Products derived from this software may not be called "Resin" - * nor may "Resin" appear in their names without prior written - * permission of Caucho Technology. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @author Scott Ferguson - */ - -package com.caucho.hessian.client; - -import com.caucho.hessian.io.*; -import com.caucho.services.server.*; - -import java.io.*; -import java.util.logging.*; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.WeakHashMap; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.zip.*; - -/** - * Proxy implementation for Hessian clients. Applications will generally - * use HessianProxyFactory to create proxy clients. - */ -public class HessianProxy implements InvocationHandler, Serializable { - private static final Logger log - = Logger.getLogger(HessianProxy.class.getName()); - - protected HessianProxyFactory _factory; - - private WeakHashMap<Method,String> _mangleMap - = new WeakHashMap<Method,String>(); - - private Class<?> _type; - private URL _url; - - /** - * Protected constructor for subclassing - */ - protected HessianProxy(URL url, HessianProxyFactory factory) - { - this(url, factory, null); - } - - /** - * Protected constructor for subclassing - */ - protected HessianProxy(URL url, - HessianProxyFactory factory, - Class<?> type) - { - _factory = factory; - _url = url; - _type = type; - } - - /** - * Returns the proxy's URL. - */ - public URL getURL() - { - return _url; - } - - /** - * Handles the object invocation. - * - * @param proxy the proxy object to invoke - * @param method the method to call - * @param args the arguments to the proxy object - */ - public Object invoke(Object proxy, Method method, Object []args) - throws Throwable - { - String mangleName; - - synchronized (_mangleMap) { - mangleName = _mangleMap.get(method); - } - - if (mangleName == null) { - String methodName = method.getName(); - Class<?> []params = method.getParameterTypes(); - - // equals and hashCode are special cased - if (methodName.equals("equals") - && params.length == 1 && params[0].equals(Object.class)) { - Object value = args[0]; - if (value == null || ! Proxy.isProxyClass(value.getClass())) - return Boolean.FALSE; - - Object proxyHandler = Proxy.getInvocationHandler(value); - - if (! (proxyHandler instanceof HessianProxy)) - return Boolean.FALSE; - - HessianProxy handler = (HessianProxy) proxyHandler; - - return new Boolean(_url.equals(handler.getURL())); - } - else if (methodName.equals("hashCode") && params.length == 0) - return new Integer(_url.hashCode()); - else if (methodName.equals("getHessianType")) - return proxy.getClass().getInterfaces()[0].getName(); - else if (methodName.equals("getHessianURL")) - return _url.toString(); - else if (methodName.equals("toString") && params.length == 0) - return "HessianProxy[" + _url + "]"; - - if (! _factory.isOverloadEnabled()) - mangleName = method.getName(); - else - mangleName = mangleName(method); - - synchronized (_mangleMap) { - _mangleMap.put(method, mangleName); - } - } - - InputStream is = null; - HessianConnection conn = null; - - try { - if (log.isLoggable(Level.FINER)) - log.finer("Hessian[" + _url + "] calling " + mangleName); - - conn = sendRequest(mangleName, args); - - is = getInputStream(conn); - - if (log.isLoggable(Level.FINEST)) { - PrintWriter dbg = new PrintWriter(new LogWriter(log)); - HessianDebugInputStream dIs - = new HessianDebugInputStream(is, dbg); - - dIs.startTop2(); - - is = dIs; - } - - AbstractHessianInput in; - - int code = is.read(); - - if (code == 'H') { - int major = is.read(); - int minor = is.read(); - - in = _factory.getHessian2Input(is); - - Object value = in.readReply(method.getReturnType()); - - if (value instanceof InputStream) { - value = new ResultInputStream(conn, is, in, (InputStream) value); - is = null; - conn = null; - } - - return value; - } - else if (code == 'r') { - int major = is.read(); - int minor = is.read(); - - in = _factory.getHessianInput(is); - - in.startReplyBody(); - - Object value = in.readObject(method.getReturnType()); - - if (value instanceof InputStream) { - value = new ResultInputStream(conn, is, in, (InputStream) value); - is = null; - conn = null; - } - else { - in.completeReply(); - } - - return value; - } - else - throw new HessianProtocolException("'" + (char) code + "' is an unknown code"); - } catch (HessianProtocolException e) { - throw new HessianRuntimeException(e); - } finally { - try { - if (is != null) - is.close(); - } catch (Exception e) { - log.log(Level.FINE, e.toString(), e); - } - - try { - if (conn != null) - conn.destroy(); - } catch (Exception e) { - log.log(Level.FINE, e.toString(), e); - } - } - } - - protected InputStream getInputStream(HessianConnection conn) - throws IOException - { - InputStream is = conn.getInputStream(); - - if ("deflate".equals(conn.getContentEncoding())) { - is = new InflaterInputStream(is, new Inflater(true)); - } - - return is; - } - - protected String mangleName(Method method) - { - Class<?> []param = method.getParameterTypes(); - - if (param == null || param.length == 0) - return method.getName(); - else - return AbstractSkeleton.mangleName(method, false); - } - - /** - * Sends the HTTP request to the Hessian connection. - */ - protected HessianConnection sendRequest(String methodName, Object []args) - throws IOException - { - HessianConnection conn = null; - - conn = _factory.getConnectionFactory().open(_url); - boolean isValid = false; - - try { - addRequestHeaders(conn); - - OutputStream os = null; - - try { - os = conn.getOutputStream(); - } catch (Exception e) { - throw new HessianRuntimeException(e); - } - - if (log.isLoggable(Level.FINEST)) { - PrintWriter dbg = new PrintWriter(new LogWriter(log)); - HessianDebugOutputStream dOs = new HessianDebugOutputStream(os, dbg); - dOs.startTop2(); - os = dOs; - } - - AbstractHessianOutput out = _factory.getHessianOutput(os); - - out.call(methodName, args); - out.flush(); - - conn.sendRequest(); - - isValid = true; - - return conn; - } finally { - if (! isValid && conn != null) - conn.destroy(); - } - } - - /** - * Method that allows subclasses to add request headers such as cookies. - * Default implementation is empty. - */ - protected void addRequestHeaders(HessianConnection conn) - { - conn.addHeader("Content-Type", "x-application/hessian"); - conn.addHeader("Accept-Encoding", "deflate"); - - String basicAuth = _factory.getBasicAuth(); - - if (basicAuth != null) - conn.addHeader("Authorization", basicAuth); - } - - /** - * Method that allows subclasses to parse response headers such as cookies. - * Default implementation is empty. - * @param conn - */ - protected void parseResponseHeaders(URLConnection conn) - { - } - - public Object writeReplace() - { - return new HessianRemote(_type.getName(), _url.toString()); - } - - static class ResultInputStream extends InputStream { - private HessianConnection _conn; - private InputStream _connIs; - private AbstractHessianInput _in; - private InputStream _hessianIs; - - ResultInputStream(HessianConnection conn, - InputStream is, - AbstractHessianInput in, - InputStream hessianIs) - { - _conn = conn; - _connIs = is; - _in = in; - _hessianIs = hessianIs; - } - - public int read() - throws IOException - { - if (_hessianIs != null) { - int value = _hessianIs.read(); - - if (value < 0) - close(); - - return value; - } - else - return -1; - } - - public int read(byte []buffer, int offset, int length) - throws IOException - { - if (_hessianIs != null) { - int value = _hessianIs.read(buffer, offset, length); - - if (value < 0) - close(); - - return value; - } - else - return -1; - } - - public void close() - throws IOException - { - HessianConnection conn = _conn; - _conn = null; - - InputStream connIs = _connIs; - _connIs = null; - - AbstractHessianInput in = _in; - _in = null; - - InputStream hessianIs = _hessianIs; - _hessianIs = null; - - try { - if (hessianIs != null) - hessianIs.close(); - } catch (Exception e) { - log.log(Level.FINE, e.toString(), e); - } - - try { - if (in != null) { - in.completeReply(); - in.close(); - } - } catch (Exception e) { - log.log(Level.FINE, e.toString(), e); - } - - try { - if (connIs != null) { - connIs.close(); - } - } catch (Exception e) { - log.log(Level.FINE, e.toString(), e); - } - - try { - if (conn != null) { - conn.close(); - } - } catch (Exception e) { - log.log(Level.FINE, e.toString(), e); - } - } - } - - static class LogWriter extends Writer { - private Logger _log; - private Level _level = Level.FINEST; - private StringBuilder _sb = new StringBuilder(); - - LogWriter(Logger log) - { - _log = log; - } - - public void write(char ch) - { - if (ch == '\n' && _sb.length() > 0) { - _log.fine(_sb.toString()); - _sb.setLength(0); - } - else - _sb.append((char) ch); - } - - public void write(char []buffer, int offset, int length) - { - for (int i = 0; i < length; i++) { - char ch = buffer[offset + i]; - - if (ch == '\n' && _sb.length() > 0) { - _log.log(_level, _sb.toString()); - _sb.setLength(0); - } - else - _sb.append((char) ch); - } - } - - public void flush() - { - } - - public void close() - { - if (_sb.length() > 0) - _log.log(_level, _sb.toString()); - } - } -} +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Caucho Technology (http://www.caucho.com/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Hessian", "Resin", and "Caucho" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * info@caucho.com. + * + * 5. Products derived from this software may not be called "Resin" + * nor may "Resin" appear in their names without prior written + * permission of Caucho Technology. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Scott Ferguson + */ + +package com.caucho.hessian.client; + +import com.caucho.hessian.io.*; +import com.caucho.services.server.*; + +import java.io.*; +import java.util.logging.*; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.WeakHashMap; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.zip.*; + +/** + * Proxy implementation for Hessian clients. Applications will generally + * use HessianProxyFactory to create proxy clients. + */ +public class HessianProxy implements InvocationHandler, Serializable { + private static final Logger log + = Logger.getLogger(HessianProxy.class.getName()); + + protected HessianProxyFactory _factory; + + private WeakHashMap<Method,String> _mangleMap + = new WeakHashMap<Method,String>(); + + private Class<?> _type; + private URL _url; + + /** + * Protected constructor for subclassing + */ + protected HessianProxy(URL url, HessianProxyFactory factory) + { + this(url, factory, null); + } + + /** + * Protected constructor for subclassing + */ + protected HessianProxy(URL url, + HessianProxyFactory factory, + Class<?> type) + { + _factory = factory; + _url = url; + _type = type; + } + + /** + * Returns the proxy's URL. + */ + public URL getURL() + { + return _url; + } + + /** + * Handles the object invocation. + * + * @param proxy the proxy object to invoke + * @param method the method to call + * @param args the arguments to the proxy object + */ + public Object invoke(Object proxy, Method method, Object []args) + throws Throwable + { + String mangleName; + + synchronized (_mangleMap) { + mangleName = _mangleMap.get(method); + } + + if (mangleName == null) { + String methodName = method.getName(); + Class<?> []params = method.getParameterTypes(); + + // equals and hashCode are special cased + if (methodName.equals("equals") + && params.length == 1 && params[0].equals(Object.class)) { + Object value = args[0]; + if (value == null || ! Proxy.isProxyClass(value.getClass())) + return Boolean.FALSE; + + Object proxyHandler = Proxy.getInvocationHandler(value); + + if (! (proxyHandler instanceof HessianProxy)) + return Boolean.FALSE; + + HessianProxy handler = (HessianProxy) proxyHandler; + + return new Boolean(_url.equals(handler.getURL())); + } + else if (methodName.equals("hashCode") && params.length == 0) + return new Integer(_url.hashCode()); + else if (methodName.equals("getHessianType")) + return proxy.getClass().getInterfaces()[0].getName(); + else if (methodName.equals("getHessianURL")) + return _url.toString(); + else if (methodName.equals("toString") && params.length == 0) + return "HessianProxy[" + _url + "]"; + + if (! _factory.isOverloadEnabled()) + mangleName = method.getName(); + else + mangleName = mangleName(method); + + synchronized (_mangleMap) { + _mangleMap.put(method, mangleName); + } + } + + InputStream is = null; + HessianConnection conn = null; + + try { + if (log.isLoggable(Level.FINER)) + log.finer("Hessian[" + _url + "] calling " + mangleName); + + conn = sendRequest(mangleName, args); + + is = getInputStream(conn); + + if (log.isLoggable(Level.FINEST)) { + PrintWriter dbg = new PrintWriter(new LogWriter(log)); + HessianDebugInputStream dIs + = new HessianDebugInputStream(is, dbg); + + dIs.startTop2(); + + is = dIs; + } + + AbstractHessianInput in; + + int code = is.read(); + + if (code == 'H') { + int major = is.read(); + int minor = is.read(); + + in = _factory.getHessian2Input(is); + + Object value = in.readReply(method.getReturnType()); + + if (value instanceof InputStream) { + value = new ResultInputStream(conn, is, in, (InputStream) value); + is = null; + conn = null; + } + + return value; + } + else if (code == 'r') { + int major = is.read(); + int minor = is.read(); + + in = _factory.getHessianInput(is); + + in.startReplyBody(); + + Object value = in.readObject(method.getReturnType()); + + if (value instanceof InputStream) { + value = new ResultInputStream(conn, is, in, (InputStream) value); + is = null; + conn = null; + } + else { + in.completeReply(); + } + + return value; + } + else + throw new HessianProtocolException("'" + (char) code + "' is an unknown code"); + } catch (HessianProtocolException e) { + throw new HessianRuntimeException(e); + } finally { + try { + if (is != null) + is.close(); + } catch (Exception e) { + log.log(Level.FINE, e.toString(), e); + } + + try { + if (conn != null) + conn.destroy(); + } catch (Exception e) { + log.log(Level.FINE, e.toString(), e); + } + } + } + + protected InputStream getInputStream(HessianConnection conn) + throws IOException + { + InputStream is = conn.getInputStream(); + + if ("deflate".equals(conn.getContentEncoding())) { + is = new InflaterInputStream(is, new Inflater(true)); + } + + return is; + } + + protected String mangleName(Method method) + { + Class<?> []param = method.getParameterTypes(); + + if (param == null || param.length == 0) + return method.getName(); + else + return AbstractSkeleton.mangleName(method, false); + } + + /** + * Sends the HTTP request to the Hessian connection. + */ + protected HessianConnection sendRequest(String methodName, Object []args) + throws IOException + { + HessianConnection conn = null; + + conn = _factory.getConnectionFactory().open(_url); + boolean isValid = false; + + try { + addRequestHeaders(conn); + + OutputStream os = null; + + try { + os = conn.getOutputStream(); + } catch (Exception e) { + throw new HessianRuntimeException(e); + } + + if (log.isLoggable(Level.FINEST)) { + PrintWriter dbg = new PrintWriter(new LogWriter(log)); + HessianDebugOutputStream dOs = new HessianDebugOutputStream(os, dbg); + dOs.startTop2(); + os = dOs; + } + + AbstractHessianOutput out = _factory.getHessianOutput(os); + + out.call(methodName, args); + out.flush(); + + conn.sendRequest(); + + isValid = true; + + return conn; + } finally { + if (! isValid && conn != null) + conn.destroy(); + } + } + + /** + * Method that allows subclasses to add request headers such as cookies. + * Default implementation is empty. + */ + protected void addRequestHeaders(HessianConnection conn) + { + conn.addHeader("Content-Type", "x-application/hessian"); + conn.addHeader("Interface-Name", this._type.getCanonicalName()); + + String basicAuth = _factory.getBasicAuth(); + + if (basicAuth != null) + conn.addHeader("Authorization", basicAuth); + } + + /** + * Method that allows subclasses to parse response headers such as cookies. + * Default implementation is empty. + * @param conn + */ + protected void parseResponseHeaders(URLConnection conn) + { + } + + public Object writeReplace() + { + return new HessianRemote(_type.getName(), _url.toString()); + } + + static class ResultInputStream extends InputStream { + private HessianConnection _conn; + private InputStream _connIs; + private AbstractHessianInput _in; + private InputStream _hessianIs; + + ResultInputStream(HessianConnection conn, + InputStream is, + AbstractHessianInput in, + InputStream hessianIs) + { + _conn = conn; + _connIs = is; + _in = in; + _hessianIs = hessianIs; + } + + public int read() + throws IOException + { + if (_hessianIs != null) { + int value = _hessianIs.read(); + + if (value < 0) + close(); + + return value; + } + else + return -1; + } + + public int read(byte []buffer, int offset, int length) + throws IOException + { + if (_hessianIs != null) { + int value = _hessianIs.read(buffer, offset, length); + + if (value < 0) + close(); + + return value; + } + else + return -1; + } + + public void close() + throws IOException + { + HessianConnection conn = _conn; + _conn = null; + + InputStream connIs = _connIs; + _connIs = null; + + AbstractHessianInput in = _in; + _in = null; + + InputStream hessianIs = _hessianIs; + _hessianIs = null; + + try { + if (hessianIs != null) + hessianIs.close(); + } catch (Exception e) { + log.log(Level.FINE, e.toString(), e); + } + + try { + if (in != null) { + in.completeReply(); + in.close(); + } + } catch (Exception e) { + log.log(Level.FINE, e.toString(), e); + } + + try { + if (connIs != null) { + connIs.close(); + } + } catch (Exception e) { + log.log(Level.FINE, e.toString(), e); + } + + try { + if (conn != null) { + conn.close(); + } + } catch (Exception e) { + log.log(Level.FINE, e.toString(), e); + } + } + } + + static class LogWriter extends Writer { + private Logger _log; + private Level _level = Level.FINEST; + private StringBuilder _sb = new StringBuilder(); + + LogWriter(Logger log) + { + _log = log; + } + + public void write(char ch) + { + if (ch == '\n' && _sb.length() > 0) { + _log.fine(_sb.toString()); + _sb.setLength(0); + } + else + _sb.append((char) ch); + } + + public void write(char []buffer, int offset, int length) + { + for (int i = 0; i < length; i++) { + char ch = buffer[offset + i]; + + if (ch == '\n' && _sb.length() > 0) { + _log.log(_level, _sb.toString()); + _sb.setLength(0); + } + else + _sb.append((char) ch); + } + } + + public void flush() + { + } + + public void close() + { + if (_sb.length() > 0) + _log.log(_level, _sb.toString()); + } + } +} diff -Npur hessian-4.0.65-src/com/caucho/hessian/io/ContextSerializerFactory.java hessian-4.0.65-fix/com/caucho/hessian/io/ContextSerializerFactory.java --- hessian-4.0.65-src/com/caucho/hessian/io/ContextSerializerFactory.java 2020-07-23 12:51:28.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/hessian/io/ContextSerializerFactory.java 2023-08-15 18:39:22.000000000 +0800 @@ -1,507 +1,519 @@ -/* - * Copyright (c) 2001-2008 Caucho Technology, Inc. All rights reserved. - * - * The Apache Software License, Version 1.1 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Caucho Technology (http://www.caucho.com/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "Burlap", "Resin", and "Caucho" must not be used to - * endorse or promote products derived from this software without prior - * written permission. For written permission, please contact - * info@caucho.com. - * - * 5. Products derived from this software may not be called "Resin" - * nor may "Resin" appear in their names without prior written - * permission of Caucho Technology. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @author Scott Ferguson - */ - -package com.caucho.hessian.io; - -import java.io.InputStream; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.net.InetAddress; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.WeakHashMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.caucho.hessian.HessianException; - -/** - * The classloader-specific Factory for returning serialization - */ -public class ContextSerializerFactory -{ - private static final Logger log - = Logger.getLogger(ContextSerializerFactory.class.getName()); - - private static Deserializer OBJECT_DESERIALIZER - = new BasicDeserializer(BasicDeserializer.OBJECT); - - private static final WeakHashMap<ClassLoader,SoftReference<ContextSerializerFactory>> - _contextRefMap - = new WeakHashMap<ClassLoader,SoftReference<ContextSerializerFactory>>(); - - private static final ClassLoader _systemClassLoader; - - private static HashMap<String,Serializer> _staticSerializerMap; - private static HashMap<String,Deserializer> _staticDeserializerMap; - private static HashMap _staticClassNameMap; - - private ContextSerializerFactory _parent; - private WeakReference<ClassLoader> _loaderRef; - - private final HashSet<String> _serializerFiles = new HashSet<String>(); - private final HashSet<String> _deserializerFiles = new HashSet<String>(); - - private final HashMap<String,Serializer> _serializerClassMap - = new HashMap<String,Serializer>(); - - private final ConcurrentHashMap<String,Serializer> _customSerializerMap - = new ConcurrentHashMap<String,Serializer>(); - - private final HashMap<Class<?>,Serializer> _serializerInterfaceMap - = new HashMap<Class<?>,Serializer>(); - - private final HashMap<String,Deserializer> _deserializerClassMap - = new HashMap<String,Deserializer>(); - - private final HashMap<String,Deserializer> _deserializerClassNameMap - = new HashMap<String,Deserializer>(); - - private final ConcurrentHashMap<String,Deserializer> _customDeserializerMap - = new ConcurrentHashMap<String,Deserializer>(); - - private final HashMap<Class<?>,Deserializer> _deserializerInterfaceMap - = new HashMap<Class<?>,Deserializer>(); - - public ContextSerializerFactory(ContextSerializerFactory parent, - ClassLoader loader) - { - if (loader == null) - loader = _systemClassLoader; - - _loaderRef = new WeakReference<ClassLoader>(loader); - - init(); - } - - public static ContextSerializerFactory create() - { - return create(Thread.currentThread().getContextClassLoader()); - } - - public static ContextSerializerFactory create(ClassLoader loader) - { - synchronized (_contextRefMap) { - SoftReference<ContextSerializerFactory> factoryRef - = _contextRefMap.get(loader); - - ContextSerializerFactory factory = null; - - if (factoryRef != null) - factory = factoryRef.get(); - - if (factory == null) { - ContextSerializerFactory parent = null; - - if (loader != null) - parent = create(loader.getParent()); - - factory = new ContextSerializerFactory(parent, loader); - factoryRef = new SoftReference<ContextSerializerFactory>(factory); - - _contextRefMap.put(loader, factoryRef); - } - - return factory; - } - } - - public ClassLoader getClassLoader() - { - WeakReference<ClassLoader> loaderRef = _loaderRef; - - if (loaderRef != null) - return loaderRef.get(); - else - return null; - } - - /** - * Returns the serializer for a given class. - */ - public Serializer getSerializer(String className) - { - Serializer serializer = _serializerClassMap.get(className); - - if (serializer == AbstractSerializer.NULL) - return null; - else - return serializer; - } - - /** - * Returns a custom serializer the class - * - * @param cl the class of the object that needs to be serialized. - * - * @return a serializer object for the serialization. - */ - public Serializer getCustomSerializer(Class cl) - { - Serializer serializer = _customSerializerMap.get(cl.getName()); - - if (serializer == AbstractSerializer.NULL) - return null; - else if (serializer != null) - return serializer; - - try { - Class serClass = Class.forName(cl.getName() + "HessianSerializer", - false, cl.getClassLoader()); - - Serializer ser = (Serializer) serClass.newInstance(); - - _customSerializerMap.put(cl.getName(), ser); - - return ser; - } catch (ClassNotFoundException e) { - log.log(Level.ALL, e.toString(), e); - } catch (Exception e) { - throw new HessianException(e); - } - - _customSerializerMap.put(cl.getName(), AbstractSerializer.NULL); - - return null; - } - - /** - * Returns the deserializer for a given class. - */ - public Deserializer getDeserializer(String className) - { - Deserializer deserializer = _deserializerClassMap.get(className); - - if (deserializer != null && deserializer != AbstractDeserializer.NULL) { - return deserializer; - } - - deserializer = _deserializerInterfaceMap.get(className); - - if (deserializer != null && deserializer != AbstractDeserializer.NULL) { - return deserializer; - } - - return null; - } - - /** - * Returns a custom deserializer the class - * - * @param cl the class of the object that needs to be deserialized. - * - * @return a deserializer object for the deserialization. - */ - public Deserializer getCustomDeserializer(Class cl) - { - Deserializer deserializer = _customDeserializerMap.get(cl.getName()); - - if (deserializer == AbstractDeserializer.NULL) - return null; - else if (deserializer != null) - return deserializer; - - try { - Class serClass = Class.forName(cl.getName() + "HessianDeserializer", - false, cl.getClassLoader()); - - Deserializer ser = (Deserializer) serClass.newInstance(); - - _customDeserializerMap.put(cl.getName(), ser); - - return ser; - } catch (ClassNotFoundException e) { - log.log(Level.ALL, e.toString(), e); - } catch (Exception e) { - throw new HessianException(e); - } - - _customDeserializerMap.put(cl.getName(), AbstractDeserializer.NULL); - - return null; - } - - /** - * Initialize the factory - */ - private void init() - { - if (_parent != null) { - _serializerFiles.addAll(_parent._serializerFiles); - _deserializerFiles.addAll(_parent._deserializerFiles); - - _serializerClassMap.putAll(_parent._serializerClassMap); - _deserializerClassMap.putAll(_parent._deserializerClassMap); - } - - if (_parent == null) { - _serializerClassMap.putAll(_staticSerializerMap); - _deserializerClassMap.putAll(_staticDeserializerMap); - _deserializerClassNameMap.putAll(_staticClassNameMap); - } - - HashMap<Class,Class> classMap; - - classMap = new HashMap<Class,Class>(); - initSerializerFiles("META-INF/hessian/serializers", - _serializerFiles, - classMap, - Serializer.class); - - for (Map.Entry<Class,Class> entry : classMap.entrySet()) { - try { - Serializer ser = (Serializer) entry.getValue().newInstance(); - - if (entry.getKey().isInterface()) - _serializerInterfaceMap.put(entry.getKey(), ser); - else - _serializerClassMap.put(entry.getKey().getName(), ser); - } catch (Exception e) { - throw new HessianException(e); - } - } - - classMap = new HashMap<Class,Class>(); - initSerializerFiles("META-INF/hessian/deserializers", - _deserializerFiles, - classMap, - Deserializer.class); - - for (Map.Entry<Class,Class> entry : classMap.entrySet()) { - try { - Deserializer ser = (Deserializer) entry.getValue().newInstance(); - - if (entry.getKey().isInterface()) - _deserializerInterfaceMap.put(entry.getKey(), ser); - else { - _deserializerClassMap.put(entry.getKey().getName(), ser); - } - } catch (Exception e) { - throw new HessianException(e); - } - } - } - - private void initSerializerFiles(String fileName, - HashSet<String> fileList, - HashMap<Class,Class> classMap, - Class type) - { - try { - ClassLoader classLoader = getClassLoader(); - - // on systems with the security manager enabled, the system classloader - // is null - if (classLoader == null) - return; - - Enumeration iter; - - iter = classLoader.getResources(fileName); - while (iter.hasMoreElements()) { - URL url = (URL) iter.nextElement(); - - if (fileList.contains(url.toString())) - continue; - - fileList.add(url.toString()); - - InputStream is = null; - try { - is = url.openStream(); - - Properties props = new Properties(); - props.load(is); - - for (Map.Entry entry : props.entrySet()) { - String apiName = (String) entry.getKey(); - String serializerName = (String) entry.getValue(); - - Class apiClass = null; - Class serializerClass = null; - - try { - apiClass = Class.forName(apiName, false, classLoader); - } catch (ClassNotFoundException e) { - log.fine(url + ": " + apiName + " is not available in this context: " + getClassLoader()); - continue; - } - - try { - serializerClass = Class.forName(serializerName, false, classLoader); - } catch (ClassNotFoundException e) { - log.fine(url + ": " + serializerName + " is not available in this context: " + getClassLoader()); - continue; - } - - if (! type.isAssignableFrom(serializerClass)) - throw new HessianException(url + ": " + serializerClass.getName() + " is invalid because it does not implement " + type.getName()); - - classMap.put(apiClass, serializerClass); - } - } finally { - if (is != null) - is.close(); - } - } - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new HessianException(e); - } - } - - private static void addBasic(Class cl, String typeName, int type) - { - _staticSerializerMap.put(cl.getName(), new BasicSerializer(type)); - - Deserializer deserializer = new BasicDeserializer(type); - _staticDeserializerMap.put(cl.getName(), deserializer); - _staticClassNameMap.put(typeName, deserializer); - } - - static { - _staticSerializerMap = new HashMap(); - _staticDeserializerMap = new HashMap(); - _staticClassNameMap = new HashMap(); - - FieldDeserializer2Factory fieldFactory = FieldDeserializer2Factory.create(); - - addBasic(void.class, "void", BasicSerializer.NULL); - - addBasic(Boolean.class, "boolean", BasicSerializer.BOOLEAN); - addBasic(Byte.class, "byte", BasicSerializer.BYTE); - addBasic(Short.class, "short", BasicSerializer.SHORT); - addBasic(Integer.class, "int", BasicSerializer.INTEGER); - addBasic(Long.class, "long", BasicSerializer.LONG); - addBasic(Float.class, "float", BasicSerializer.FLOAT); - addBasic(Double.class, "double", BasicSerializer.DOUBLE); - addBasic(Character.class, "char", BasicSerializer.CHARACTER_OBJECT); - addBasic(String.class, "string", BasicSerializer.STRING); - addBasic(Object.class, "object", BasicSerializer.OBJECT); - addBasic(java.util.Date.class, "date", BasicSerializer.DATE); - - addBasic(boolean.class, "boolean", BasicSerializer.BOOLEAN); - addBasic(byte.class, "byte", BasicSerializer.BYTE); - addBasic(short.class, "short", BasicSerializer.SHORT); - addBasic(int.class, "int", BasicSerializer.INTEGER); - addBasic(long.class, "long", BasicSerializer.LONG); - addBasic(float.class, "float", BasicSerializer.FLOAT); - addBasic(double.class, "double", BasicSerializer.DOUBLE); - addBasic(char.class, "char", BasicSerializer.CHARACTER); - - addBasic(boolean[].class, "[boolean", BasicSerializer.BOOLEAN_ARRAY); - addBasic(byte[].class, "[byte", BasicSerializer.BYTE_ARRAY); - _staticSerializerMap.put(byte[].class.getName(), ByteArraySerializer.SER); - addBasic(short[].class, "[short", BasicSerializer.SHORT_ARRAY); - addBasic(int[].class, "[int", BasicSerializer.INTEGER_ARRAY); - addBasic(long[].class, "[long", BasicSerializer.LONG_ARRAY); - addBasic(float[].class, "[float", BasicSerializer.FLOAT_ARRAY); - addBasic(double[].class, "[double", BasicSerializer.DOUBLE_ARRAY); - addBasic(char[].class, "[char", BasicSerializer.CHARACTER_ARRAY); - addBasic(String[].class, "[string", BasicSerializer.STRING_ARRAY); - addBasic(Object[].class, "[object", BasicSerializer.OBJECT_ARRAY); - - Deserializer objectDeserializer = new JavaDeserializer(Object.class, fieldFactory); - _staticDeserializerMap.put("object", objectDeserializer); - _staticClassNameMap.put("object", objectDeserializer); - - _staticSerializerMap.put(Class.class.getName(), new ClassSerializer()); - - _staticDeserializerMap.put(Number.class.getName(), new BasicDeserializer(BasicSerializer.NUMBER)); - - /* - for (Class cl : new Class[] { BigDecimal.class, File.class, ObjectName.class }) { - _staticSerializerMap.put(cl, StringValueSerializer.SER); - _staticDeserializerMap.put(cl, new StringValueDeserializer(cl)); - } - - _staticSerializerMap.put(ObjectName.class, StringValueSerializer.SER); - try { - _staticDeserializerMap.put(ObjectName.class, - new StringValueDeserializer(ObjectName.class)); - } catch (Throwable e) { - } - */ - - _staticSerializerMap.put(InetAddress.class.getName(), - InetAddressSerializer.create()); - - _staticSerializerMap.put(java.sql.Date.class.getName(), - new SqlDateSerializer()); - _staticSerializerMap.put(java.sql.Time.class.getName(), - new SqlDateSerializer()); - _staticSerializerMap.put(java.sql.Timestamp.class.getName(), - new SqlDateSerializer()); - - _staticDeserializerMap.put(java.sql.Date.class.getName(), - new SqlDateDeserializer(java.sql.Date.class)); - _staticDeserializerMap.put(java.sql.Time.class.getName(), - new SqlDateDeserializer(java.sql.Time.class)); - _staticDeserializerMap.put(java.sql.Timestamp.class.getName(), - new SqlDateDeserializer(java.sql.Timestamp.class)); - - // hessian/3bb5 - _staticDeserializerMap.put(StackTraceElement.class.getName(), - new StackTraceElementDeserializer(fieldFactory)); - - ClassLoader systemClassLoader = null; - try { - systemClassLoader = ClassLoader.getSystemClassLoader(); - } catch (Exception e) { - } - - _systemClassLoader = systemClassLoader; - } -} - +/* + * Copyright (c) 2001-2008 Caucho Technology, Inc. All rights reserved. + * + * The Apache Software License, Version 1.1 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Caucho Technology (http://www.caucho.com/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Burlap", "Resin", and "Caucho" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * info@caucho.com. + * + * 5. Products derived from this software may not be called "Resin" + * nor may "Resin" appear in their names without prior written + * permission of Caucho Technology. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Scott Ferguson + */ + +package com.caucho.hessian.io; + +import java.io.InputStream; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.net.InetAddress; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.caucho.hessian.HessianException; + +/** + * The classloader-specific Factory for returning serialization + */ +public class ContextSerializerFactory +{ + private static final Logger log + = Logger.getLogger(ContextSerializerFactory.class.getName()); + + private static Deserializer OBJECT_DESERIALIZER + = new BasicDeserializer(BasicDeserializer.OBJECT); + + private static final WeakHashMap<ClassLoader,SoftReference<ContextSerializerFactory>> + _contextRefMap + = new WeakHashMap<ClassLoader,SoftReference<ContextSerializerFactory>>(); + + private static final ClassLoader _systemClassLoader; + + private static HashMap<String,Serializer> _staticSerializerMap; + private static HashMap<String,Deserializer> _staticDeserializerMap; + private static HashMap _staticClassNameMap; + + private ContextSerializerFactory _parent; + private WeakReference<ClassLoader> _loaderRef; + + private final HashSet<String> _serializerFiles = new HashSet<String>(); + private final HashSet<String> _deserializerFiles = new HashSet<String>(); + + private final HashMap<String,Serializer> _serializerClassMap + = new HashMap<String,Serializer>(); + + private final ConcurrentHashMap<String,Serializer> _customSerializerMap + = new ConcurrentHashMap<String,Serializer>(); + + private final HashMap<Class<?>,Serializer> _serializerInterfaceMap + = new HashMap<Class<?>,Serializer>(); + + private final HashMap<String,Deserializer> _deserializerClassMap + = new HashMap<String,Deserializer>(); + + private final HashMap<String,Deserializer> _deserializerClassNameMap + = new HashMap<String,Deserializer>(); + + private final ConcurrentHashMap<String,Deserializer> _customDeserializerMap + = new ConcurrentHashMap<String,Deserializer>(); + + private final HashMap<Class<?>,Deserializer> _deserializerInterfaceMap + = new HashMap<Class<?>,Deserializer>(); + + public ContextSerializerFactory(ContextSerializerFactory parent, + ClassLoader loader) + { + if (loader == null) + loader = _systemClassLoader; + + _loaderRef = new WeakReference<ClassLoader>(loader); + + init(); + } + + public static ContextSerializerFactory create() + { + return create(Thread.currentThread().getContextClassLoader()); + } + + public static ContextSerializerFactory create(ClassLoader loader) + { + synchronized (_contextRefMap) { + SoftReference<ContextSerializerFactory> factoryRef + = _contextRefMap.get(loader); + + ContextSerializerFactory factory = null; + + if (factoryRef != null) + factory = factoryRef.get(); + + if (factory == null) { + ContextSerializerFactory parent = null; + + if (loader != null) + parent = create(loader.getParent()); + + factory = new ContextSerializerFactory(parent, loader); + factoryRef = new SoftReference<ContextSerializerFactory>(factory); + + _contextRefMap.put(loader, factoryRef); + } + + return factory; + } + } + + public ClassLoader getClassLoader() + { + WeakReference<ClassLoader> loaderRef = _loaderRef; + + if (loaderRef != null) + return loaderRef.get(); + else + return null; + } + + /** + * Returns the serializer for a given class. + */ + public Serializer getSerializer(String className) + { + Serializer serializer = _serializerClassMap.get(className); + + if (serializer == AbstractSerializer.NULL) + return null; + else + return serializer; + } + + /** + * Returns a custom serializer the class + * + * @param cl the class of the object that needs to be serialized. + * + * @return a serializer object for the serialization. + */ + public Serializer getCustomSerializer(Class cl) + { + Serializer serializer = _customSerializerMap.get(cl.getName()); + + if (serializer == AbstractSerializer.NULL) + return null; + else if (serializer != null) + return serializer; + + try { + String className = cl.getName() + "HessianSerializer"; + + if (cl.getName().equals("java.util.Locale")) { + className = "com.caucho.hessian.io.LocaleHessianSerializer"; + } + + Class serClass = Class.forName(className, false, + Thread.currentThread().getContextClassLoader()); + + Serializer ser = (Serializer) serClass.newInstance(); + + _customSerializerMap.put(cl.getName(), ser); + + return ser; + } catch (ClassNotFoundException e) { + log.log(Level.ALL, e.toString(), e); + } catch (Exception e) { + throw new HessianException(e); + } + + _customSerializerMap.put(cl.getName(), AbstractSerializer.NULL); + + return null; + } + + /** + * Returns the deserializer for a given class. + */ + public Deserializer getDeserializer(String className) + { + Deserializer deserializer = _deserializerClassMap.get(className); + + if (deserializer != null && deserializer != AbstractDeserializer.NULL) { + return deserializer; + } + + deserializer = _deserializerInterfaceMap.get(className); + + if (deserializer != null && deserializer != AbstractDeserializer.NULL) { + return deserializer; + } + + return null; + } + + /** + * Returns a custom deserializer the class + * + * @param cl the class of the object that needs to be deserialized. + * + * @return a deserializer object for the deserialization. + */ + public Deserializer getCustomDeserializer(Class cl) + { + Deserializer deserializer = _customDeserializerMap.get(cl.getName()); + + if (deserializer == AbstractDeserializer.NULL) + return null; + else if (deserializer != null) + return deserializer; + + try { + String className = cl.getName() + "HessianDeserializer"; + + if (cl.getName().equals("java.util.Locale")) { + className = "com.caucho.hessian.io.LocaleHessianDeserializer"; + } + + Class serClass = Class.forName(className, false, + Thread.currentThread().getContextClassLoader()); + + Deserializer ser = (Deserializer) serClass.newInstance(); + + _customDeserializerMap.put(cl.getName(), ser); + + return ser; + } catch (ClassNotFoundException e) { + log.log(Level.ALL, e.toString(), e); + } catch (Exception e) { + throw new HessianException(e); + } + + _customDeserializerMap.put(cl.getName(), AbstractDeserializer.NULL); + + return null; + } + + /** + * Initialize the factory + */ + private void init() + { + if (_parent != null) { + _serializerFiles.addAll(_parent._serializerFiles); + _deserializerFiles.addAll(_parent._deserializerFiles); + + _serializerClassMap.putAll(_parent._serializerClassMap); + _deserializerClassMap.putAll(_parent._deserializerClassMap); + } + + if (_parent == null) { + _serializerClassMap.putAll(_staticSerializerMap); + _deserializerClassMap.putAll(_staticDeserializerMap); + _deserializerClassNameMap.putAll(_staticClassNameMap); + } + + HashMap<Class,Class> classMap; + + classMap = new HashMap<Class,Class>(); + initSerializerFiles("META-INF/hessian/serializers", + _serializerFiles, + classMap, + Serializer.class); + + for (Map.Entry<Class,Class> entry : classMap.entrySet()) { + try { + Serializer ser = (Serializer) entry.getValue().newInstance(); + + if (entry.getKey().isInterface()) + _serializerInterfaceMap.put(entry.getKey(), ser); + else + _serializerClassMap.put(entry.getKey().getName(), ser); + } catch (Exception e) { + throw new HessianException(e); + } + } + + classMap = new HashMap<Class,Class>(); + initSerializerFiles("META-INF/hessian/deserializers", + _deserializerFiles, + classMap, + Deserializer.class); + + for (Map.Entry<Class,Class> entry : classMap.entrySet()) { + try { + Deserializer ser = (Deserializer) entry.getValue().newInstance(); + + if (entry.getKey().isInterface()) + _deserializerInterfaceMap.put(entry.getKey(), ser); + else { + _deserializerClassMap.put(entry.getKey().getName(), ser); + } + } catch (Exception e) { + throw new HessianException(e); + } + } + } + + private void initSerializerFiles(String fileName, + HashSet<String> fileList, + HashMap<Class,Class> classMap, + Class type) + { + try { + ClassLoader classLoader = getClassLoader(); + + // on systems with the security manager enabled, the system classloader + // is null + if (classLoader == null) + return; + + Enumeration iter; + + iter = classLoader.getResources(fileName); + while (iter.hasMoreElements()) { + URL url = (URL) iter.nextElement(); + + if (fileList.contains(url.toString())) + continue; + + fileList.add(url.toString()); + + InputStream is = null; + try { + is = url.openStream(); + + Properties props = new Properties(); + props.load(is); + + for (Map.Entry entry : props.entrySet()) { + String apiName = (String) entry.getKey(); + String serializerName = (String) entry.getValue(); + + Class apiClass = null; + Class serializerClass = null; + + try { + apiClass = Class.forName(apiName, false, classLoader); + } catch (ClassNotFoundException e) { + log.fine(url + ": " + apiName + " is not available in this context: " + getClassLoader()); + continue; + } + + try { + serializerClass = Class.forName(serializerName, false, classLoader); + } catch (ClassNotFoundException e) { + log.fine(url + ": " + serializerName + " is not available in this context: " + getClassLoader()); + continue; + } + + if (! type.isAssignableFrom(serializerClass)) + throw new HessianException(url + ": " + serializerClass.getName() + " is invalid because it does not implement " + type.getName()); + + classMap.put(apiClass, serializerClass); + } + } finally { + if (is != null) + is.close(); + } + } + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new HessianException(e); + } + } + + private static void addBasic(Class cl, String typeName, int type) + { + _staticSerializerMap.put(cl.getName(), new BasicSerializer(type)); + + Deserializer deserializer = new BasicDeserializer(type); + _staticDeserializerMap.put(cl.getName(), deserializer); + _staticClassNameMap.put(typeName, deserializer); + } + + static { + _staticSerializerMap = new HashMap(); + _staticDeserializerMap = new HashMap(); + _staticClassNameMap = new HashMap(); + + FieldDeserializer2Factory fieldFactory = FieldDeserializer2Factory.create(); + + addBasic(void.class, "void", BasicSerializer.NULL); + + addBasic(Boolean.class, "boolean", BasicSerializer.BOOLEAN); + addBasic(Byte.class, "byte", BasicSerializer.BYTE); + addBasic(Short.class, "short", BasicSerializer.SHORT); + addBasic(Integer.class, "int", BasicSerializer.INTEGER); + addBasic(Long.class, "long", BasicSerializer.LONG); + addBasic(Float.class, "float", BasicSerializer.FLOAT); + addBasic(Double.class, "double", BasicSerializer.DOUBLE); + addBasic(Character.class, "char", BasicSerializer.CHARACTER_OBJECT); + addBasic(String.class, "string", BasicSerializer.STRING); + addBasic(Object.class, "object", BasicSerializer.OBJECT); + addBasic(java.util.Date.class, "date", BasicSerializer.DATE); + + addBasic(boolean.class, "boolean", BasicSerializer.BOOLEAN); + addBasic(byte.class, "byte", BasicSerializer.BYTE); + addBasic(short.class, "short", BasicSerializer.SHORT); + addBasic(int.class, "int", BasicSerializer.INTEGER); + addBasic(long.class, "long", BasicSerializer.LONG); + addBasic(float.class, "float", BasicSerializer.FLOAT); + addBasic(double.class, "double", BasicSerializer.DOUBLE); + addBasic(char.class, "char", BasicSerializer.CHARACTER); + + addBasic(boolean[].class, "[boolean", BasicSerializer.BOOLEAN_ARRAY); + addBasic(byte[].class, "[byte", BasicSerializer.BYTE_ARRAY); + _staticSerializerMap.put(byte[].class.getName(), ByteArraySerializer.SER); + addBasic(short[].class, "[short", BasicSerializer.SHORT_ARRAY); + addBasic(int[].class, "[int", BasicSerializer.INTEGER_ARRAY); + addBasic(long[].class, "[long", BasicSerializer.LONG_ARRAY); + addBasic(float[].class, "[float", BasicSerializer.FLOAT_ARRAY); + addBasic(double[].class, "[double", BasicSerializer.DOUBLE_ARRAY); + addBasic(char[].class, "[char", BasicSerializer.CHARACTER_ARRAY); + addBasic(String[].class, "[string", BasicSerializer.STRING_ARRAY); + addBasic(Object[].class, "[object", BasicSerializer.OBJECT_ARRAY); + + Deserializer objectDeserializer = new JavaDeserializer(Object.class, fieldFactory); + _staticDeserializerMap.put("object", objectDeserializer); + _staticClassNameMap.put("object", objectDeserializer); + + _staticSerializerMap.put(Class.class.getName(), new ClassSerializer()); + + _staticDeserializerMap.put(Number.class.getName(), new BasicDeserializer(BasicSerializer.NUMBER)); + + /* + for (Class cl : new Class[] { BigDecimal.class, File.class, ObjectName.class }) { + _staticSerializerMap.put(cl, StringValueSerializer.SER); + _staticDeserializerMap.put(cl, new StringValueDeserializer(cl)); + } + + _staticSerializerMap.put(ObjectName.class, StringValueSerializer.SER); + try { + _staticDeserializerMap.put(ObjectName.class, + new StringValueDeserializer(ObjectName.class)); + } catch (Throwable e) { + } + */ + + _staticSerializerMap.put(InetAddress.class.getName(), + InetAddressSerializer.create()); + + _staticSerializerMap.put(java.sql.Date.class.getName(), + new SqlDateSerializer()); + _staticSerializerMap.put(java.sql.Time.class.getName(), + new SqlDateSerializer()); + _staticSerializerMap.put(java.sql.Timestamp.class.getName(), + new SqlDateSerializer()); + + _staticDeserializerMap.put(java.sql.Date.class.getName(), + new SqlDateDeserializer(java.sql.Date.class)); + _staticDeserializerMap.put(java.sql.Time.class.getName(), + new SqlDateDeserializer(java.sql.Time.class)); + _staticDeserializerMap.put(java.sql.Timestamp.class.getName(), + new SqlDateDeserializer(java.sql.Timestamp.class)); + + // hessian/3bb5 + _staticDeserializerMap.put(StackTraceElement.class.getName(), + new StackTraceElementDeserializer(fieldFactory)); + + ClassLoader systemClassLoader = null; + try { + systemClassLoader = ClassLoader.getSystemClassLoader(); + } catch (Exception e) { + } + + _systemClassLoader = systemClassLoader; + } +} + diff -Npur hessian-4.0.65-src/com/caucho/hessian/io/LocaleHessianDeserializer.java hessian-4.0.65-fix/com/caucho/hessian/io/LocaleHessianDeserializer.java --- hessian-4.0.65-src/com/caucho/hessian/io/LocaleHessianDeserializer.java 1970-01-01 08:00:00.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/hessian/io/LocaleHessianDeserializer.java 2023-08-15 18:39:22.000000000 +0800 @@ -0,0 +1,85 @@ +package com.caucho.hessian.io; +import com.caucho.hessian.io.AbstractDeserializer; +import com.caucho.hessian.io.AbstractHessianInput; + +import java.io.IOException; +import java.util.Locale; + +public class LocaleHessianDeserializer extends AbstractDeserializer { + + public Class getType() { + return Locale.class; + } + + public Object readMap(AbstractHessianInput in) + throws IOException { + int ref = in.addRef(null); + + String languageValue = null; + String countryValue = null; + String variantValue = null; + + while (!in.isEnd()) { + String key = in.readString(); + + if (key.equals("language")) + languageValue = in.readString(); + else if (key.equals("country")) + countryValue = in.readString(); + else if (key.equals("variant")) + variantValue = in.readString(); + else + in.readString(); + } + + in.readMapEnd(); + + Object value = getObject(languageValue, countryValue, variantValue); + + in.setRef(ref, value); + + return value; + } + + @Override + public Object readObject(AbstractHessianInput in, Object[] fields) throws IOException { + int ref = in.addRef(null); + + String languageValue = null; + String countryValue = null; + String variantValue = null; + + for (Object key : fields) { + if (key.equals("language")) + languageValue = in.readString(); + else if (key.equals("country")) + countryValue = in.readString(); + else if (key.equals("variant")) + variantValue = in.readString(); + else + in.readObject(); + + } + + Object value = getObject(languageValue, countryValue, variantValue); + + in.setRef(ref, value); + + return value; + } + + private Object getObject(String languageValue, String countryValue, String variantValue) { + Object value = null; + if (languageValue != null && countryValue != null && variantValue != null) { + value = new Locale(languageValue, countryValue, variantValue); + } else if (languageValue != null && countryValue != null) { + value = new Locale(languageValue, countryValue); + } else if (languageValue != null) { + value = new Locale(languageValue); + } else { + value = Locale.getDefault(); + } + return value; + } + +} \ No newline at end of file diff -Npur hessian-4.0.65-src/com/caucho/hessian/io/LocaleHessianSerializer.java hessian-4.0.65-fix/com/caucho/hessian/io/LocaleHessianSerializer.java --- hessian-4.0.65-src/com/caucho/hessian/io/LocaleHessianSerializer.java 1970-01-01 08:00:00.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/hessian/io/LocaleHessianSerializer.java 2023-08-15 18:39:22.000000000 +0800 @@ -0,0 +1,64 @@ +package com.caucho.hessian.io; +import com.caucho.hessian.io.AbstractHessianOutput; +import com.caucho.hessian.io.AbstractSerializer; + +import java.io.IOException; +import java.util.Locale; + +public class LocaleHessianSerializer extends AbstractSerializer +{ + public void writeObject(Object obj, AbstractHessianOutput out) + throws IOException + { + + if (obj == null) + out.writeNull(); + else + { + Class cl = obj.getClass(); + + if (out.addRef(obj)) + return; + + int ref = out.writeObjectBegin(cl.getName()); + + Locale loc = (Locale) obj; + + if (ref < -1) + { + if (loc.getLanguage() != null) + { + out.writeString("language"); + out.writeString(loc.getLanguage()); + } + if (loc.getCountry() != null) + { + out.writeString("country"); + out.writeString(loc.getCountry()); + } + if (loc.getVariant() != null) + { + out.writeString("variant"); + out.writeString(loc.getVariant()); + } + + out.writeMapEnd(); + } + else + { + if (ref == -1) + { + out.writeInt(3); + out.writeString("language"); + out.writeString("country"); + out.writeString("variant"); + out.writeObjectBegin(cl.getName()); + } + + out.writeString(loc.getLanguage()); + out.writeString(loc.getCountry()); + out.writeString(loc.getVariant()); + } + } + } +} \ No newline at end of file diff -Npur hessian-4.0.65-src/com/caucho/hessian/io/NonTransientUnsafeDeserializer.java hessian-4.0.65-fix/com/caucho/hessian/io/NonTransientUnsafeDeserializer.java --- hessian-4.0.65-src/com/caucho/hessian/io/NonTransientUnsafeDeserializer.java 1970-01-01 08:00:00.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/hessian/io/NonTransientUnsafeDeserializer.java 2023-08-15 18:39:22.000000000 +0800 @@ -0,0 +1,755 @@ +/** + * + */ +package com.caucho.hessian.io; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import sun.misc.Unsafe; + +/** + * @author l65882 + * + */ +public class NonTransientUnsafeDeserializer extends AbstractMapDeserializer { + private static final Logger log + = Logger.getLogger(JavaDeserializer.class.getName()); + + private static boolean _isEnabled; + @SuppressWarnings("restriction") + private static Unsafe _unsafe; + + private Class<?> _type; + private HashMap<String,FieldDeserializer> _fieldMap; + private Method _readResolve; + + public NonTransientUnsafeDeserializer(Class<?> cl) + { + _type = cl; + _fieldMap = getFieldMap(cl); + + _readResolve = getReadResolve(cl); + + if (_readResolve != null) { + _readResolve.setAccessible(true); + } + } + + public static boolean isEnabled() + { + return _isEnabled; + } + + @Override + public Class<?> getType() + { + return _type; + } + + @Override + public boolean isReadResolve() + { + return _readResolve != null; + } + + public Object readMap(AbstractHessianInput in) + throws IOException + { + try { + Object obj = instantiate(); + + return readMap(in, obj); + } catch (IOException e) { + throw e; + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e); + } + } + + @Override + public Object []createFields(int len) + { + return new FieldDeserializer[len]; + } + + public Object createField(String name) + { + Object reader = _fieldMap.get(name); + + if (reader == null) + reader = NullFieldDeserializer.DESER; + + return reader; + } + + @Override + public Object readObject(AbstractHessianInput in, + Object []fields) + throws IOException + { + try { + Object obj = instantiate(); + + return readObject(in, obj, (FieldDeserializer []) fields); + } catch (IOException e) { + throw e; + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e); + } + } + + @Override + public Object readObject(AbstractHessianInput in, + String []fieldNames) + throws IOException + { + try { + Object obj = instantiate(); + + return readObject(in, obj, fieldNames); + } catch (IOException e) { + throw e; + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e); + } + } + + /** + * Returns the readResolve method + */ + protected Method getReadResolve(Class<?> cl) + { + for (; cl != null; cl = cl.getSuperclass()) { + Method []methods = cl.getDeclaredMethods(); + + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + + if (method.getName().equals("readResolve") + && method.getParameterTypes().length == 0) + return method; + } + } + + return null; + } + + public Object readMap(AbstractHessianInput in, Object obj) + throws IOException + { + try { + int ref = in.addRef(obj); + + while (! in.isEnd()) { + Object key = in.readObject(); + + FieldDeserializer deser = (FieldDeserializer) _fieldMap.get(key); + + if (deser != null) + deser.deserialize(in, obj); + else + in.readObject(); + } + + in.readMapEnd(); + + Object resolve = resolve(in, obj); + + if (obj != resolve) + in.setRef(ref, resolve); + + return resolve; + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOExceptionWrapper(e); + } + } + + public Object readObject(AbstractHessianInput in, + Object obj, + FieldDeserializer []fields) + throws IOException + { + try { + int ref = in.addRef(obj); + + for (FieldDeserializer reader : fields) { + reader.deserialize(in, obj); + } + + Object resolve = resolve(in, obj); + + if (obj != resolve) + in.setRef(ref, resolve); + + return resolve; + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOExceptionWrapper(obj.getClass().getName() + ":" + e, e); + } + } + + public Object readObject(AbstractHessianInput in, + Object obj, + String []fieldNames) + throws IOException + { + try { + int ref = in.addRef(obj); + + for (String fieldName : fieldNames) { + FieldDeserializer reader = _fieldMap.get(fieldName); + + if (reader != null) + reader.deserialize(in, obj); + else + in.readObject(); + } + + Object resolve = resolve(in, obj); + + if (obj != resolve) + in.setRef(ref, resolve); + + return resolve; + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOExceptionWrapper(obj.getClass().getName() + ":" + e, e); + } + } + + protected Object resolve(AbstractHessianInput in, Object obj) + throws Exception + { + // if there's a readResolve method, call it + try { + if (_readResolve != null) + return _readResolve.invoke(obj, new Object[0]); + } catch (InvocationTargetException e) { + if (e.getCause() instanceof Exception) + throw (Exception) e.getCause(); + else + throw e; + } + + return obj; + } + + @SuppressWarnings("restriction") + protected Object instantiate() + throws Exception + { + return _unsafe.allocateInstance(_type); + } + + /** + * Creates a map of the classes fields. + */ + protected HashMap<String,FieldDeserializer> getFieldMap(Class<?> cl) + { + HashMap<String,FieldDeserializer> fieldMap + = new HashMap<String,FieldDeserializer>(); + + for (; cl != null; cl = cl.getSuperclass()) { + Field []fields = cl.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + + if (Modifier.isStatic(field.getModifiers())) + continue; + else if (fieldMap.get(field.getName()) != null) + continue; + // XXX: could parameterize the handler to only deal with public + try { + field.setAccessible(true); + } catch (Throwable e) { + e.printStackTrace(); + } + + Class<?> type = field.getType(); + FieldDeserializer deser; + + if (String.class.equals(type)) { + deser = new StringFieldDeserializer(field); + } + else if (byte.class.equals(type)) { + deser = new ByteFieldDeserializer(field); + } + else if (char.class.equals(type)) { + deser = new CharFieldDeserializer(field); + } + else if (short.class.equals(type)) { + deser = new ShortFieldDeserializer(field); + } + else if (int.class.equals(type)) { + deser = new IntFieldDeserializer(field); + } + else if (long.class.equals(type)) { + deser = new LongFieldDeserializer(field); + } + else if (float.class.equals(type)) { + deser = new FloatFieldDeserializer(field); + } + else if (double.class.equals(type)) { + deser = new DoubleFieldDeserializer(field); + } + else if (boolean.class.equals(type)) { + deser = new BooleanFieldDeserializer(field); + } + else if (java.sql.Date.class.equals(type)) { + deser = new SqlDateFieldDeserializer(field); + } + else if (java.sql.Timestamp.class.equals(type)) { + deser = new SqlTimestampFieldDeserializer(field); + } + else if (java.sql.Time.class.equals(type)) { + deser = new SqlTimeFieldDeserializer(field); + } + else { + deser = new ObjectFieldDeserializer(field); + } + + fieldMap.put(field.getName(), deser); + } + } + + return fieldMap; + } + + abstract static class FieldDeserializer { + abstract void deserialize(AbstractHessianInput in, Object obj) + throws IOException; + } + + static class NullFieldDeserializer extends FieldDeserializer { + static NullFieldDeserializer DESER = new NullFieldDeserializer(); + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + in.readObject(); + } + } + + static class ObjectFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + ObjectFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + Object value = null; + + try { + value = in.readObject(_field.getType()); + + _unsafe.putObject(obj, _offset, value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class BooleanFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + BooleanFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + boolean value = false; + + try { + value = in.readBoolean(); + + _unsafe.putBoolean(obj, _offset, value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class ByteFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + ByteFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + int value = 0; + + try { + value = in.readInt(); + + _unsafe.putByte(obj, _offset, (byte) value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class CharFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + CharFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + String value = null; + + try { + value = in.readString(); + + char ch; + + if (value != null && value.length() > 0) + ch = value.charAt(0); + else + ch = 0; + + _unsafe.putChar(obj, _offset, ch); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class ShortFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + ShortFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + int value = 0; + + try { + value = in.readInt(); + + _unsafe.putShort(obj, _offset, (short) value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class IntFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + IntFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + int value = 0; + + try { + value = in.readInt(); + + _unsafe.putInt(obj, _offset, value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class LongFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + LongFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + long value = 0; + + try { + value = in.readLong(); + + _unsafe.putLong(obj, _offset, value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class FloatFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + FloatFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + double value = 0; + + try { + value = in.readDouble(); + + _unsafe.putFloat(obj, _offset, (float) value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class DoubleFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + DoubleFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + double value = 0; + + try { + value = in.readDouble(); + + _unsafe.putDouble(obj, _offset, value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class StringFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + StringFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + String value = null; + + try { + value = in.readString(); + + _unsafe.putObject(obj, _offset, value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class SqlDateFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + SqlDateFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + java.sql.Date value = null; + + try { + java.util.Date date = (java.util.Date) in.readObject(); + value = new java.sql.Date(date.getTime()); + + _unsafe.putObject(obj, _offset, value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class SqlTimestampFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + SqlTimestampFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + java.sql.Timestamp value = null; + + try { + java.util.Date date = (java.util.Date) in.readObject(); + value = new java.sql.Timestamp(date.getTime()); + + _unsafe.putObject(obj, _offset, value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static class SqlTimeFieldDeserializer extends FieldDeserializer { + private final Field _field; + private final long _offset; + + @SuppressWarnings("restriction") + SqlTimeFieldDeserializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(_field); + } + + @SuppressWarnings("restriction") + void deserialize(AbstractHessianInput in, Object obj) + throws IOException + { + java.sql.Time value = null; + + try { + java.util.Date date = (java.util.Date) in.readObject(); + value = new java.sql.Time(date.getTime()); + + _unsafe.putObject(obj, _offset, value); + } catch (Exception e) { + logDeserializeError(_field, obj, value, e); + } + } + } + + static void logDeserializeError(Field field, Object obj, Object value, + Throwable e) + throws IOException + { + String fieldName = (field.getDeclaringClass().getName() + + "." + field.getName()); + + if (e instanceof HessianFieldException) + throw (HessianFieldException) e; + else if (e instanceof IOException) + throw new HessianFieldException(fieldName + ": " + e.getMessage(), e); + + if (value != null) + throw new HessianFieldException(fieldName + ": " + value.getClass().getName() + " (" + value + ")" + + " cannot be assigned to '" + field.getType().getName() + "'", e); + else + throw new HessianFieldException(fieldName + ": " + field.getType().getName() + " cannot be assigned from null", e); + } + + static { + boolean isEnabled = false; + + try { + Class<?> unsafe = Class.forName("sun.misc.Unsafe"); + Field theUnsafe = null; + for (Field field : unsafe.getDeclaredFields()) { + if (field.getName().equals("theUnsafe")) + theUnsafe = field; + } + + if (theUnsafe != null) { + theUnsafe.setAccessible(true); + _unsafe = (Unsafe) theUnsafe.get(null); + } + + isEnabled = _unsafe != null; + + String unsafeProp = System.getProperty("com.caucho.hessian.unsafe"); + + if ("false".equals(unsafeProp)) + isEnabled = false; + } catch (Throwable e) { + log.log(Level.FINER, e.toString(), e); + } + + _isEnabled = isEnabled; + } +} diff -Npur hessian-4.0.65-src/com/caucho/hessian/io/NonTransientUnsafeSerializer.java hessian-4.0.65-fix/com/caucho/hessian/io/NonTransientUnsafeSerializer.java --- hessian-4.0.65-src/com/caucho/hessian/io/NonTransientUnsafeSerializer.java 1970-01-01 08:00:00.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/hessian/io/NonTransientUnsafeSerializer.java 2023-08-15 18:39:22.000000000 +0800 @@ -0,0 +1,518 @@ +/** + * + */ +package com.caucho.hessian.io; + +import java.io.IOException; +import java.lang.ref.SoftReference; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.WeakHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import sun.misc.Unsafe; + + + +/** + * @author l65882 + * + */ +public class NonTransientUnsafeSerializer extends AbstractSerializer { + + private static final Logger log + = Logger.getLogger(NonTransientUnsafeSerializer.class.getName()); + + private static boolean _isEnabled; + private static Unsafe _unsafe; + + private static final WeakHashMap<Class<?>,SoftReference<NonTransientUnsafeSerializer>> _serializerMap + = new WeakHashMap<Class<?>,SoftReference<NonTransientUnsafeSerializer>>(); + + private static Object []NULL_ARGS = new Object[0]; + + private Field []_fields; + private FieldSerializer []_fieldSerializers; + + public static boolean isEnabled() + { + return _isEnabled; + } + + public NonTransientUnsafeSerializer(Class<?> cl) + { + introspect(cl); + } + + public static NonTransientUnsafeSerializer create(Class<?> cl) + { + ClassLoader loader = cl.getClassLoader(); + + synchronized (_serializerMap) { + SoftReference<NonTransientUnsafeSerializer> baseRef + = _serializerMap.get(cl); + + NonTransientUnsafeSerializer base = baseRef != null ? baseRef.get() : null; + + if (base == null) { + base = new NonTransientUnsafeSerializer(cl); + baseRef = new SoftReference<NonTransientUnsafeSerializer>(base); + _serializerMap.put(cl, baseRef); + } + + return base; + } + } + + protected void introspect(Class<?> cl) + { + ArrayList<Field> primitiveFields = new ArrayList<Field>(); + ArrayList<Field> compoundFields = new ArrayList<Field>(); + + for (; cl != null; cl = cl.getSuperclass()) { + Field []fields = cl.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + + if (Modifier.isStatic(field.getModifiers())) + continue; + + // XXX: could parameterize the handler to only deal with public + field.setAccessible(true); + + if (field.getType().isPrimitive() + || (field.getType().getName().startsWith("java.lang.") + && ! field.getType().equals(Object.class))) + primitiveFields.add(field); + else + compoundFields.add(field); + } + } + + ArrayList<Field> fields = new ArrayList<Field>(); + fields.addAll(primitiveFields); + fields.addAll(compoundFields); + + _fields = new Field[fields.size()]; + fields.toArray(_fields); + + _fieldSerializers = new FieldSerializer[_fields.length]; + + for (int i = 0; i < _fields.length; i++) { + _fieldSerializers[i] = getFieldSerializer(_fields[i]); + } + } + + @Override + public void writeObject(Object obj, AbstractHessianOutput out) + throws IOException + { + if (out.addRef(obj)) { + return; + } + + Class<?> cl = obj.getClass(); + + int ref = out.writeObjectBegin(cl.getName()); + + if (ref >= 0) { + writeInstance(obj, out); + } + else if (ref == -1) { + writeDefinition20(out); + out.writeObjectBegin(cl.getName()); + writeInstance(obj, out); + } + else { + writeObject10(obj, out); + } + } + + protected void writeObject10(Object obj, AbstractHessianOutput out) + throws IOException + { + for (int i = 0; i < _fields.length; i++) { + Field field = _fields[i]; + + out.writeString(field.getName()); + + _fieldSerializers[i].serialize(out, obj); + } + + out.writeMapEnd(); + } + + private void writeDefinition20(AbstractHessianOutput out) + throws IOException + { + out.writeClassFieldLength(_fields.length); + + for (int i = 0; i < _fields.length; i++) { + Field field = _fields[i]; + + out.writeString(field.getName()); + } + } + + final public void writeInstance(Object obj, AbstractHessianOutput out) + throws IOException + { + try { + FieldSerializer []fieldSerializers = _fieldSerializers; + int length = fieldSerializers.length; + + for (int i = 0; i < length; i++) { + fieldSerializers[i].serialize(out, obj); + } + } catch (RuntimeException e) { + throw new RuntimeException(e.getMessage() + "\n class: " + + obj.getClass().getName() + + " (object=" + obj + ")", + e); + } catch (IOException e) { + throw new IOExceptionWrapper(e.getMessage() + "\n class: " + + obj.getClass().getName() + + " (object=" + obj + ")", + e); + } + } + + private static FieldSerializer getFieldSerializer(Field field) + { + Class<?> type = field.getType(); + + if (boolean.class.equals(type)) { + return new BooleanFieldSerializer(field); + } + else if (byte.class.equals(type)) { + return new ByteFieldSerializer(field); + } + else if (char.class.equals(type)) { + return new CharFieldSerializer(field); + } + else if (short.class.equals(type)) { + return new ShortFieldSerializer(field); + } + else if (int.class.equals(type)) { + return new IntFieldSerializer(field); + } + else if (long.class.equals(type)) { + return new LongFieldSerializer(field); + } + else if (double.class.equals(type)) { + return new DoubleFieldSerializer(field); + } + else if (float.class.equals(type)) { + return new FloatFieldSerializer(field); + } + else if (String.class.equals(type)) { + return new StringFieldSerializer(field); + } + else if (java.util.Date.class.equals(type) + || java.sql.Date.class.equals(type) + || java.sql.Timestamp.class.equals(type) + || java.sql.Time.class.equals(type)) { + return new DateFieldSerializer(field); + } + else + return new ObjectFieldSerializer(field); + } + + abstract static class FieldSerializer { + abstract void serialize(AbstractHessianOutput out, Object obj) + throws IOException; + } + + final static class ObjectFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + ObjectFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + @Override + final void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + try { + Object value = _unsafe.getObject(obj, _offset); + + out.writeObject(value); + } catch (RuntimeException e) { + throw new RuntimeException(e.getMessage() + "\n field: " + + _field.getDeclaringClass().getName() + + '.' + _field.getName(), + e); + } catch (IOException e) { + throw new IOExceptionWrapper(e.getMessage() + "\n field: " + + _field.getDeclaringClass().getName() + + '.' + _field.getName(), + e); + } + } + } + + final static class BooleanFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + BooleanFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + boolean value = _unsafe.getBoolean(obj, _offset); + + out.writeBoolean(value); + } + } + + final static class ByteFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + ByteFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + final void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + int value = _unsafe.getByte(obj, _offset); + + out.writeInt(value); + } + } + + final static class CharFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + CharFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + final void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + char value = _unsafe.getChar(obj, _offset); + + out.writeString(String.valueOf(value)); + } + } + + final static class ShortFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + ShortFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + final void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + int value = _unsafe.getShort(obj, _offset); + + out.writeInt(value); + } + } + + final static class IntFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + IntFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + final void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + int value = _unsafe.getInt(obj, _offset); + + out.writeInt(value); + } + } + + final static class LongFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + LongFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + final void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + long value = _unsafe.getLong(obj, _offset); + + out.writeLong(value); + } + } + + final static class FloatFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + FloatFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + final void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + double value = _unsafe.getFloat(obj, _offset); + + out.writeDouble(value); + } + } + + final static class DoubleFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + DoubleFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + final void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + double value = _unsafe.getDouble(obj, _offset); + + out.writeDouble(value); + } + } + + final static class StringFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + StringFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + @Override + final void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + String value = (String) _unsafe.getObject(obj, _offset); + + out.writeString(value); + } + } + + final static class DateFieldSerializer extends FieldSerializer { + private final Field _field; + private final long _offset; + + DateFieldSerializer(Field field) + { + _field = field; + _offset = _unsafe.objectFieldOffset(field); + + if (_offset == Unsafe.INVALID_FIELD_OFFSET) + throw new IllegalStateException(); + } + + @Override + void serialize(AbstractHessianOutput out, Object obj) + throws IOException + { + java.util.Date value + = (java.util.Date) _unsafe.getObject(obj, _offset); + + if (value == null) + out.writeNull(); + else + out.writeUTCDate(value.getTime()); + } + } + + static { + boolean isEnabled = false; + + try { + Class unsafe = Class.forName("sun.misc.Unsafe"); + Field theUnsafe = null; + for (Field field : unsafe.getDeclaredFields()) { + if (field.getName().equals("theUnsafe")) + theUnsafe = field; + } + + if (theUnsafe != null) { + theUnsafe.setAccessible(true); + _unsafe = (Unsafe) theUnsafe.get(null); + } + + isEnabled = _unsafe != null; + + String unsafeProp = System.getProperty("com.caucho.hessian.unsafe"); + + if ("false".equals(unsafeProp)) + isEnabled = false; + } catch (Throwable e) { + log.log(Level.FINER, e.toString(), e); + } + + _isEnabled = isEnabled; + } + +} diff -Npur hessian-4.0.65-src/com/caucho/hessian/io/SerializerFactory.java hessian-4.0.65-fix/com/caucho/hessian/io/SerializerFactory.java --- hessian-4.0.65-src/com/caucho/hessian/io/SerializerFactory.java 2020-07-23 12:51:28.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/hessian/io/SerializerFactory.java 2023-08-15 18:39:22.000000000 +0800 @@ -1,804 +1,810 @@ -/* - * Copyright (c) 2001-2008 Caucho Technology, Inc. All rights reserved. - * - * The Apache Software License, Version 1.1 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Caucho Technology (http://www.caucho.com/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "Burlap", "Resin", and "Caucho" must not be used to - * endorse or promote products derived from this software without prior - * written permission. For written permission, please contact - * info@caucho.com. - * - * 5. Products derived from this software may not be called "Resin" - * nor may "Resin" appear in their names without prior written - * permission of Caucho Technology. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @author Scott Ferguson - */ - -package com.caucho.hessian.io; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.lang.annotation.Annotation; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.WeakHashMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.caucho.burlap.io.BurlapRemoteObject; - -/** - * Factory for returning serialization methods. - */ -public class SerializerFactory extends AbstractSerializerFactory -{ - private static final Logger log - = Logger.getLogger(SerializerFactory.class.getName()); - - private static final Deserializer OBJECT_DESERIALIZER - = new BasicDeserializer(BasicDeserializer.OBJECT); - - private static final ClassLoader _systemClassLoader; - - private static final HashMap _staticTypeMap; - - private static final - WeakHashMap<ClassLoader,SoftReference<SerializerFactory>> - _defaultFactoryRefMap - = new WeakHashMap<ClassLoader,SoftReference<SerializerFactory>>(); - - private ContextSerializerFactory _contextFactory; - private WeakReference<ClassLoader> _loaderRef; - - protected Serializer _defaultSerializer; - - // Additional factories - protected ArrayList _factories = new ArrayList(); - - protected CollectionSerializer _collectionSerializer; - protected MapSerializer _mapSerializer; - - private Deserializer _hashMapDeserializer; - private Deserializer _arrayListDeserializer; - private Map _cachedSerializerMap; - private Map _cachedDeserializerMap; - private HashMap _cachedTypeDeserializerMap; - - private boolean _isAllowNonSerializable; - private boolean _isEnableUnsafeSerializer - = (UnsafeSerializer.isEnabled() - && UnsafeDeserializer.isEnabled()); - - private FieldDeserializer2Factory _fieldDeserializerFactory; - - private ClassFactory _classFactory; - - public SerializerFactory() - { - this(Thread.currentThread().getContextClassLoader()); - } - - public SerializerFactory(ClassLoader loader) - { - _loaderRef = new WeakReference<ClassLoader>(loader); - - _contextFactory = ContextSerializerFactory.create(loader); - - if (_isEnableUnsafeSerializer) { - _fieldDeserializerFactory = new FieldDeserializer2FactoryUnsafe(); - } - else { - _fieldDeserializerFactory = new FieldDeserializer2Factory(); - } - } - - public static SerializerFactory createDefault() - { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - - synchronized (_defaultFactoryRefMap) { - SoftReference<SerializerFactory> factoryRef - = _defaultFactoryRefMap.get(loader); - - SerializerFactory factory = null; - - if (factoryRef != null) - factory = factoryRef.get(); - - if (factory == null) { - factory = new SerializerFactory(); - - factoryRef = new SoftReference<SerializerFactory>(factory); - - _defaultFactoryRefMap.put(loader, factoryRef); - } - - return factory; - } - } - - public ClassLoader getClassLoader() - { - return _loaderRef.get(); - } - - /** - * Set true if the collection serializer should send the java type. - */ - public void setSendCollectionType(boolean isSendType) - { - if (_collectionSerializer == null) - _collectionSerializer = new CollectionSerializer(); - - _collectionSerializer.setSendJavaType(isSendType); - - if (_mapSerializer == null) - _mapSerializer = new MapSerializer(); - - _mapSerializer.setSendJavaType(isSendType); - } - - /** - * Adds a factory. - */ - public void addFactory(AbstractSerializerFactory factory) - { - _factories.add(factory); - } - - /** - * If true, non-serializable objects are allowed. - */ - public void setAllowNonSerializable(boolean allow) - { - _isAllowNonSerializable = allow; - } - - /** - * If true, non-serializable objects are allowed. - */ - public boolean isAllowNonSerializable() - { - return _isAllowNonSerializable; - } - - /** - * Returns the serializer for a class. - * - * @param cl the class of the object that needs to be serialized. - * - * @return a serializer object for the serialization. - */ - public Serializer getObjectSerializer(Class<?> cl) - throws HessianProtocolException - { - Serializer serializer = getSerializer(cl); - - if (serializer instanceof ObjectSerializer) - return ((ObjectSerializer) serializer).getObjectSerializer(); - else - return serializer; - } - - public Class<?> loadSerializedClass(String className) - throws ClassNotFoundException - { - return getClassFactory().load(className); - } - - public ClassFactory getClassFactory() - { - synchronized (this) { - if (_classFactory == null) { - _classFactory = new ClassFactory(getClassLoader()); - } - - return _classFactory; - } - } - - public FieldDeserializer2Factory getFieldDeserializerFactory() - { - return _fieldDeserializerFactory; - } - - /** - * Returns the serializer for a class. - * - * @param cl the class of the object that needs to be serialized. - * - * @return a serializer object for the serialization. - */ - public Serializer getSerializer(Class cl) - throws HessianProtocolException - { - Serializer serializer; - - if (_cachedSerializerMap != null) { - serializer = (Serializer) _cachedSerializerMap.get(cl); - - if (serializer != null) { - return serializer; - } - } - - serializer = loadSerializer(cl); - - if (_cachedSerializerMap == null) - _cachedSerializerMap = new ConcurrentHashMap(8); - - _cachedSerializerMap.put(cl, serializer); - - return serializer; - } - - protected Serializer loadSerializer(Class<?> cl) - throws HessianProtocolException - { - Serializer serializer = null; - - for (int i = 0; - _factories != null && i < _factories.size(); - i++) { - AbstractSerializerFactory factory; - - factory = (AbstractSerializerFactory) _factories.get(i); - - serializer = factory.getSerializer(cl); - - if (serializer != null) - return serializer; - } - - serializer = _contextFactory.getSerializer(cl.getName()); - - if (serializer != null) - return serializer; - - ClassLoader loader = cl.getClassLoader(); - - if (loader == null) - loader = _systemClassLoader; - - ContextSerializerFactory factory = null; - - factory = ContextSerializerFactory.create(loader); - - serializer = factory.getCustomSerializer(cl); - - if (serializer != null) { - return serializer; - } - - if (HessianRemoteObject.class.isAssignableFrom(cl)) { - return new RemoteSerializer(); - } - else if (BurlapRemoteObject.class.isAssignableFrom(cl)) { - return new RemoteSerializer(); - } - else if (InetAddress.class.isAssignableFrom(cl)) { - return InetAddressSerializer.create(); - } - else if (JavaSerializer.getWriteReplace(cl) != null) { - Serializer baseSerializer = getDefaultSerializer(cl); - - return new WriteReplaceSerializer(cl, getClassLoader(), baseSerializer); - } - else if (Map.class.isAssignableFrom(cl)) { - if (_mapSerializer == null) - _mapSerializer = new MapSerializer(); - - return _mapSerializer; - } - else if (Collection.class.isAssignableFrom(cl)) { - if (_collectionSerializer == null) { - _collectionSerializer = new CollectionSerializer(); - } - - return _collectionSerializer; - } - - else if (cl.isArray()) { - return new ArraySerializer(); - } - - else if (Throwable.class.isAssignableFrom(cl)) - return new ThrowableSerializer(getDefaultSerializer(cl)); - - else if (InputStream.class.isAssignableFrom(cl)) - return new InputStreamSerializer(); - - else if (Iterator.class.isAssignableFrom(cl)) - return IteratorSerializer.create(); - - else if (Calendar.class.isAssignableFrom(cl)) - return CalendarSerializer.SER; - - else if (Enumeration.class.isAssignableFrom(cl)) - return EnumerationSerializer.create(); - - else if (Enum.class.isAssignableFrom(cl)) - return new EnumSerializer(cl); - - else if (Annotation.class.isAssignableFrom(cl)) - return new AnnotationSerializer(cl); - - return getDefaultSerializer(cl); - } - - /** - * Returns the default serializer for a class that isn't matched - * directly. Application can override this method to produce - * bean-style serialization instead of field serialization. - * - * @param cl the class of the object that needs to be serialized. - * - * @return a serializer object for the serialization. - */ - protected Serializer getDefaultSerializer(Class cl) - { - if (_defaultSerializer != null) - return _defaultSerializer; - - if (! Serializable.class.isAssignableFrom(cl) - && ! _isAllowNonSerializable) { - throw new IllegalStateException("Serialized class " + cl.getName() + " must implement java.io.Serializable"); - } - - if (_isEnableUnsafeSerializer - && JavaSerializer.getWriteReplace(cl) == null) { - return UnsafeSerializer.create(cl); - } - else - return JavaSerializer.create(cl); - } - - /** - * Returns the deserializer for a class. - * - * @param cl the class of the object that needs to be deserialized. - * - * @return a deserializer object for the serialization. - */ - public Deserializer getDeserializer(Class cl) - throws HessianProtocolException - { - Deserializer deserializer; - - if (_cachedDeserializerMap != null) { - deserializer = (Deserializer) _cachedDeserializerMap.get(cl); - - if (deserializer != null) - return deserializer; - } - - deserializer = loadDeserializer(cl); - - if (_cachedDeserializerMap == null) - _cachedDeserializerMap = new ConcurrentHashMap(8); - - _cachedDeserializerMap.put(cl, deserializer); - - return deserializer; - } - - protected Deserializer loadDeserializer(Class cl) - throws HessianProtocolException - { - Deserializer deserializer = null; - - for (int i = 0; - deserializer == null && _factories != null && i < _factories.size(); - i++) { - AbstractSerializerFactory factory; - factory = (AbstractSerializerFactory) _factories.get(i); - - deserializer = factory.getDeserializer(cl); - } - - if (deserializer != null) - return deserializer; - - // XXX: need test - deserializer = _contextFactory.getDeserializer(cl.getName()); - - if (deserializer != null) - return deserializer; - - ContextSerializerFactory factory = null; - - if (cl.getClassLoader() != null) - factory = ContextSerializerFactory.create(cl.getClassLoader()); - else - factory = ContextSerializerFactory.create(_systemClassLoader); - - deserializer = factory.getDeserializer(cl.getName()); - - if (deserializer != null) - return deserializer; - - deserializer = factory.getCustomDeserializer(cl); - - if (deserializer != null) - return deserializer; - - if (Collection.class.isAssignableFrom(cl)) - deserializer = new CollectionDeserializer(cl); - - else if (Map.class.isAssignableFrom(cl)) { - deserializer = new MapDeserializer(cl); - } - else if (Iterator.class.isAssignableFrom(cl)) { - deserializer = IteratorDeserializer.create(); - } - else if (Annotation.class.isAssignableFrom(cl)) { - deserializer = new AnnotationDeserializer(cl); - } - else if (cl.isInterface()) { - deserializer = new ObjectDeserializer(cl); - } - else if (cl.isArray()) { - deserializer = new ArrayDeserializer(cl.getComponentType()); - } - else if (Enumeration.class.isAssignableFrom(cl)) { - deserializer = EnumerationDeserializer.create(); - } - else if (Enum.class.isAssignableFrom(cl)) - deserializer = new EnumDeserializer(cl); - - else if (Class.class.equals(cl)) - deserializer = new ClassDeserializer(getClassLoader()); - - else - deserializer = getDefaultDeserializer(cl); - - return deserializer; - } - - /** - * Returns a custom serializer the class - * - * @param cl the class of the object that needs to be serialized. - * - * @return a serializer object for the serialization. - */ - protected Deserializer getCustomDeserializer(Class cl) - { - try { - Class serClass = Class.forName(cl.getName() + "HessianDeserializer", - false, cl.getClassLoader()); - - Deserializer ser = (Deserializer) serClass.newInstance(); - - return ser; - } catch (ClassNotFoundException e) { - log.log(Level.FINEST, e.toString(), e); - - return null; - } catch (Exception e) { - log.log(Level.FINE, e.toString(), e); - - return null; - } - } - - /** - * Returns the default serializer for a class that isn't matched - * directly. Application can override this method to produce - * bean-style serialization instead of field serialization. - * - * @param cl the class of the object that needs to be serialized. - * - * @return a serializer object for the serialization. - */ - protected Deserializer getDefaultDeserializer(Class cl) - { - if (InputStream.class.equals(cl)) - return InputStreamDeserializer.DESER; - - if (_isEnableUnsafeSerializer) { - return new UnsafeDeserializer(cl, _fieldDeserializerFactory); - } - else - return new JavaDeserializer(cl, _fieldDeserializerFactory); - } - - /** - * Reads the object as a list. - */ - public Object readList(AbstractHessianInput in, int length, String type) - throws HessianProtocolException, IOException - { - Deserializer deserializer = getDeserializer(type); - - if (deserializer != null) - return deserializer.readList(in, length); - else - return new CollectionDeserializer(ArrayList.class).readList(in, length); - } - - /** - * Reads the object as a map. - */ - public Object readMap(AbstractHessianInput in, String type) - throws HessianProtocolException, IOException - { - Deserializer deserializer = getDeserializer(type); - - if (deserializer != null) - return deserializer.readMap(in); - else if (_hashMapDeserializer != null) - return _hashMapDeserializer.readMap(in); - else { - _hashMapDeserializer = new MapDeserializer(HashMap.class); - - return _hashMapDeserializer.readMap(in); - } - } - - /** - * Reads the object as a map. - */ - public Object readObject(AbstractHessianInput in, - String type, - String []fieldNames) - throws HessianProtocolException, IOException - { - Deserializer deserializer = getDeserializer(type); - - if (deserializer != null) - return deserializer.readObject(in, fieldNames); - else if (_hashMapDeserializer != null) - return _hashMapDeserializer.readObject(in, fieldNames); - else { - _hashMapDeserializer = new MapDeserializer(HashMap.class); - - return _hashMapDeserializer.readObject(in, fieldNames); - } - } - - /** - * Reads the object as a map. - */ - public Deserializer getObjectDeserializer(String type, Class cl) - throws HessianProtocolException - { - Deserializer reader = getObjectDeserializer(type); - - if (cl == null - || cl.equals(reader.getType()) - || cl.isAssignableFrom(reader.getType()) - || reader.isReadResolve() - || HessianHandle.class.isAssignableFrom(reader.getType())) { - return reader; - } - - if (log.isLoggable(Level.FINE)) { - log.fine("hessian: expected deserializer '" + cl.getName() + "' at '" + type + "' (" - + reader.getType().getName() + ")"); - } - - return getDeserializer(cl); - } - - /** - * Reads the object as a map. - */ - public Deserializer getObjectDeserializer(String type) - throws HessianProtocolException - { - Deserializer deserializer = getDeserializer(type); - - if (deserializer != null) - return deserializer; - else if (_hashMapDeserializer != null) - return _hashMapDeserializer; - else { - _hashMapDeserializer = new MapDeserializer(HashMap.class); - - return _hashMapDeserializer; - } - } - - /** - * Reads the object as a map. - */ - public Deserializer getListDeserializer(String type, Class cl) - throws HessianProtocolException - { - Deserializer reader = getListDeserializer(type); - - if (cl == null - || cl.equals(reader.getType()) - || cl.isAssignableFrom(reader.getType())) { - return reader; - } - - if (log.isLoggable(Level.FINE)) { - log.fine("hessian: expected '" + cl.getName() + "' at '" + type + "' (" - + reader.getType().getName() + ")"); - } - - return getDeserializer(cl); - } - - /** - * Reads the object as a map. - */ - public Deserializer getListDeserializer(String type) - throws HessianProtocolException - { - Deserializer deserializer = getDeserializer(type); - - if (deserializer != null) - return deserializer; - else if (_arrayListDeserializer != null) - return _arrayListDeserializer; - else { - _arrayListDeserializer = new CollectionDeserializer(ArrayList.class); - - return _arrayListDeserializer; - } - } - - /** - * Returns a deserializer based on a string type. - */ - public Deserializer getDeserializer(String type) - throws HessianProtocolException - { - if (type == null || type.equals("")) - return null; - - Deserializer deserializer; - - if (_cachedTypeDeserializerMap != null) { - synchronized (_cachedTypeDeserializerMap) { - deserializer = (Deserializer) _cachedTypeDeserializerMap.get(type); - } - - if (deserializer != null) - return deserializer; - } - - - deserializer = (Deserializer) _staticTypeMap.get(type); - if (deserializer != null) - return deserializer; - - if (type.startsWith("[")) { - Deserializer subDeserializer = getDeserializer(type.substring(1)); - - if (subDeserializer != null) - deserializer = new ArrayDeserializer(subDeserializer.getType()); - else - deserializer = new ArrayDeserializer(Object.class); - } - else { - try { - //Class cl = Class.forName(type, false, getClassLoader()); - - Class cl = loadSerializedClass(type); - - deserializer = getDeserializer(cl); - } catch (Exception e) { - log.warning("Hessian/Burlap: '" + type + "' is an unknown class in " + getClassLoader() + ":\n" + e); - - log.log(Level.FINER, e.toString(), e); - } - } - - if (deserializer != null) { - if (_cachedTypeDeserializerMap == null) - _cachedTypeDeserializerMap = new HashMap(8); - - synchronized (_cachedTypeDeserializerMap) { - _cachedTypeDeserializerMap.put(type, deserializer); - } - } - - return deserializer; - } - - private static void addBasic(Class<?> cl, String typeName, int type) - { - Deserializer deserializer = new BasicDeserializer(type); - - _staticTypeMap.put(typeName, deserializer); - } - - static { - _staticTypeMap = new HashMap(); - - addBasic(void.class, "void", BasicSerializer.NULL); - - addBasic(Boolean.class, "boolean", BasicSerializer.BOOLEAN); - addBasic(Byte.class, "byte", BasicSerializer.BYTE); - addBasic(Short.class, "short", BasicSerializer.SHORT); - addBasic(Integer.class, "int", BasicSerializer.INTEGER); - addBasic(Long.class, "long", BasicSerializer.LONG); - addBasic(Float.class, "float", BasicSerializer.FLOAT); - addBasic(Double.class, "double", BasicSerializer.DOUBLE); - addBasic(Character.class, "char", BasicSerializer.CHARACTER_OBJECT); - addBasic(String.class, "string", BasicSerializer.STRING); - addBasic(StringBuilder.class, "string", BasicSerializer.STRING_BUILDER); - addBasic(Object.class, "object", BasicSerializer.OBJECT); - addBasic(java.util.Date.class, "date", BasicSerializer.DATE); - - addBasic(boolean.class, "boolean", BasicSerializer.BOOLEAN); - addBasic(byte.class, "byte", BasicSerializer.BYTE); - addBasic(short.class, "short", BasicSerializer.SHORT); - addBasic(int.class, "int", BasicSerializer.INTEGER); - addBasic(long.class, "long", BasicSerializer.LONG); - addBasic(float.class, "float", BasicSerializer.FLOAT); - addBasic(double.class, "double", BasicSerializer.DOUBLE); - addBasic(char.class, "char", BasicSerializer.CHARACTER); - - addBasic(boolean[].class, "[boolean", BasicSerializer.BOOLEAN_ARRAY); - addBasic(byte[].class, "[byte", BasicSerializer.BYTE_ARRAY); - addBasic(short[].class, "[short", BasicSerializer.SHORT_ARRAY); - addBasic(int[].class, "[int", BasicSerializer.INTEGER_ARRAY); - addBasic(long[].class, "[long", BasicSerializer.LONG_ARRAY); - addBasic(float[].class, "[float", BasicSerializer.FLOAT_ARRAY); - addBasic(double[].class, "[double", BasicSerializer.DOUBLE_ARRAY); - addBasic(char[].class, "[char", BasicSerializer.CHARACTER_ARRAY); - addBasic(String[].class, "[string", BasicSerializer.STRING_ARRAY); - addBasic(Object[].class, "[object", BasicSerializer.OBJECT_ARRAY); - - Deserializer objectDeserializer = new JavaDeserializer(Object.class, new FieldDeserializer2Factory()); - _staticTypeMap.put("object", objectDeserializer); - _staticTypeMap.put(HessianRemote.class.getName(), - RemoteDeserializer.DESER); - - - ClassLoader systemClassLoader = null; - try { - systemClassLoader = ClassLoader.getSystemClassLoader(); - } catch (Exception e) { - } - - _systemClassLoader = systemClassLoader; - } -} +/* + * Copyright (c) 2001-2008 Caucho Technology, Inc. All rights reserved. + * + * The Apache Software License, Version 1.1 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Caucho Technology (http://www.caucho.com/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Burlap", "Resin", and "Caucho" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * info@caucho.com. + * + * 5. Products derived from this software may not be called "Resin" + * nor may "Resin" appear in their names without prior written + * permission of Caucho Technology. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Scott Ferguson + */ + +package com.caucho.hessian.io; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.lang.annotation.Annotation; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.net.InetAddress; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.caucho.burlap.io.BurlapRemoteObject; + +/** + * Factory for returning serialization methods. + */ +public class SerializerFactory extends AbstractSerializerFactory +{ + private static final Logger log + = Logger.getLogger(SerializerFactory.class.getName()); + + private static final Deserializer OBJECT_DESERIALIZER + = new BasicDeserializer(BasicDeserializer.OBJECT); + + private static final ClassLoader _systemClassLoader; + + private static final HashMap _staticTypeMap; + + private static final + WeakHashMap<ClassLoader,SoftReference<SerializerFactory>> + _defaultFactoryRefMap + = new WeakHashMap<ClassLoader,SoftReference<SerializerFactory>>(); + + private ContextSerializerFactory _contextFactory; + private WeakReference<ClassLoader> _loaderRef; + + protected Serializer _defaultSerializer; + + // Additional factories + protected ArrayList _factories = new ArrayList(); + + protected CollectionSerializer _collectionSerializer; + protected MapSerializer _mapSerializer; + + private Deserializer _hashMapDeserializer; + private Deserializer _arrayListDeserializer; + private Map _cachedSerializerMap; + private Map _cachedDeserializerMap; + private HashMap _cachedTypeDeserializerMap; + + private boolean _isAllowNonSerializable; + private boolean _isEnableUnsafeSerializer + = (UnsafeSerializer.isEnabled() + && UnsafeDeserializer.isEnabled()); + + private FieldDeserializer2Factory _fieldDeserializerFactory; + + private ClassFactory _classFactory; + + public SerializerFactory() + { + this(Thread.currentThread().getContextClassLoader()); + } + + public SerializerFactory(ClassLoader loader) + { + _loaderRef = new WeakReference<ClassLoader>(loader); + + _contextFactory = ContextSerializerFactory.create(loader); + + if (_isEnableUnsafeSerializer) { + _fieldDeserializerFactory = new FieldDeserializer2FactoryUnsafe(); + } + else { + _fieldDeserializerFactory = new FieldDeserializer2Factory(); + } + } + + public static SerializerFactory createDefault() + { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + + synchronized (_defaultFactoryRefMap) { + SoftReference<SerializerFactory> factoryRef + = _defaultFactoryRefMap.get(loader); + + SerializerFactory factory = null; + + if (factoryRef != null) + factory = factoryRef.get(); + + if (factory == null) { + factory = new SerializerFactory(); + + factoryRef = new SoftReference<SerializerFactory>(factory); + + _defaultFactoryRefMap.put(loader, factoryRef); + } + + return factory; + } + } + + public ClassLoader getClassLoader() + { + return _loaderRef.get(); + } + + /** + * Set true if the collection serializer should send the java type. + */ + public void setSendCollectionType(boolean isSendType) + { + if (_collectionSerializer == null) + _collectionSerializer = new CollectionSerializer(); + + _collectionSerializer.setSendJavaType(isSendType); + + if (_mapSerializer == null) + _mapSerializer = new MapSerializer(); + + _mapSerializer.setSendJavaType(isSendType); + } + + /** + * Adds a factory. + */ + public void addFactory(AbstractSerializerFactory factory) + { + _factories.add(factory); + } + + /** + * If true, non-serializable objects are allowed. + */ + public void setAllowNonSerializable(boolean allow) + { + _isAllowNonSerializable = allow; + } + + /** + * If true, non-serializable objects are allowed. + */ + public boolean isAllowNonSerializable() + { + return _isAllowNonSerializable; + } + + /** + * Returns the serializer for a class. + * + * @param cl the class of the object that needs to be serialized. + * + * @return a serializer object for the serialization. + */ + public Serializer getObjectSerializer(Class<?> cl) + throws HessianProtocolException + { + Serializer serializer = getSerializer(cl); + + if (serializer instanceof ObjectSerializer) + return ((ObjectSerializer) serializer).getObjectSerializer(); + else + return serializer; + } + + public Class<?> loadSerializedClass(String className) + throws ClassNotFoundException + { + return getClassFactory().load(className); + } + + public ClassFactory getClassFactory() + { + synchronized (this) { + if (_classFactory == null) { + _classFactory = new ClassFactory(getClassLoader()); + } + + return _classFactory; + } + } + + public FieldDeserializer2Factory getFieldDeserializerFactory() + { + return _fieldDeserializerFactory; + } + + /** + * Returns the serializer for a class. + * + * @param cl the class of the object that needs to be serialized. + * + * @return a serializer object for the serialization. + */ + public Serializer getSerializer(Class cl) + throws HessianProtocolException + { + Serializer serializer; + + if (_cachedSerializerMap != null) { + serializer = (Serializer) _cachedSerializerMap.get(cl); + + if (serializer != null) { + return serializer; + } + } + + serializer = loadSerializer(cl); + + if (_cachedSerializerMap == null) + _cachedSerializerMap = new ConcurrentHashMap(8); + + _cachedSerializerMap.put(cl, serializer); + + return serializer; + } + + protected Serializer loadSerializer(Class<?> cl) + throws HessianProtocolException + { + Serializer serializer = null; + + for (int i = 0; + _factories != null && i < _factories.size(); + i++) { + AbstractSerializerFactory factory; + + factory = (AbstractSerializerFactory) _factories.get(i); + + serializer = factory.getSerializer(cl); + + if (serializer != null) + return serializer; + } + + serializer = _contextFactory.getSerializer(cl.getName()); + + if (serializer != null) + return serializer; + + ClassLoader loader = cl.getClassLoader(); + + if (loader == null) + loader = _systemClassLoader; + + ContextSerializerFactory factory = null; + + factory = ContextSerializerFactory.create(loader); + + serializer = factory.getCustomSerializer(cl); + + if (serializer != null) { + return serializer; + } + + if (HessianRemoteObject.class.isAssignableFrom(cl)) { + return new RemoteSerializer(); + } + else if (BurlapRemoteObject.class.isAssignableFrom(cl)) { + return new RemoteSerializer(); + } + else if (InetAddress.class.isAssignableFrom(cl)) { + return InetAddressSerializer.create(); + } + else if (JavaSerializer.getWriteReplace(cl) != null) { + Serializer baseSerializer = getDefaultSerializer(cl); + + return new WriteReplaceSerializer(cl, getClassLoader(), baseSerializer); + } + else if (Map.class.isAssignableFrom(cl)) { + if (_mapSerializer == null) + _mapSerializer = new MapSerializer(); + + return _mapSerializer; + } + else if (Collection.class.isAssignableFrom(cl)) { + if (_collectionSerializer == null) { + _collectionSerializer = new CollectionSerializer(); + } + + return _collectionSerializer; + } + + else if (cl.isArray()) { + return new ArraySerializer(); + } + + else if (Throwable.class.isAssignableFrom(cl)) + return new ThrowableSerializer(getDefaultSerializer(cl)); + + else if (InputStream.class.isAssignableFrom(cl)) + return new InputStreamSerializer(); + + else if (Iterator.class.isAssignableFrom(cl)) + return IteratorSerializer.create(); + + else if (Calendar.class.isAssignableFrom(cl)) + return CalendarSerializer.SER; + + else if (Enumeration.class.isAssignableFrom(cl)) + return EnumerationSerializer.create(); + + else if (Enum.class.isAssignableFrom(cl)) + return new EnumSerializer(cl); + + else if (Annotation.class.isAssignableFrom(cl)) + return new AnnotationSerializer(cl); + + else if (BigDecimal.class.isAssignableFrom(cl)) + return new NonTransientUnsafeSerializer(cl); + else + return getDefaultSerializer(cl); + } + + /** + * Returns the default serializer for a class that isn't matched + * directly. Application can override this method to produce + * bean-style serialization instead of field serialization. + * + * @param cl the class of the object that needs to be serialized. + * + * @return a serializer object for the serialization. + */ + protected Serializer getDefaultSerializer(Class cl) + { + if (_defaultSerializer != null) + return _defaultSerializer; + + if (! Serializable.class.isAssignableFrom(cl) + && ! _isAllowNonSerializable) { + throw new IllegalStateException("Serialized class " + cl.getName() + " must implement java.io.Serializable"); + } + + if (_isEnableUnsafeSerializer + && JavaSerializer.getWriteReplace(cl) == null) { + return UnsafeSerializer.create(cl); + } + else + return JavaSerializer.create(cl); + } + + /** + * Returns the deserializer for a class. + * + * @param cl the class of the object that needs to be deserialized. + * + * @return a deserializer object for the serialization. + */ + public Deserializer getDeserializer(Class cl) + throws HessianProtocolException + { + Deserializer deserializer; + + if (_cachedDeserializerMap != null) { + deserializer = (Deserializer) _cachedDeserializerMap.get(cl); + + if (deserializer != null) + return deserializer; + } + + deserializer = loadDeserializer(cl); + + if (_cachedDeserializerMap == null) + _cachedDeserializerMap = new ConcurrentHashMap(8); + + _cachedDeserializerMap.put(cl, deserializer); + + return deserializer; + } + + protected Deserializer loadDeserializer(Class cl) + throws HessianProtocolException + { + Deserializer deserializer = null; + + for (int i = 0; + deserializer == null && _factories != null && i < _factories.size(); + i++) { + AbstractSerializerFactory factory; + factory = (AbstractSerializerFactory) _factories.get(i); + + deserializer = factory.getDeserializer(cl); + } + + if (deserializer != null) + return deserializer; + + // XXX: need test + deserializer = _contextFactory.getDeserializer(cl.getName()); + + if (deserializer != null) + return deserializer; + + ContextSerializerFactory factory = null; + + if (cl.getClassLoader() != null) + factory = ContextSerializerFactory.create(cl.getClassLoader()); + else + factory = ContextSerializerFactory.create(_systemClassLoader); + + deserializer = factory.getDeserializer(cl.getName()); + + if (deserializer != null) + return deserializer; + + deserializer = factory.getCustomDeserializer(cl); + + if (deserializer != null) + return deserializer; + + if (Collection.class.isAssignableFrom(cl)) + deserializer = new CollectionDeserializer(cl); + + else if (Map.class.isAssignableFrom(cl)) { + deserializer = new MapDeserializer(cl); + } + else if (Iterator.class.isAssignableFrom(cl)) { + deserializer = IteratorDeserializer.create(); + } + else if (Annotation.class.isAssignableFrom(cl)) { + deserializer = new AnnotationDeserializer(cl); + } + else if (cl.isInterface()) { + deserializer = new ObjectDeserializer(cl); + } + else if (cl.isArray()) { + deserializer = new ArrayDeserializer(cl.getComponentType()); + } + else if (Enumeration.class.isAssignableFrom(cl)) { + deserializer = EnumerationDeserializer.create(); + } + else if (Enum.class.isAssignableFrom(cl)){ + deserializer = new EnumDeserializer(cl); + } + else if (Class.class.equals(cl)) + deserializer = new ClassDeserializer(getClassLoader()); + + else if (BigDecimal.class.equals(cl)) + deserializer = new NonTransientUnsafeDeserializer(cl); + else + deserializer = getDefaultDeserializer(cl); + + return deserializer; + } + + /** + * Returns a custom serializer the class + * + * @param cl the class of the object that needs to be serialized. + * + * @return a serializer object for the serialization. + */ + protected Deserializer getCustomDeserializer(Class cl) + { + try { + Class serClass = Class.forName(cl.getName() + "HessianDeserializer", + false, cl.getClassLoader()); + + Deserializer ser = (Deserializer) serClass.newInstance(); + + return ser; + } catch (ClassNotFoundException e) { + log.log(Level.FINEST, e.toString(), e); + + return null; + } catch (Exception e) { + log.log(Level.FINE, e.toString(), e); + + return null; + } + } + + /** + * Returns the default serializer for a class that isn't matched + * directly. Application can override this method to produce + * bean-style serialization instead of field serialization. + * + * @param cl the class of the object that needs to be serialized. + * + * @return a serializer object for the serialization. + */ + protected Deserializer getDefaultDeserializer(Class cl) + { + if (InputStream.class.equals(cl)) + return InputStreamDeserializer.DESER; + + if (_isEnableUnsafeSerializer) { + return new UnsafeDeserializer(cl, _fieldDeserializerFactory); + } + else + return new JavaDeserializer(cl, _fieldDeserializerFactory); + } + + /** + * Reads the object as a list. + */ + public Object readList(AbstractHessianInput in, int length, String type) + throws HessianProtocolException, IOException + { + Deserializer deserializer = getDeserializer(type); + + if (deserializer != null) + return deserializer.readList(in, length); + else + return new CollectionDeserializer(ArrayList.class).readList(in, length); + } + + /** + * Reads the object as a map. + */ + public Object readMap(AbstractHessianInput in, String type) + throws HessianProtocolException, IOException + { + Deserializer deserializer = getDeserializer(type); + + if (deserializer != null) + return deserializer.readMap(in); + else if (_hashMapDeserializer != null) + return _hashMapDeserializer.readMap(in); + else { + _hashMapDeserializer = new MapDeserializer(HashMap.class); + + return _hashMapDeserializer.readMap(in); + } + } + + /** + * Reads the object as a map. + */ + public Object readObject(AbstractHessianInput in, + String type, + String []fieldNames) + throws HessianProtocolException, IOException + { + Deserializer deserializer = getDeserializer(type); + + if (deserializer != null) + return deserializer.readObject(in, fieldNames); + else if (_hashMapDeserializer != null) + return _hashMapDeserializer.readObject(in, fieldNames); + else { + _hashMapDeserializer = new MapDeserializer(HashMap.class); + + return _hashMapDeserializer.readObject(in, fieldNames); + } + } + + /** + * Reads the object as a map. + */ + public Deserializer getObjectDeserializer(String type, Class cl) + throws HessianProtocolException + { + Deserializer reader = getObjectDeserializer(type); + + if (cl == null + || cl.equals(reader.getType()) + || cl.isAssignableFrom(reader.getType()) + || reader.isReadResolve() + || HessianHandle.class.isAssignableFrom(reader.getType())) { + return reader; + } + + if (log.isLoggable(Level.FINE)) { + log.fine("hessian: expected deserializer '" + cl.getName() + "' at '" + type + "' (" + + reader.getType().getName() + ")"); + } + + return getDeserializer(cl); + } + + /** + * Reads the object as a map. + */ + public Deserializer getObjectDeserializer(String type) + throws HessianProtocolException + { + Deserializer deserializer = getDeserializer(type); + + if (deserializer != null) + return deserializer; + else if (_hashMapDeserializer != null) + return _hashMapDeserializer; + else { + _hashMapDeserializer = new MapDeserializer(HashMap.class); + + return _hashMapDeserializer; + } + } + + /** + * Reads the object as a map. + */ + public Deserializer getListDeserializer(String type, Class cl) + throws HessianProtocolException + { + Deserializer reader = getListDeserializer(type); + + if (cl == null + || cl.equals(reader.getType()) + || cl.isAssignableFrom(reader.getType())) { + return reader; + } + + if (log.isLoggable(Level.FINE)) { + log.fine("hessian: expected '" + cl.getName() + "' at '" + type + "' (" + + reader.getType().getName() + ")"); + } + + return getDeserializer(cl); + } + + /** + * Reads the object as a map. + */ + public Deserializer getListDeserializer(String type) + throws HessianProtocolException + { + Deserializer deserializer = getDeserializer(type); + + if (deserializer != null) + return deserializer; + else if (_arrayListDeserializer != null) + return _arrayListDeserializer; + else { + _arrayListDeserializer = new CollectionDeserializer(ArrayList.class); + + return _arrayListDeserializer; + } + } + + /** + * Returns a deserializer based on a string type. + */ + public Deserializer getDeserializer(String type) + throws HessianProtocolException + { + if (type == null || type.equals("")) + return null; + + Deserializer deserializer; + + if (_cachedTypeDeserializerMap != null) { + synchronized (_cachedTypeDeserializerMap) { + deserializer = (Deserializer) _cachedTypeDeserializerMap.get(type); + } + + if (deserializer != null) + return deserializer; + } + + + deserializer = (Deserializer) _staticTypeMap.get(type); + if (deserializer != null) + return deserializer; + + if (type.startsWith("[")) { + Deserializer subDeserializer = getDeserializer(type.substring(1)); + + if (subDeserializer != null) + deserializer = new ArrayDeserializer(subDeserializer.getType()); + else + deserializer = new ArrayDeserializer(Object.class); + } + else { + try { + //Class cl = Class.forName(type, false, getClassLoader()); + + Class cl = loadSerializedClass(type); + + deserializer = getDeserializer(cl); + } catch (Exception e) { + log.warning("Hessian/Burlap: '" + type + "' is an unknown class in " + getClassLoader() + ":\n" + e); + + log.log(Level.FINER, e.toString(), e); + } + } + + if (deserializer != null) { + if (_cachedTypeDeserializerMap == null) + _cachedTypeDeserializerMap = new HashMap(8); + + synchronized (_cachedTypeDeserializerMap) { + _cachedTypeDeserializerMap.put(type, deserializer); + } + } + + return deserializer; + } + + private static void addBasic(Class<?> cl, String typeName, int type) + { + Deserializer deserializer = new BasicDeserializer(type); + + _staticTypeMap.put(typeName, deserializer); + } + + static { + _staticTypeMap = new HashMap(); + + addBasic(void.class, "void", BasicSerializer.NULL); + + addBasic(Boolean.class, "boolean", BasicSerializer.BOOLEAN); + addBasic(Byte.class, "byte", BasicSerializer.BYTE); + addBasic(Short.class, "short", BasicSerializer.SHORT); + addBasic(Integer.class, "int", BasicSerializer.INTEGER); + addBasic(Long.class, "long", BasicSerializer.LONG); + addBasic(Float.class, "float", BasicSerializer.FLOAT); + addBasic(Double.class, "double", BasicSerializer.DOUBLE); + addBasic(Character.class, "char", BasicSerializer.CHARACTER_OBJECT); + addBasic(String.class, "string", BasicSerializer.STRING); + addBasic(StringBuilder.class, "string", BasicSerializer.STRING_BUILDER); + addBasic(Object.class, "object", BasicSerializer.OBJECT); + addBasic(java.util.Date.class, "date", BasicSerializer.DATE); + + addBasic(boolean.class, "boolean", BasicSerializer.BOOLEAN); + addBasic(byte.class, "byte", BasicSerializer.BYTE); + addBasic(short.class, "short", BasicSerializer.SHORT); + addBasic(int.class, "int", BasicSerializer.INTEGER); + addBasic(long.class, "long", BasicSerializer.LONG); + addBasic(float.class, "float", BasicSerializer.FLOAT); + addBasic(double.class, "double", BasicSerializer.DOUBLE); + addBasic(char.class, "char", BasicSerializer.CHARACTER); + + addBasic(boolean[].class, "[boolean", BasicSerializer.BOOLEAN_ARRAY); + addBasic(byte[].class, "[byte", BasicSerializer.BYTE_ARRAY); + addBasic(short[].class, "[short", BasicSerializer.SHORT_ARRAY); + addBasic(int[].class, "[int", BasicSerializer.INTEGER_ARRAY); + addBasic(long[].class, "[long", BasicSerializer.LONG_ARRAY); + addBasic(float[].class, "[float", BasicSerializer.FLOAT_ARRAY); + addBasic(double[].class, "[double", BasicSerializer.DOUBLE_ARRAY); + addBasic(char[].class, "[char", BasicSerializer.CHARACTER_ARRAY); + addBasic(String[].class, "[string", BasicSerializer.STRING_ARRAY); + addBasic(Object[].class, "[object", BasicSerializer.OBJECT_ARRAY); + + Deserializer objectDeserializer = new JavaDeserializer(Object.class, new FieldDeserializer2Factory()); + _staticTypeMap.put("object", objectDeserializer); + _staticTypeMap.put(HessianRemote.class.getName(), + RemoteDeserializer.DESER); + + + ClassLoader systemClassLoader = null; + try { + systemClassLoader = ClassLoader.getSystemClassLoader(); + } catch (Exception e) { + } + + _systemClassLoader = systemClassLoader; + } +} diff -Npur hessian-4.0.65-src/com/caucho/hessian/server/HessianDispatcher.java hessian-4.0.65-fix/com/caucho/hessian/server/HessianDispatcher.java --- hessian-4.0.65-src/com/caucho/hessian/server/HessianDispatcher.java 1970-01-01 08:00:00.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/hessian/server/HessianDispatcher.java 2023-08-15 18:39:22.000000000 +0800 @@ -0,0 +1,337 @@ + +package com.caucho.hessian.server; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.Writer; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +import javax.servlet.GenericServlet; +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.context.ApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import com.caucho.hessian.io.Hessian2Input; +import com.caucho.hessian.io.SerializerFactory; +import com.caucho.services.server.Service; +import com.caucho.services.server.ServiceContext; + + +public class HessianDispatcher extends GenericServlet +{ + + + private static final long serialVersionUID = -8611469561907416355L; + + private SerializerFactory _serializerFactory; + + private static final String SERVICE_FILE_PATH = "config-file"; + + private static Map<String, HessianSkeleton> registry = new ConcurrentHashMap<String, HessianSkeleton>(); + + private static Properties props = new Properties(); + + public HessianDispatcher() + { + } + + public String getServletInfo() + { + return "Hessian Dispatcher"; + } + + /** + * Sets the serializer factory. + */ + public void setSerializerFactory(SerializerFactory factory) + { + _serializerFactory = factory; + } + + /** + * Gets the serializer factory. + */ + public SerializerFactory getSerializerFactory() + { + if (_serializerFactory == null) + _serializerFactory = new SerializerFactory(); + + return _serializerFactory; + } + + /** + * Sets the serializer send collection java type. + */ + public void setSendCollectionType(boolean sendType) + { + getSerializerFactory().setSendCollectionType(sendType); + } + + /** + * Initialize the service, including the service object. + */ + public void init(ServletConfig config) throws ServletException + { + super.init(config); + + try + { + String serviceConfigFile = getInitParameter(SERVICE_FILE_PATH); + + if (null == serviceConfigFile) + { + throw new ServletException( + "Hessian service registry file path must be set in classpath when using 'HessianDispatcher'"); + } + + props.load(this.getClass().getClassLoader() + .getResourceAsStream(serviceConfigFile)); + } + + catch (Exception e) + { + throw new ServletException(e); + } + } + + private Class<?> loadClass(String className) throws ClassNotFoundException + { + ClassLoader loader = getContextClassLoader(); + + if (loader != null) + return Class.forName(className, false, loader); + else + return Class.forName(className); + } + + protected ClassLoader getContextClassLoader() + { + return Thread.currentThread().getContextClassLoader(); + } + + private void init(Object service) throws ServletException + { + if (!this.getClass().equals(HessianDispatcher.class)) + { + } + else if (service instanceof Service) + ((Service) service).init(getServletConfig()); + else if (service instanceof Servlet) + ((Servlet) service).init(getServletConfig()); + } + + /** + * Execute a request. The path-info of the request selects the bean. Once + * the bean's selected, it will be applied. + */ + public void service(ServletRequest request, ServletResponse response) + throws IOException, ServletException + { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse res = (HttpServletResponse) response; + + if (!req.getMethod().equals("POST")) + { + res.setStatus(500, "Hessian Requires POST"); + PrintWriter out = res.getWriter(); + + res.setContentType("text/html"); + out.println("<h1>Hessian Requires POST</h1>"); + + return; + } + + String serviceInterface = req.getHeader("Interface-Name"); + + if (null == serviceInterface) + { + throw new ServletException( + "The service interface you reqeust is null. please check the client setting."); + } + + try + { + HessianSkeleton skeleton = findHessianSkeleton(serviceInterface); + + String serviceId = req.getPathInfo(); + + String objectId = req.getParameter("id"); + + if (objectId == null) + objectId = req.getParameter("ejbid"); + + ServiceContext.begin(req, serviceId, objectId); + + InputStream is = request.getInputStream(); + + OutputStream os = response.getOutputStream(); + + response.setContentType("application/x-hessian"); + + SerializerFactory serializerFactory = getSerializerFactory(); + + invoke(is, os, skeleton, serializerFactory); + } + catch (RuntimeException e) + { + throw e; + } + catch (ServletException e) + { + throw e; + } + catch (Throwable e) + { + throw new ServletException(e); + } + finally + { + ServiceContext.end(); + } + } + + + private HessianSkeleton findHessianSkeleton(String serviceInterface) + throws ServletException, ClassNotFoundException, + IllegalAccessException, InstantiationException + { + HessianSkeleton skeleton = null; + + if (registry.containsKey(serviceInterface))// find in cache first + { + skeleton = registry.get(serviceInterface); + } + else + // parse serviceImpl string to create skeleton. + { + String serviceImpl = (String) this.props.get(serviceInterface); + + if (null == serviceImpl) + { + throw new ServletException( + "Your request service of " + + serviceInterface + + " dose not exsit.please check the server configuration."); + } + if (serviceImpl.startsWith("#"))// for get bean from spring + { + skeleton = findSpringSkeleton(serviceInterface, serviceImpl); + } + else + { + skeleton = findLocalSkeleton(serviceInterface, serviceImpl); + } + + } + + registry.put(serviceInterface, skeleton); + + return skeleton; + } + + + private HessianSkeleton findLocalSkeleton(String serviceInterface, + String serviceImpl) throws ClassNotFoundException, + InstantiationException, IllegalAccessException, ServletException + { + HessianSkeleton skeleton; + Class homeClass = loadClass(serviceImpl); + + Object localBean = homeClass.newInstance(); + + init(localBean); + + skeleton = new HessianSkeleton(localBean, loadClass(serviceInterface)); + return skeleton; + } + + + private HessianSkeleton findSpringSkeleton(String serviceInterface, + String serviceImpl) throws ServletException, ClassNotFoundException + { + HessianSkeleton skeleton; + String beanId = serviceImpl.substring(1, serviceImpl.length()); + + ApplicationContext wac = WebApplicationContextUtils + .getWebApplicationContext(getServletContext()); + + Object springBean = wac.getBean(beanId.trim()); + + init(springBean); + + skeleton = new HessianSkeleton(springBean, loadClass(serviceInterface)); + + return skeleton; + } + + protected void invoke(InputStream is, OutputStream os, + HessianSkeleton skeleton, SerializerFactory serializerFactory) + throws Exception + { + skeleton.invoke(is, os, serializerFactory); + } + + protected Hessian2Input createHessian2Input(InputStream is) + { + return new Hessian2Input(is); + } + + static class LogWriter extends Writer + { + private Logger _log; + + private StringBuilder _sb = new StringBuilder(); + + LogWriter(Logger log) + { + _log = log; + } + + public void write(char ch) + { + if (ch == '\n' && _sb.length() > 0) + { + _log.fine(_sb.toString()); + _sb.setLength(0); + } + else + _sb.append((char) ch); + } + + public void write(char[] buffer, int offset, int length) + { + for (int i = 0; i < length; i++) + { + char ch = buffer[offset + i]; + + if (ch == '\n' && _sb.length() > 0) + { + _log.fine(_sb.toString()); + _sb.setLength(0); + } + else + _sb.append((char) ch); + } + } + + public void flush() + { + } + + public void close() + { + } + } +} diff -Npur hessian-4.0.65-src/com/caucho/hessian/server/HessianServlet.java hessian-4.0.65-fix/com/caucho/hessian/server/HessianServlet.java --- hessian-4.0.65-src/com/caucho/hessian/server/HessianServlet.java 2020-07-23 12:51:28.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/hessian/server/HessianServlet.java 2023-08-15 18:39:22.000000000 +0800 @@ -1,477 +1,551 @@ -/* - * Copyright (c) 2001-2008 Caucho Technology, Inc. All rights reserved. - * - * The Apache Software License, Version 1.1 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Caucho Technology (http://www.caucho.com/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "Hessian", "Resin", and "Caucho" must not be used to - * endorse or promote products derived from this software without prior - * written permission. For written permission, please contact - * info@caucho.com. - * - * 5. Products derived from this software may not be called "Resin" - * nor may "Resin" appear in their names without prior written - * permission of Caucho Technology. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @author Scott Ferguson - */ - -package com.caucho.hessian.server; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.logging.Logger; - -import javax.servlet.GenericServlet; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.caucho.hessian.io.Hessian2Input; -import com.caucho.hessian.io.SerializerFactory; -import com.caucho.services.server.Service; -import com.caucho.services.server.ServiceContext; - -/** - * Servlet for serving Hessian services. - * - * Applications can use ServletContext inside a Hessian service to get - * ServletRequest, ServletResponse and session information. - */ -@SuppressWarnings("serial") -public class HessianServlet extends HttpServlet { - private Class<?> _homeAPI; - private Object _homeImpl; - - private Class<?> _objectAPI; - private Object _objectImpl; - - private HessianSkeleton _homeSkeleton; - private HessianSkeleton _objectSkeleton; - - private SerializerFactory _serializerFactory; - - public HessianServlet() - { - } - - public String getServletInfo() - { - return "Hessian Servlet"; - } - - /** - * Sets the home api. - */ - public void setHomeAPI(Class<?> api) - { - _homeAPI = api; - } - - /** - * Sets the home implementation - */ - public void setHome(Object home) - { - _homeImpl = home; - } - - /** - * Sets the object api. - */ - public void setObjectAPI(Class<?> api) - { - _objectAPI = api; - } - - /** - * Sets the object implementation - */ - public void setObject(Object object) - { - _objectImpl = object; - } - - /** - * Sets the service class. - */ - public void setService(Object service) - { - setHome(service); - } - - /** - * Sets the api-class. - */ - public void setAPIClass(Class<?> api) - { - setHomeAPI(api); - } - - /** - * Gets the api-class. - */ - public Class<?> getAPIClass() - { - return _homeAPI; - } - - /** - * Sets the serializer factory. - */ - public void setSerializerFactory(SerializerFactory factory) - { - _serializerFactory = factory; - } - - /** - * Gets the serializer factory. - */ - public SerializerFactory getSerializerFactory() - { - if (_serializerFactory == null) - _serializerFactory = new SerializerFactory(); - - return _serializerFactory; - } - - /** - * Sets the serializer send collection java type. - */ - public void setSendCollectionType(boolean sendType) - { - getSerializerFactory().setSendCollectionType(sendType); - } - - /** - * Sets whitelist mode for the deserializer - */ - public void setWhitelist(boolean isWhitelist) - { - getSerializerFactory().getClassFactory().setWhitelist(isWhitelist); - } - - /** - * Adds an allow rule to the deserializer - * - * Examples: "java.util.*", "com.foo.io.Bean" - */ - public void allow(String pattern) - { - getSerializerFactory().getClassFactory().allow(pattern); - } - - /** - * Adds a deny rule to the deserializer - */ - public void deny(String pattern) - { - getSerializerFactory().getClassFactory().deny(pattern); - } - - /** - * Sets the debugging flag. - */ - public void setDebug(boolean isDebug) - { - } - - /** - * Sets the debugging log name. - */ - public void setLogName(String name) - { - // _log = Logger.getLogger(name); - } - - /** - * Initialize the service, including the service object. - */ - public void init(ServletConfig config) - throws ServletException - { - super.init(config); - - try { - if (_homeImpl != null) { - } - else if (getInitParameter("home-class") != null) { - String className = getInitParameter("home-class"); - - Class<?> homeClass = loadClass(className); - - _homeImpl = homeClass.newInstance(); - - init(_homeImpl); - } - else if (getInitParameter("service-class") != null) { - String className = getInitParameter("service-class"); - - Class<?> homeClass = loadClass(className); - - _homeImpl = homeClass.newInstance(); - - init(_homeImpl); - } - else { - if (getClass().equals(HessianServlet.class)) - throw new ServletException("server must extend HessianServlet"); - - _homeImpl = this; - } - - if (_homeAPI != null) { - } - else if (getInitParameter("home-api") != null) { - String className = getInitParameter("home-api"); - - _homeAPI = loadClass(className); - } - else if (getInitParameter("api-class") != null) { - String className = getInitParameter("api-class"); - - _homeAPI = loadClass(className); - } - else if (_homeImpl != null) { - _homeAPI = findRemoteAPI(_homeImpl.getClass()); - - if (_homeAPI == null) - _homeAPI = _homeImpl.getClass(); - - _homeAPI = _homeImpl.getClass(); - } - - if (_objectImpl != null) { - } - else if (getInitParameter("object-class") != null) { - String className = getInitParameter("object-class"); - - Class<?> objectClass = loadClass(className); - - _objectImpl = objectClass.newInstance(); - - init(_objectImpl); - } - - if (_objectAPI != null) { - } - else if (getInitParameter("object-api") != null) { - String className = getInitParameter("object-api"); - - _objectAPI = loadClass(className); - } - else if (_objectImpl != null) - _objectAPI = _objectImpl.getClass(); - - _homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI); - - if (_objectAPI != null) - _homeSkeleton.setObjectClass(_objectAPI); - - if (_objectImpl != null) { - _objectSkeleton = new HessianSkeleton(_objectImpl, _objectAPI); - _objectSkeleton.setHomeClass(_homeAPI); - } - else - _objectSkeleton = _homeSkeleton; - - if ("true".equals(getInitParameter("debug"))) { - } - - if ("false".equals(getInitParameter("send-collection-type"))) - setSendCollectionType(false); - } catch (ServletException e) { - throw e; - } catch (Exception e) { - throw new ServletException(e); - } - } - - private Class<?> findRemoteAPI(Class<?> implClass) - { - // hessian/34d0 - return null; - - /* - if (implClass == null || implClass.equals(GenericService.class)) - return null; - - Class []interfaces = implClass.getInterfaces(); - - if (interfaces.length == 1) - return interfaces[0]; - - return findRemoteAPI(implClass.getSuperclass()); - */ - } - - private Class<?> loadClass(String className) - throws ClassNotFoundException - { - ClassLoader loader = getContextClassLoader(); - - if (loader != null) - return Class.forName(className, false, loader); - else - return Class.forName(className); - } - - protected ClassLoader getContextClassLoader() - { - return Thread.currentThread().getContextClassLoader(); - } - - private void init(Object service) - throws ServletException - { - if (! this.getClass().equals(HessianServlet.class)) { - } - else if (service instanceof Service) - ((Service) service).init(getServletConfig()); - else if (service instanceof Servlet) - ((Servlet) service).init(getServletConfig()); - } - - /** - * Execute a request. The path-info of the request selects the bean. - * Once the bean's selected, it will be applied. - */ - public void service(ServletRequest request, ServletResponse response) - throws IOException, ServletException - { - HttpServletRequest req = (HttpServletRequest) request; - HttpServletResponse res = (HttpServletResponse) response; - - if (! req.getMethod().equals("POST")) { - res.setStatus(500); // , "Hessian Requires POST"); - PrintWriter out = res.getWriter(); - - res.setContentType("text/html"); - out.println("<h1>Hessian Requires POST</h1>"); - - return; - } - - String serviceId = req.getPathInfo(); - String objectId = req.getParameter("id"); - if (objectId == null) - objectId = req.getParameter("ejbid"); - - ServiceContext.begin(req, res, serviceId, objectId); - - try { - InputStream is = request.getInputStream(); - OutputStream os = response.getOutputStream(); - - response.setContentType("x-application/hessian"); - - SerializerFactory serializerFactory = getSerializerFactory(); - - invoke(is, os, objectId, serializerFactory); - } catch (RuntimeException e) { - throw e; - } catch (ServletException e) { - throw e; - } catch (Throwable e) { - throw new ServletException(e); - } finally { - ServiceContext.end(); - } - } - - protected void invoke(InputStream is, OutputStream os, - String objectId, - SerializerFactory serializerFactory) - throws Exception - { - if (objectId != null) - _objectSkeleton.invoke(is, os, serializerFactory); - else - _homeSkeleton.invoke(is, os, serializerFactory); - } - - protected Hessian2Input createHessian2Input(InputStream is) - { - return new Hessian2Input(is); - } - - static class LogWriter extends Writer { - private Logger _log; - private StringBuilder _sb = new StringBuilder(); - - LogWriter(Logger log) - { - _log = log; - } - - public void write(char ch) - { - if (ch == '\n' && _sb.length() > 0) { - _log.fine(_sb.toString()); - _sb.setLength(0); - } - else - _sb.append((char) ch); - } - - public void write(char []buffer, int offset, int length) - { - for (int i = 0; i < length; i++) { - char ch = buffer[offset + i]; - - if (ch == '\n' && _sb.length() > 0) { - _log.fine(_sb.toString()); - _sb.setLength(0); - } - else - _sb.append((char) ch); - } - } - - public void flush() - { - } - - public void close() - { - } - } -} +/* + * Copyright (c) 2001-2008 Caucho Technology, Inc. All rights reserved. + * + * The Apache Software License, Version 1.1 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Caucho Technology (http://www.caucho.com/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Hessian", "Resin", and "Caucho" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * info@caucho.com. + * + * 5. Products derived from this software may not be called "Resin" + * nor may "Resin" appear in their names without prior written + * permission of Caucho Technology. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Scott Ferguson + */ + +package com.caucho.hessian.server; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.Writer; +import java.util.logging.Logger; + +import javax.servlet.GenericServlet; +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.context.ApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import com.caucho.hessian.io.Hessian2Input; +import com.caucho.hessian.io.SerializerFactory; +import com.caucho.services.server.GenericService; +import com.caucho.services.server.Service; +import com.caucho.services.server.ServiceContext; + +/** + * Servlet for serving Hessian services. + * + * Applications can use ServletContext inside a Hessian service to get + * ServletRequest, ServletResponse and session information. + */ +@SuppressWarnings("serial") +public class HessianServlet extends HttpServlet { + private static final long serialVersionUID = 1345616653808440850L; + private Logger _log = Logger.getLogger(HessianServlet.class.getName()); + private Class<?> _homeAPI; + private Object _homeImpl; + + private Class<?> _objectAPI; + private Object _objectImpl; + + private HessianSkeleton _homeSkeleton; + private HessianSkeleton _objectSkeleton; + + private SerializerFactory _serializerFactory; + private boolean _isDebug; + + public HessianServlet() + { + } + + public String getServletInfo() + { + return "Hessian Servlet"; + } + + /** + * Sets the home api. + */ + public void setHomeAPI(Class<?> api) + { + _homeAPI = api; + } + + /** + * Sets the home implementation + */ + public void setHome(Object home) + { + _homeImpl = home; + } + + /** + * Sets the object api. + */ + public void setObjectAPI(Class<?> api) + { + _objectAPI = api; + } + + /** + * Sets the object implementation + */ + public void setObject(Object object) + { + _objectImpl = object; + } + + /** + * Sets the service class. + */ + public void setService(Object service) + { + setHome(service); + } + + /** + * Sets the api-class. + */ + public void setAPIClass(Class<?> api) + { + setHomeAPI(api); + } + + /** + * Gets the api-class. + */ + public Class<?> getAPIClass() + { + return _homeAPI; + } + + /** + * Sets the serializer factory. + */ + public void setSerializerFactory(SerializerFactory factory) + { + _serializerFactory = factory; + } + + /** + * Gets the serializer factory. + */ + public SerializerFactory getSerializerFactory() + { + if (_serializerFactory == null) + _serializerFactory = new SerializerFactory(); + + return _serializerFactory; + } + + /** + * Sets the serializer send collection java type. + */ + public void setSendCollectionType(boolean sendType) + { + getSerializerFactory().setSendCollectionType(sendType); + } + + /** + * Sets whitelist mode for the deserializer + */ + public void setWhitelist(boolean isWhitelist) + { + getSerializerFactory().getClassFactory().setWhitelist(isWhitelist); + } + + /** + * Adds an allow rule to the deserializer + * + * Examples: "java.util.*", "com.foo.io.Bean" + */ + public void allow(String pattern) + { + getSerializerFactory().getClassFactory().allow(pattern); + } + + /** + * Adds a deny rule to the deserializer + */ + public void deny(String pattern) + { + getSerializerFactory().getClassFactory().deny(pattern); + } + + /** + * Sets the debugging flag. + */ + public void setDebug(boolean isDebug) + { + _isDebug = isDebug; + } + + /** + * Sets the debugging log name. + */ + public void setLogName(String name) + { + _log = Logger.getLogger(name); + } + + /** + * Initialize the service, including the service object. + */ + public void init(ServletConfig config) throws ServletException { + super.init(config); + + try { + String homeClassValue = getInitParameter("home-class"); + + if ((homeClassValue != null) & homeClassValue.startsWith("#")) //for get bean from spring + { + SpringPrepareForSkeleton(config, homeClassValue); + } else { + LocalPrepareForSkeleton(); + } + + _homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI); + + if (_objectAPI != null) { + _homeSkeleton.setObjectClass(_objectAPI); + } + + if (_objectImpl != null) { + _objectSkeleton = new HessianSkeleton(_objectImpl, _objectAPI); + _objectSkeleton.setHomeClass(_homeAPI); + } else { + _objectSkeleton = _homeSkeleton; + } + + if ("true".equals(getInitParameter("debug"))) { + _isDebug = true; + } + + if ("false".equals(getInitParameter("send-collection-type"))) { + setSendCollectionType(false); + } + } catch (ServletException e) { + throw e; + } catch (Exception e) { + throw new ServletException(e); + } + } + + /** + * TODO + * + * @param config + * @param homeClassValue + * @throws ServletException + */ + private void SpringPrepareForSkeleton(ServletConfig config, + String homeClassValue) + throws ClassNotFoundException, InstantiationException, + IllegalAccessException, ServletException { + if (getInitParameter("home-api") != null) { + String className = getInitParameter("home-api"); + _homeAPI = loadClass(className); + } + + String beanID = homeClassValue.substring(1, homeClassValue.length()); + ApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext()); + _homeImpl = wac.getBean(beanID); + + init(_homeImpl); + } + + /** + * @throws ClassNotFoundException + * @throws InstantiationException + * @throws IllegalAccessException + * @throws ServletException + */ + private void LocalPrepareForSkeleton() + throws ClassNotFoundException, InstantiationException, + IllegalAccessException, ServletException { + + if (_homeImpl != null) { + } + else if (getInitParameter("home-class") != null) { + String className = getInitParameter("home-class"); + + Class<?> homeClass = loadClass(className); + + _homeImpl = homeClass.newInstance(); + + init(_homeImpl); + } + else if (getInitParameter("service-class") != null) { + String className = getInitParameter("service-class"); + + Class<?> homeClass = loadClass(className); + + _homeImpl = homeClass.newInstance(); + + init(_homeImpl); + } + else { + if (getClass().equals(HessianServlet.class)) + throw new ServletException("server must extend HessianServlet"); + + _homeImpl = this; + } + + if (_homeAPI != null) { + } + else if (getInitParameter("home-api") != null) { + String className = getInitParameter("home-api"); + + _homeAPI = loadClass(className); + } + else if (getInitParameter("api-class") != null) { + String className = getInitParameter("api-class"); + + _homeAPI = loadClass(className); + } + else if (_homeImpl != null) { + _homeAPI = findRemoteAPI(_homeImpl.getClass()); + + if (_homeAPI == null) + _homeAPI = _homeImpl.getClass(); + + // _homeAPI = _homeImpl.getClass(); + } + + if (_objectImpl != null) { + } + else if (getInitParameter("object-class") != null) { + String className = getInitParameter("object-class"); + + Class<?> objectClass = loadClass(className); + + _objectImpl = objectClass.newInstance(); + + init(_objectImpl); + } + + if (_objectAPI != null) { + } + else if (getInitParameter("object-api") != null) { + String className = getInitParameter("object-api"); + + _objectAPI = loadClass(className); + } + else if (_objectImpl != null) + _objectAPI = _objectImpl.getClass(); + + /* _homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI); + + if (_objectAPI != null) + _homeSkeleton.setObjectClass(_objectAPI); + + if (_objectImpl != null) { + _objectSkeleton = new HessianSkeleton(_objectImpl, _objectAPI); + _objectSkeleton.setHomeClass(_homeAPI); + } + else + _objectSkeleton = _homeSkeleton; + + if ("true".equals(getInitParameter("debug"))) { + } + + if ("false".equals(getInitParameter("send-collection-type"))) + setSendCollectionType(false); + } catch (ServletException e) { + throw e; + } catch (Exception e) { + throw new ServletException(e); + } + */ + + } + + private Class<?> findRemoteAPI(Class<?> implClass) + { + + if (implClass == null || implClass.equals(GenericService.class)) + return null; + + Class []interfaces = implClass.getInterfaces(); + + if (interfaces.length == 1) + return interfaces[0]; + + return findRemoteAPI(implClass.getSuperclass()); + + } + + private Class<?> loadClass(String className) + throws ClassNotFoundException + { + ClassLoader loader = getContextClassLoader(); + + if (loader != null) + return Class.forName(className, false, loader); + else + return Class.forName(className); + } + + protected ClassLoader getContextClassLoader() + { + return Thread.currentThread().getContextClassLoader(); + } + + private void init(Object service) + throws ServletException + { + if (! this.getClass().equals(HessianServlet.class)) { + } + else if (service instanceof Service) + ((Service) service).init(getServletConfig()); + else if (service instanceof Servlet) + ((Servlet) service).init(getServletConfig()); + } + + /** + * Execute a request. The path-info of the request selects the bean. + * Once the bean's selected, it will be applied. + */ + public void service(ServletRequest request, ServletResponse response) + throws IOException, ServletException + { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse res = (HttpServletResponse) response; + + if (! req.getMethod().equals("POST")) { + res.setStatus(500); // , "Hessian Requires POST"); + PrintWriter out = res.getWriter(); + + res.setContentType("text/html"); + out.println("<h1>Hessian Requires POST</h1>"); + + return; + } + + String serviceId = req.getPathInfo(); + String objectId = req.getParameter("id"); + if (objectId == null) + objectId = req.getParameter("ejbid"); + + ServiceContext.begin(req, res, serviceId, objectId); + + try { + InputStream is = request.getInputStream(); + OutputStream os = response.getOutputStream(); + + response.setContentType("x-application/hessian"); + + SerializerFactory serializerFactory = getSerializerFactory(); + + invoke(is, os, objectId, serializerFactory); + } catch (RuntimeException e) { + throw e; + } catch (ServletException e) { + throw e; + } catch (Throwable e) { + throw new ServletException(e); + } finally { + ServiceContext.end(); + } + } + + protected void invoke(InputStream is, OutputStream os, + String objectId, + SerializerFactory serializerFactory) + throws Exception + { + if (objectId != null) + _objectSkeleton.invoke(is, os, serializerFactory); + else + _homeSkeleton.invoke(is, os, serializerFactory); + } + + protected Hessian2Input createHessian2Input(InputStream is) + { + return new Hessian2Input(is); + } + + static class LogWriter extends Writer { + private Logger _log; + private StringBuilder _sb = new StringBuilder(); + + LogWriter(Logger log) + { + _log = log; + } + + public void write(char ch) + { + if (ch == '\n' && _sb.length() > 0) { + _log.fine(_sb.toString()); + _sb.setLength(0); + } + else + _sb.append((char) ch); + } + + public void write(char []buffer, int offset, int length) + { + for (int i = 0; i < length; i++) { + char ch = buffer[offset + i]; + + if (ch == '\n' && _sb.length() > 0) { + _log.fine(_sb.toString()); + _sb.setLength(0); + } + else + _sb.append((char) ch); + } + } + + public void flush() + { + } + + public void close() + { + } + } +} diff -Npur hessian-4.0.65-src/com/caucho/services/server/ServiceContext.java hessian-4.0.65-fix/com/caucho/services/server/ServiceContext.java --- hessian-4.0.65-src/com/caucho/services/server/ServiceContext.java 2020-07-23 12:51:28.000000000 +0800 +++ hessian-4.0.65-fix/com/caucho/services/server/ServiceContext.java 2023-08-15 18:39:24.000000000 +0800 @@ -1,259 +1,274 @@ -/* - * Copyright (c) 2001-2008 Caucho Technology, Inc. All rights reserved. - * - * The Apache Software License, Version 1.1 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Caucho Technology (http://www.caucho.com/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "Hessian", "Resin", and "Caucho" must not be used to - * endorse or promote products derived from this software without prior - * written permission. For written permission, please contact - * info@caucho.com. - * - * 5. Products derived from this software may not be called "Resin" - * nor may "Resin" appear in their names without prior written - * permission of Caucho Technology. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @author Scott Ferguson - */ - -package com.caucho.services.server; - -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import java.util.HashMap; - -/** - * Context for a service, to handle request-specific information. - * - * Applications can use the ServiceContext to get servlet session ids or - * HTTP headers. - * - * <code><pre> - * ServletRequest req = ServiceContext.getContext().getRequest(); - * </pre></code> - */ -public class ServiceContext { - private static final ThreadLocal<ServiceContext> _localContext - = new ThreadLocal<ServiceContext>(); - - private ServletRequest _request; - private ServletResponse _response; - private String _serviceName; - private String _objectId; - private int _count; - private HashMap _headers = new HashMap(); - - private ServiceContext() - { - } - - /** - * Sets the request object prior to calling the service's method. - * - * @param request the calling servlet request - * @param serviceId the service identifier - * @param objectId the object identifier - */ - public static void begin(ServletRequest request, - ServletResponse response, - String serviceName, - String objectId) - throws ServletException - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context == null) { - context = new ServiceContext(); - _localContext.set(context); - } - - context._request = request; - context._response = response; - context._serviceName = serviceName; - context._objectId = objectId; - context._count++; - } - - /** - * Returns the service request. - */ - public static ServiceContext getContext() - { - return (ServiceContext) _localContext.get(); - } - - /** - * Adds a header. - */ - public void addHeader(String header, Object value) - { - _headers.put(header, value); - } - - /** - * Gets a header. - */ - public Object getHeader(String header) - { - return _headers.get(header); - } - - /** - * Gets a header from the context. - */ - public static Object getContextHeader(String header) - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context != null) - return context.getHeader(header); - else - return null; - } - - /** - * Returns the service request. - */ - public static ServletRequest getContextRequest() - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context != null) - return context._request; - else - return null; - } - - /** - * Returns the service request. - */ - public static ServletResponse getContextResponse() - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context != null) - return context._response; - else - return null; - } - - /** - * Returns the service id, corresponding to the pathInfo of the URL. - */ - public static String getContextServiceName() - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context != null) - return context._serviceName; - else - return null; - } - - /** - * Returns the object id, corresponding to the ?id= of the URL. - */ - public static String getContextObjectId() - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context != null) - return context._objectId; - else - return null; - } - - /** - * Cleanup at the end of a request. - */ - public static void end() - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context != null && --context._count == 0) { - context._request = null; - context._response = null; - - context._headers.clear(); - - _localContext.set(null); - } - } - - /** - * Returns the service request. - * - * @deprecated - */ - public static ServletRequest getRequest() - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context != null) - return context._request; - else - return null; - } - - /** - * Returns the service id, corresponding to the pathInfo of the URL. - * - * @deprecated - */ - public static String getServiceName() - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context != null) - return context._serviceName; - else - return null; - } - - /** - * Returns the object id, corresponding to the ?id= of the URL. - * - * @deprecated - */ - public static String getObjectId() - { - ServiceContext context = (ServiceContext) _localContext.get(); - - if (context != null) - return context._objectId; - else - return null; - } -} +/* + * Copyright (c) 2001-2008 Caucho Technology, Inc. All rights reserved. + * + * The Apache Software License, Version 1.1 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Caucho Technology (http://www.caucho.com/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Hessian", "Resin", and "Caucho" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * info@caucho.com. + * + * 5. Products derived from this software may not be called "Resin" + * nor may "Resin" appear in their names without prior written + * permission of Caucho Technology. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Scott Ferguson + */ + +package com.caucho.services.server; + +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import java.util.HashMap; + +/** + * Context for a service, to handle request-specific information. + * + * Applications can use the ServiceContext to get servlet session ids or + * HTTP headers. + * + * <code><pre> + * ServletRequest req = ServiceContext.getContext().getRequest(); + * </pre></code> + */ +public class ServiceContext { + private static final ThreadLocal<ServiceContext> _localContext + = new ThreadLocal<ServiceContext>(); + + private ServletRequest _request; + private ServletResponse _response; + private String _serviceName; + private String _objectId; + private int _count; + private HashMap _headers = new HashMap(); + + private ServiceContext() + { + } + + /** + * Sets the request object prior to calling the service's method. + * + * @param request the calling servlet request + * @param serviceId the service identifier + * @param objectId the object identifier + */ + public static void begin(ServletRequest request, + ServletResponse response, + String serviceName, + String objectId) + throws ServletException + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context == null) { + context = new ServiceContext(); + _localContext.set(context); + } + + context._request = request; + context._response = response; + context._serviceName = serviceName; + context._objectId = objectId; + context._count++; + } + + public static void begin(ServletRequest request, String serviceName, + String objectId) throws ServletException { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context == null) { + context = new ServiceContext(); + _localContext.set(context); + } + + context._request = request; + context._serviceName = serviceName; + context._objectId = objectId; + context._count++; + } + + /** + * Returns the service request. + */ + public static ServiceContext getContext() + { + return (ServiceContext) _localContext.get(); + } + + /** + * Adds a header. + */ + public void addHeader(String header, Object value) + { + _headers.put(header, value); + } + + /** + * Gets a header. + */ + public Object getHeader(String header) + { + return _headers.get(header); + } + + /** + * Gets a header from the context. + */ + public static Object getContextHeader(String header) + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context != null) + return context.getHeader(header); + else + return null; + } + + /** + * Returns the service request. + */ + public static ServletRequest getContextRequest() + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context != null) + return context._request; + else + return null; + } + + /** + * Returns the service request. + */ + public static ServletResponse getContextResponse() + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context != null) + return context._response; + else + return null; + } + + /** + * Returns the service id, corresponding to the pathInfo of the URL. + */ + public static String getContextServiceName() + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context != null) + return context._serviceName; + else + return null; + } + + /** + * Returns the object id, corresponding to the ?id= of the URL. + */ + public static String getContextObjectId() + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context != null) + return context._objectId; + else + return null; + } + + /** + * Cleanup at the end of a request. + */ + public static void end() + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context != null && --context._count == 0) { + context._request = null; + context._response = null; + + context._headers.clear(); + + _localContext.set(null); + } + } + + /** + * Returns the service request. + * + * @deprecated + */ + public static ServletRequest getRequest() + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context != null) + return context._request; + else + return null; + } + + /** + * Returns the service id, corresponding to the pathInfo of the URL. + * + * @deprecated + */ + public static String getServiceName() + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context != null) + return context._serviceName; + else + return null; + } + + /** + * Returns the object id, corresponding to the ?id= of the URL. + * + * @deprecated + */ + public static String getObjectId() + { + ServiceContext context = (ServiceContext) _localContext.get(); + + if (context != null) + return context._objectId; + else + return null; + } +}
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2