X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=support%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fgeneral%2FSerializableProxyFactory.java;fp=support%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fgeneral%2FSerializableProxyFactory.java;h=34b7e3a564a99dc04a64006cfbf34a3fd3fe39bc;hb=5ddf0de8b6ecb45f2420c9b2e68f82cb7c52dfbb;hp=0000000000000000000000000000000000000000;hpb=fb9750bc8475eb0c6c9525133e5e9b2aac18fadb;p=utils diff --git a/support/general/src/main/java/org/wamblee/general/SerializableProxyFactory.java b/support/general/src/main/java/org/wamblee/general/SerializableProxyFactory.java new file mode 100644 index 00000000..34b7e3a5 --- /dev/null +++ b/support/general/src/main/java/org/wamblee/general/SerializableProxyFactory.java @@ -0,0 +1,113 @@ +/* + * Copyright 2005-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wamblee.general; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; + +/** + *

+ * Serializable proxy factory that allows to create serializable proxies to + * objects that are themselves not serializable. + *

+ * + *

+ * This class does not do any cleanup so it is recommended to only use this in + * test utilities. + *

+ * + * + * @author Erik Brakkee + * + * @param + */ +public class SerializableProxyFactory { + + private T svc; + private Class clazz; + private T proxy; + + /** + * Constructs the factory. + * + * @param aClass + * Interface class of the service to proxy. + */ + public SerializableProxyFactory(Class aClass) { + this(aClass, null); + } + + /** + * Constructs the factory with a callback to create thread-specific objects + * automatically. + * + * @param aClass + * Interface class of the service to proxy. + * @param aCallback + * Callback to create the object if it does not exist. When null, + * then no initialization is done. + */ + public SerializableProxyFactory(Class aClass, T aSvc) { + if (!aClass.isInterface()) { + throw new IllegalArgumentException("Class " + aClass.getName() + + " is not an interface"); + } + if (!aClass.isInstance(aSvc)) { + throw new IllegalArgumentException("Object " + aSvc + + " cannot be cast to " + aSvc.getClass()); + } + svc = aSvc; + clazz = aClass; + proxy = createProxy(); + + } + + /** + * Gets the underlying service. + * + * @return Service. + */ + public T get() { + return svc; + } + + /** + * Gets the proxy that delegates to the thread-specific instance set by + * {@link #set(Object)} + * + * @return Proxy. + */ + public T getProxy() { + return proxy; + } + + private T createProxy() { + InvocationHandler handler = new SerializableInvocationHandler(svc, + clazz); + Class proxyClass = Proxy.getProxyClass(clazz.getClassLoader(), + new Class[] { clazz }); + T proxyObj; + try { + proxyObj = (T) proxyClass.getConstructor( + new Class[] { InvocationHandler.class }).newInstance( + new Object[] { handler }); + return proxyObj; + } catch (Exception e) { + throw new RuntimeException("Could not create proxy for " + + clazz.getName(), e); + } + } +}