代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/hessian 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
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;
+ }
+}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。