You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by yi...@apache.org on 2011/01/10 23:44:57 UTC

svn commit: r1057407 - in /openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans: component/BuildInOwbBean.java proxy/JavassistProxyFactory.java

Author: yingwang
Date: Mon Jan 10 22:44:57 2011
New Revision: 1057407

URL: http://svn.apache.org/viewvc?rev=1057407&view=rev
Log:
[OWB-508] add abstract build in owb bean class

Added:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java
Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java

Added: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java?rev=1057407&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java Mon Jan 10 22:44:57 2011
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.webbeans.component;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.ProxyObject;
+
+import org.apache.webbeans.config.BeansDeployer;
+import org.apache.webbeans.config.OpenWebBeansConfiguration;
+import org.apache.webbeans.container.BeanManagerImpl;
+import org.apache.webbeans.logger.WebBeansLogger;
+import org.apache.webbeans.proxy.JavassistProxyFactory;
+
+/**
+ * Following 3 options are provided for vendor's build-in beans implementation:
+ * 
+ * 1. "none", means the build-in bean does not need a proxy wrapper.
+ * 2. "default", means the build-in bean needs OWB-provided default proxy wrapper.
+ * 3. A class name, which implements MethodHandler. This will allow vendor to 
+ *    customize the serialization behavior.
+ *    
+ * The default values for 4 build-in beans are "default". Following property could
+ * be used to change the default behavior:
+ * 
+ * Property Name:   org.apache.webbeans.component.BuildInOwbBean.property 
+ * Sample values:   UserTransation:none;Principal:default;Validation:com.mycompany.ValidationProxyHandler;ValidationFactory:default
+ *  
+ * @author yingwang
+ *
+ * @param <T>
+ */
+public abstract class BuildInOwbBean<T> extends AbstractOwbBean<T>
+{
+
+    //Logger instance
+    private final WebBeansLogger logger = WebBeansLogger.getLogger(BeansDeployer.class);
+
+    
+    private static HashMap<WebBeansType, String> proxyHandlerMap = new HashMap<WebBeansType, String>();
+
+    
+    public static final String BUILD_IN_BEAN_PROPERTY = "org.apache.webbeans.component.BuildInOwbBean.property";
+    
+    /**
+     * none means the build-in bean instance does not need proxy wrapper. This is used
+     * for the build-in beans from vendors that are already serializable. 
+     */
+    private static final String PROXY_HANDLER_VALUE_NONE="none";
+
+    /**
+     * default means the build-bin bean instance need a default proxy wrapper. And the
+     * default proxy wrapper will get new instance from build in bean providers when
+     * it is deserialized. 
+     */
+    private static final String PROXY_HANDLER_VALUE_DEFAULT="default";
+
+    /**
+     * Initialize build-in config.
+     */
+    private static boolean initialized = initBuildInBeanConfig();
+
+    /**
+     * The handler class name.
+     */
+    protected String handlerClassName;
+    
+    /**
+     * The handler class.
+     */
+    protected Class handlerClass;
+    
+    
+    protected Constructor handlerContructor;
+    
+    /**
+     * Parse the custom property.
+     * 
+     * @return true
+     */
+    protected static boolean initBuildInBeanConfig() 
+    {
+        String s = OpenWebBeansConfiguration.getInstance().getProperty(BUILD_IN_BEAN_PROPERTY);
+        proxyHandlerMap.put(WebBeansType.USERTRANSACTION, PROXY_HANDLER_VALUE_DEFAULT);
+        proxyHandlerMap.put(WebBeansType.PRINCIPAL, PROXY_HANDLER_VALUE_DEFAULT);
+        proxyHandlerMap.put(WebBeansType.VALIDATION, PROXY_HANDLER_VALUE_DEFAULT);
+        proxyHandlerMap.put(WebBeansType.VALIDATIONFACT, PROXY_HANDLER_VALUE_DEFAULT);
+        if (s != null && !s.equalsIgnoreCase("default"))
+        {
+            int i;
+            String name;
+            String value;
+            String mapStrings[] = s.split(";");
+            for(i=0; i<mapStrings.length; i++)
+            {
+                name = null;
+                value = null;
+                String pair[] = mapStrings[i].trim().split(":");
+                if (pair.length == 2) 
+                {
+                    name = pair[0].trim();
+                    value = pair[1].trim();
+                }
+                if (name == null || value == null || value.equalsIgnoreCase(PROXY_HANDLER_VALUE_DEFAULT)) 
+                {
+                    continue;
+                }
+                if (name.contains("UserTransaction"))
+                {
+                    proxyHandlerMap.put(WebBeansType.USERTRANSACTION, value);
+                } 
+                else if (name.contains("Principal"))
+                {
+                    proxyHandlerMap.put(WebBeansType.PRINCIPAL, value);
+                }
+                else if (name.contains("Validation"))
+                {
+                    proxyHandlerMap.put(WebBeansType.VALIDATION, value);
+                } 
+                else if (name.contains("ValidationFactory"))
+                {
+                    proxyHandlerMap.put(WebBeansType.VALIDATIONFACT, value);
+                }
+            } 
+        } 
+        return true;
+    }
+
+    protected BuildInOwbBean(WebBeansType webBeanType)
+    {
+        this(webBeanType, null);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected BuildInOwbBean(WebBeansType webBeansType, Class<T> returnType)
+    {
+        super(webBeansType, returnType);
+        this.handlerClassName = proxyHandlerMap.get(this.getWebBeansType());
+        if (handlerClassName.equalsIgnoreCase(PROXY_HANDLER_VALUE_NONE) ||
+                handlerClassName.equalsIgnoreCase(PROXY_HANDLER_VALUE_DEFAULT)) 
+        {
+            return;
+        }
+
+        // initialize the custom proxy handler class and its constructor.
+        AccessController.doPrivileged(new PrivilegedAction<T>() 
+        {
+            BuildInOwbBean<T> buildinBean;
+            
+            public T run()
+            {
+                try 
+                {
+                    buildinBean.handlerClass = Class.forName(name);
+                    buildinBean.handlerContructor = buildinBean.handlerClass.getConstructor(BuildInOwbBean.class, Object.class);
+                    return null;
+                } 
+                catch (ClassNotFoundException e) 
+                {
+                    logger.error(e);
+                } 
+                catch (SecurityException e) 
+                {
+                    logger.error(e);
+                } 
+                catch (NoSuchMethodException e) 
+                {
+                    logger.error(e);
+                }
+                buildinBean.handlerClass = null;
+                buildinBean.handlerContructor = null;
+                return null;
+            }
+            
+            protected PrivilegedAction<T> setBuildInBean(BuildInOwbBean<T> b) 
+            {
+                this.buildinBean = b;
+                return this;
+            }
+            
+        }.setBuildInBean(this));
+    }
+        
+    /**
+     * Create a dependent proxy wrapper around the actual build in bean instance.
+     * 
+     * @param actualInstance
+     * @param creationalContext
+     * @return
+     */
+    protected T createProxyWrapper(T actualInstance, CreationalContext<T> creationalContext)
+    {
+        if (handlerClassName.equals(PROXY_HANDLER_VALUE_NONE))
+        {
+            return actualInstance;
+        }
+        
+        T proxy = (T)JavassistProxyFactory.getInstance().createBuildInBeanProxy(this);
+        if (handlerClassName.equals(PROXY_HANDLER_VALUE_DEFAULT)) 
+        {
+            ((ProxyObject)proxy).setHandler(new BuildInBeanMethodHandler(this, actualInstance));
+            return proxy;
+        } 
+        else if (handlerContructor != null)
+        {
+            try 
+            {
+                ((ProxyObject)proxy).setHandler( (MethodHandler)(handlerContructor.newInstance(this, actualInstance)));
+                return proxy;
+            } 
+            catch (Exception e) 
+            {
+                logger.error(e);
+            }
+        }
+        return null;
+    }
+    
+
+    protected abstract T createActualInstance(CreationalContext<T> creationalContext);
+    
+    
+    /**
+     * The default build in bean handler. 
+     * 
+     * @author yingwang
+     *
+     * @param <T>
+     */
+    public static class BuildInBeanMethodHandler<T> implements MethodHandler, Serializable
+    {
+
+        /**
+         * 
+         */
+        private static final long serialVersionUID = -2442900183095535369L;
+
+        BuildInOwbBean<T> bean;
+        
+        private T actualObject = null;
+        
+        //DO NOT REMOVE, used by failover and passivation.
+        public BuildInBeanMethodHandler()
+        {
+        }
+
+        public BuildInBeanMethodHandler(BuildInOwbBean<T> bean, T actualObject) 
+        {
+            this.bean = bean;
+            this.actualObject = actualObject;
+        }    
+        
+        @Override
+        public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable
+        {
+            if(proceed != null)       
+            {
+                return proceed.invoke(actualObject,args);
+            } 
+            else 
+            {
+                //interface method.
+                return thisMethod.invoke(actualObject,args);
+            }            
+        }
+
+        private  void writeObject(ObjectOutputStream s) throws IOException
+        {
+            s.writeLong(serialVersionUID);
+            s.writeObject(bean.getId());
+        }    
+        
+        private  void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException
+        {
+            if(s.readLong() == serialVersionUID) 
+            {
+                String id = (String)s.readObject();
+                bean = (BuildInOwbBean<T>)BeanManagerImpl.getManager().getPassivationCapableBean(id);
+                // create new real instance after deserialized.
+                actualObject = bean.createActualInstance(null);
+            } 
+            else 
+            {
+                throw new IOException("Serial version uid does not match.");
+            }
+        }    
+
+    }
+}

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java?rev=1057407&r1=1057406&r2=1057407&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java Mon Jan 10 22:44:57 2011
@@ -60,6 +60,7 @@ public final class JavassistProxyFactory
 
     }
     
+    private ConcurrentMap<OwbBean<?>, Class<?>> buildInBeanProxyClasses = new ConcurrentHashMap<OwbBean<?>, Class<?>>();    
     private ConcurrentMap<OwbBean<?>, Class<?>> normalScopedBeanProxyClasses = new ConcurrentHashMap<OwbBean<?>, Class<?>>();    
     private ConcurrentMap<OwbBean<?>, Class<?>> dependentScopedBeanProxyClasses = new ConcurrentHashMap<OwbBean<?>, Class<?>>();    
     private ConcurrentMap<OwbBean<?>, Class<?>> interceptorProxyClasses = new ConcurrentHashMap<OwbBean<?>, Class<?>>();
@@ -221,6 +222,28 @@ public final class JavassistProxyFactory
         return result;
     }
     
+    public Object createBuildInBeanProxy(OwbBean<?> bean) 
+    {
+        Object result = null;
+        try
+        {
+            Class<?> proxyClass = buildInBeanProxyClasses.get(bean);
+            if (proxyClass == null)
+            {
+                ProxyFactory fact = createProxyFactory(bean);
+                proxyClass = getProxyClass(fact);
+                buildInBeanProxyClasses.putIfAbsent(bean, proxyClass);
+            }
+            result = proxyClass.newInstance();
+        }
+        catch (Exception e)
+        {
+            WebBeansUtil.throwRuntimeExceptions(e);
+        }
+        return result;
+    }
+
+    
     public  Object createDependentScopedBeanProxy(OwbBean<?> bean, Object actualInstance, CreationalContext<?> creastionalContext)
     {
         Object result = null;



Re: svn commit: r1057407 - in /openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans: component/BuildInOwbBean.java proxy/JavassistProxyFactory.java

Posted by YING WANG <wa...@gmail.com>.
Thanks David, I did not notice the recent changes around static variables.
Your fix should be ok since we only have 4 build-in beans.

On Mon, Jan 10, 2011 at 9:58 PM, David Jencks <da...@yahoo.com>wrote:

> This didn't  compile, which I fixed in rev 1057448.  However there's a
> design problem in that the proxy choices are per-application since they are
> configured from OWBConfiguration.  Therefore the choices cannot be stored in
> a static map.  My change put the entire map of configuration info in every
> BuildinOwbBean which is also wasteful.
>
> I would suggest either putting the configuration map into a service in
> WebBeansContext or simply parsing it in a static method each time a built in
> bean is created and passing in the type from the subclass constructor.
>
> thanks
> david jencks
>
> On Jan 10, 2011, at 2:44 PM, yingwang@apache.org wrote:
>
> > Author: yingwang
> > Date: Mon Jan 10 22:44:57 2011
> > New Revision: 1057407
> >
> > URL: http://svn.apache.org/viewvc?rev=1057407&view=rev
> > Log:
> > [OWB-508] add abstract build in owb bean class
> >
> > Added:
> >
>  openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java
> > Modified:
> >
>  openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
> >
> > Added:
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java
> > URL:
> http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java?rev=1057407&view=auto
> >
> ==============================================================================
> > ---
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java
> (added)
> > +++
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java
> Mon Jan 10 22:44:57 2011
> > @@ -0,0 +1,315 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements. See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership. The ASF licenses this file
> > + * to you 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.apache.webbeans.component;
> > +
> > +import java.io.IOException;
> > +import java.io.ObjectInputStream;
> > +import java.io.ObjectOutputStream;
> > +import java.io.Serializable;
> > +import java.lang.reflect.Constructor;
> > +import java.lang.reflect.Method;
> > +import java.security.AccessController;
> > +import java.security.PrivilegedAction;
> > +import java.util.HashMap;
> > +
> > +import javax.enterprise.context.spi.CreationalContext;
> > +import javassist.util.proxy.MethodHandler;
> > +import javassist.util.proxy.ProxyObject;
> > +
> > +import org.apache.webbeans.config.BeansDeployer;
> > +import org.apache.webbeans.config.OpenWebBeansConfiguration;
> > +import org.apache.webbeans.container.BeanManagerImpl;
> > +import org.apache.webbeans.logger.WebBeansLogger;
> > +import org.apache.webbeans.proxy.JavassistProxyFactory;
> > +
> > +/**
> > + * Following 3 options are provided for vendor's build-in beans
> implementation:
> > + *
> > + * 1. "none", means the build-in bean does not need a proxy wrapper.
> > + * 2. "default", means the build-in bean needs OWB-provided default
> proxy wrapper.
> > + * 3. A class name, which implements MethodHandler. This will allow
> vendor to
> > + *    customize the serialization behavior.
> > + *
> > + * The default values for 4 build-in beans are "default". Following
> property could
> > + * be used to change the default behavior:
> > + *
> > + * Property Name:
> org.apache.webbeans.component.BuildInOwbBean.property
> > + * Sample values:
> UserTransation:none;Principal:default;Validation:com.mycompany.ValidationProxyHandler;ValidationFactory:default
> > + *
> > + * @author yingwang
> > + *
> > + * @param <T>
> > + */
> > +public abstract class BuildInOwbBean<T> extends AbstractOwbBean<T>
> > +{
> > +
> > +    //Logger instance
> > +    private final WebBeansLogger logger =
> WebBeansLogger.getLogger(BeansDeployer.class);
> > +
> > +
> > +    private static HashMap<WebBeansType, String> proxyHandlerMap = new
> HashMap<WebBeansType, String>();
> > +
> > +
> > +    public static final String BUILD_IN_BEAN_PROPERTY =
> "org.apache.webbeans.component.BuildInOwbBean.property";
> > +
> > +    /**
> > +     * none means the build-in bean instance does not need proxy
> wrapper. This is used
> > +     * for the build-in beans from vendors that are already
> serializable.
> > +     */
> > +    private static final String PROXY_HANDLER_VALUE_NONE="none";
> > +
> > +    /**
> > +     * default means the build-bin bean instance need a default proxy
> wrapper. And the
> > +     * default proxy wrapper will get new instance from build in bean
> providers when
> > +     * it is deserialized.
> > +     */
> > +    private static final String PROXY_HANDLER_VALUE_DEFAULT="default";
> > +
> > +    /**
> > +     * Initialize build-in config.
> > +     */
> > +    private static boolean initialized = initBuildInBeanConfig();
> > +
> > +    /**
> > +     * The handler class name.
> > +     */
> > +    protected String handlerClassName;
> > +
> > +    /**
> > +     * The handler class.
> > +     */
> > +    protected Class handlerClass;
> > +
> > +
> > +    protected Constructor handlerContructor;
> > +
> > +    /**
> > +     * Parse the custom property.
> > +     *
> > +     * @return true
> > +     */
> > +    protected static boolean initBuildInBeanConfig()
> > +    {
> > +        String s =
> OpenWebBeansConfiguration.getInstance().getProperty(BUILD_IN_BEAN_PROPERTY);
> > +        proxyHandlerMap.put(WebBeansType.USERTRANSACTION,
> PROXY_HANDLER_VALUE_DEFAULT);
> > +        proxyHandlerMap.put(WebBeansType.PRINCIPAL,
> PROXY_HANDLER_VALUE_DEFAULT);
> > +        proxyHandlerMap.put(WebBeansType.VALIDATION,
> PROXY_HANDLER_VALUE_DEFAULT);
> > +        proxyHandlerMap.put(WebBeansType.VALIDATIONFACT,
> PROXY_HANDLER_VALUE_DEFAULT);
> > +        if (s != null && !s.equalsIgnoreCase("default"))
> > +        {
> > +            int i;
> > +            String name;
> > +            String value;
> > +            String mapStrings[] = s.split(";");
> > +            for(i=0; i<mapStrings.length; i++)
> > +            {
> > +                name = null;
> > +                value = null;
> > +                String pair[] = mapStrings[i].trim().split(":");
> > +                if (pair.length == 2)
> > +                {
> > +                    name = pair[0].trim();
> > +                    value = pair[1].trim();
> > +                }
> > +                if (name == null || value == null ||
> value.equalsIgnoreCase(PROXY_HANDLER_VALUE_DEFAULT))
> > +                {
> > +                    continue;
> > +                }
> > +                if (name.contains("UserTransaction"))
> > +                {
> > +                    proxyHandlerMap.put(WebBeansType.USERTRANSACTION,
> value);
> > +                }
> > +                else if (name.contains("Principal"))
> > +                {
> > +                    proxyHandlerMap.put(WebBeansType.PRINCIPAL, value);
> > +                }
> > +                else if (name.contains("Validation"))
> > +                {
> > +                    proxyHandlerMap.put(WebBeansType.VALIDATION, value);
> > +                }
> > +                else if (name.contains("ValidationFactory"))
> > +                {
> > +                    proxyHandlerMap.put(WebBeansType.VALIDATIONFACT,
> value);
> > +                }
> > +            }
> > +        }
> > +        return true;
> > +    }
> > +
> > +    protected BuildInOwbBean(WebBeansType webBeanType)
> > +    {
> > +        this(webBeanType, null);
> > +    }
> > +
> > +    @SuppressWarnings("unchecked")
> > +    protected BuildInOwbBean(WebBeansType webBeansType, Class<T>
> returnType)
> > +    {
> > +        super(webBeansType, returnType);
> > +        this.handlerClassName =
> proxyHandlerMap.get(this.getWebBeansType());
> > +        if (handlerClassName.equalsIgnoreCase(PROXY_HANDLER_VALUE_NONE)
> ||
> > +
>  handlerClassName.equalsIgnoreCase(PROXY_HANDLER_VALUE_DEFAULT))
> > +        {
> > +            return;
> > +        }
> > +
> > +        // initialize the custom proxy handler class and its
> constructor.
> > +        AccessController.doPrivileged(new PrivilegedAction<T>()
> > +        {
> > +            BuildInOwbBean<T> buildinBean;
> > +
> > +            public T run()
> > +            {
> > +                try
> > +                {
> > +                    buildinBean.handlerClass = Class.forName(name);
> > +                    buildinBean.handlerContructor =
> buildinBean.handlerClass.getConstructor(BuildInOwbBean.class, Object.class);
> > +                    return null;
> > +                }
> > +                catch (ClassNotFoundException e)
> > +                {
> > +                    logger.error(e);
> > +                }
> > +                catch (SecurityException e)
> > +                {
> > +                    logger.error(e);
> > +                }
> > +                catch (NoSuchMethodException e)
> > +                {
> > +                    logger.error(e);
> > +                }
> > +                buildinBean.handlerClass = null;
> > +                buildinBean.handlerContructor = null;
> > +                return null;
> > +            }
> > +
> > +            protected PrivilegedAction<T>
> setBuildInBean(BuildInOwbBean<T> b)
> > +            {
> > +                this.buildinBean = b;
> > +                return this;
> > +            }
> > +
> > +        }.setBuildInBean(this));
> > +    }
> > +
> > +    /**
> > +     * Create a dependent proxy wrapper around the actual build in bean
> instance.
> > +     *
> > +     * @param actualInstance
> > +     * @param creationalContext
> > +     * @return
> > +     */
> > +    protected T createProxyWrapper(T actualInstance,
> CreationalContext<T> creationalContext)
> > +    {
> > +        if (handlerClassName.equals(PROXY_HANDLER_VALUE_NONE))
> > +        {
> > +            return actualInstance;
> > +        }
> > +
> > +        T proxy =
> (T)JavassistProxyFactory.getInstance().createBuildInBeanProxy(this);
> > +        if (handlerClassName.equals(PROXY_HANDLER_VALUE_DEFAULT))
> > +        {
> > +            ((ProxyObject)proxy).setHandler(new
> BuildInBeanMethodHandler(this, actualInstance));
> > +            return proxy;
> > +        }
> > +        else if (handlerContructor != null)
> > +        {
> > +            try
> > +            {
> > +                ((ProxyObject)proxy).setHandler(
> (MethodHandler)(handlerContructor.newInstance(this, actualInstance)));
> > +                return proxy;
> > +            }
> > +            catch (Exception e)
> > +            {
> > +                logger.error(e);
> > +            }
> > +        }
> > +        return null;
> > +    }
> > +
> > +
> > +    protected abstract T createActualInstance(CreationalContext<T>
> creationalContext);
> > +
> > +
> > +    /**
> > +     * The default build in bean handler.
> > +     *
> > +     * @author yingwang
> > +     *
> > +     * @param <T>
> > +     */
> > +    public static class BuildInBeanMethodHandler<T> implements
> MethodHandler, Serializable
> > +    {
> > +
> > +        /**
> > +         *
> > +         */
> > +        private static final long serialVersionUID =
> -2442900183095535369L;
> > +
> > +        BuildInOwbBean<T> bean;
> > +
> > +        private T actualObject = null;
> > +
> > +        //DO NOT REMOVE, used by failover and passivation.
> > +        public BuildInBeanMethodHandler()
> > +        {
> > +        }
> > +
> > +        public BuildInBeanMethodHandler(BuildInOwbBean<T> bean, T
> actualObject)
> > +        {
> > +            this.bean = bean;
> > +            this.actualObject = actualObject;
> > +        }
> > +
> > +        @Override
> > +        public Object invoke(Object self, Method thisMethod, Method
> proceed, Object[] args) throws Throwable
> > +        {
> > +            if(proceed != null)
> > +            {
> > +                return proceed.invoke(actualObject,args);
> > +            }
> > +            else
> > +            {
> > +                //interface method.
> > +                return thisMethod.invoke(actualObject,args);
> > +            }
> > +        }
> > +
> > +        private  void writeObject(ObjectOutputStream s) throws
> IOException
> > +        {
> > +            s.writeLong(serialVersionUID);
> > +            s.writeObject(bean.getId());
> > +        }
> > +
> > +        private  void readObject(ObjectInputStream s) throws
> IOException, ClassNotFoundException
> > +        {
> > +            if(s.readLong() == serialVersionUID)
> > +            {
> > +                String id = (String)s.readObject();
> > +                bean =
> (BuildInOwbBean<T>)BeanManagerImpl.getManager().getPassivationCapableBean(id);
> > +                // create new real instance after deserialized.
> > +                actualObject = bean.createActualInstance(null);
> > +            }
> > +            else
> > +            {
> > +                throw new IOException("Serial version uid does not
> match.");
> > +            }
> > +        }
> > +
> > +    }
> > +}
> >
> > Modified:
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
> > URL:
> http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java?rev=1057407&r1=1057406&r2=1057407&view=diff
> >
> ==============================================================================
> > ---
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
> (original)
> > +++
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
> Mon Jan 10 22:44:57 2011
> > @@ -60,6 +60,7 @@ public final class JavassistProxyFactory
> >
> >     }
> >
> > +    private ConcurrentMap<OwbBean<?>, Class<?>> buildInBeanProxyClasses
> = new ConcurrentHashMap<OwbBean<?>, Class<?>>();
> >     private ConcurrentMap<OwbBean<?>, Class<?>>
> normalScopedBeanProxyClasses = new ConcurrentHashMap<OwbBean<?>,
> Class<?>>();
> >     private ConcurrentMap<OwbBean<?>, Class<?>>
> dependentScopedBeanProxyClasses = new ConcurrentHashMap<OwbBean<?>,
> Class<?>>();
> >     private ConcurrentMap<OwbBean<?>, Class<?>> interceptorProxyClasses =
> new ConcurrentHashMap<OwbBean<?>, Class<?>>();
> > @@ -221,6 +222,28 @@ public final class JavassistProxyFactory
> >         return result;
> >     }
> >
> > +    public Object createBuildInBeanProxy(OwbBean<?> bean)
> > +    {
> > +        Object result = null;
> > +        try
> > +        {
> > +            Class<?> proxyClass = buildInBeanProxyClasses.get(bean);
> > +            if (proxyClass == null)
> > +            {
> > +                ProxyFactory fact = createProxyFactory(bean);
> > +                proxyClass = getProxyClass(fact);
> > +                buildInBeanProxyClasses.putIfAbsent(bean, proxyClass);
> > +            }
> > +            result = proxyClass.newInstance();
> > +        }
> > +        catch (Exception e)
> > +        {
> > +            WebBeansUtil.throwRuntimeExceptions(e);
> > +        }
> > +        return result;
> > +    }
> > +
> > +
> >     public  Object createDependentScopedBeanProxy(OwbBean<?> bean, Object
> actualInstance, CreationalContext<?> creastionalContext)
> >     {
> >         Object result = null;
> >
> >
>
>

Re: svn commit: r1057407 - in /openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans: component/BuildInOwbBean.java proxy/JavassistProxyFactory.java

Posted by David Jencks <da...@yahoo.com>.
This didn't  compile, which I fixed in rev 1057448.  However there's a design problem in that the proxy choices are per-application since they are configured from OWBConfiguration.  Therefore the choices cannot be stored in a static map.  My change put the entire map of configuration info in every BuildinOwbBean which is also wasteful.

I would suggest either putting the configuration map into a service in WebBeansContext or simply parsing it in a static method each time a built in bean is created and passing in the type from the subclass constructor.

thanks
david jencks

On Jan 10, 2011, at 2:44 PM, yingwang@apache.org wrote:

> Author: yingwang
> Date: Mon Jan 10 22:44:57 2011
> New Revision: 1057407
> 
> URL: http://svn.apache.org/viewvc?rev=1057407&view=rev
> Log:
> [OWB-508] add abstract build in owb bean class
> 
> Added:
>    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java
> Modified:
>    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
> 
> Added: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java
> URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java?rev=1057407&view=auto
> ==============================================================================
> --- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java (added)
> +++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/BuildInOwbBean.java Mon Jan 10 22:44:57 2011
> @@ -0,0 +1,315 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.apache.webbeans.component;
> +
> +import java.io.IOException;
> +import java.io.ObjectInputStream;
> +import java.io.ObjectOutputStream;
> +import java.io.Serializable;
> +import java.lang.reflect.Constructor;
> +import java.lang.reflect.Method;
> +import java.security.AccessController;
> +import java.security.PrivilegedAction;
> +import java.util.HashMap;
> +
> +import javax.enterprise.context.spi.CreationalContext;
> +import javassist.util.proxy.MethodHandler;
> +import javassist.util.proxy.ProxyObject;
> +
> +import org.apache.webbeans.config.BeansDeployer;
> +import org.apache.webbeans.config.OpenWebBeansConfiguration;
> +import org.apache.webbeans.container.BeanManagerImpl;
> +import org.apache.webbeans.logger.WebBeansLogger;
> +import org.apache.webbeans.proxy.JavassistProxyFactory;
> +
> +/**
> + * Following 3 options are provided for vendor's build-in beans implementation:
> + * 
> + * 1. "none", means the build-in bean does not need a proxy wrapper.
> + * 2. "default", means the build-in bean needs OWB-provided default proxy wrapper.
> + * 3. A class name, which implements MethodHandler. This will allow vendor to 
> + *    customize the serialization behavior.
> + *    
> + * The default values for 4 build-in beans are "default". Following property could
> + * be used to change the default behavior:
> + * 
> + * Property Name:   org.apache.webbeans.component.BuildInOwbBean.property 
> + * Sample values:   UserTransation:none;Principal:default;Validation:com.mycompany.ValidationProxyHandler;ValidationFactory:default
> + *  
> + * @author yingwang
> + *
> + * @param <T>
> + */
> +public abstract class BuildInOwbBean<T> extends AbstractOwbBean<T>
> +{
> +
> +    //Logger instance
> +    private final WebBeansLogger logger = WebBeansLogger.getLogger(BeansDeployer.class);
> +
> +    
> +    private static HashMap<WebBeansType, String> proxyHandlerMap = new HashMap<WebBeansType, String>();
> +
> +    
> +    public static final String BUILD_IN_BEAN_PROPERTY = "org.apache.webbeans.component.BuildInOwbBean.property";
> +    
> +    /**
> +     * none means the build-in bean instance does not need proxy wrapper. This is used
> +     * for the build-in beans from vendors that are already serializable. 
> +     */
> +    private static final String PROXY_HANDLER_VALUE_NONE="none";
> +
> +    /**
> +     * default means the build-bin bean instance need a default proxy wrapper. And the
> +     * default proxy wrapper will get new instance from build in bean providers when
> +     * it is deserialized. 
> +     */
> +    private static final String PROXY_HANDLER_VALUE_DEFAULT="default";
> +
> +    /**
> +     * Initialize build-in config.
> +     */
> +    private static boolean initialized = initBuildInBeanConfig();
> +
> +    /**
> +     * The handler class name.
> +     */
> +    protected String handlerClassName;
> +    
> +    /**
> +     * The handler class.
> +     */
> +    protected Class handlerClass;
> +    
> +    
> +    protected Constructor handlerContructor;
> +    
> +    /**
> +     * Parse the custom property.
> +     * 
> +     * @return true
> +     */
> +    protected static boolean initBuildInBeanConfig() 
> +    {
> +        String s = OpenWebBeansConfiguration.getInstance().getProperty(BUILD_IN_BEAN_PROPERTY);
> +        proxyHandlerMap.put(WebBeansType.USERTRANSACTION, PROXY_HANDLER_VALUE_DEFAULT);
> +        proxyHandlerMap.put(WebBeansType.PRINCIPAL, PROXY_HANDLER_VALUE_DEFAULT);
> +        proxyHandlerMap.put(WebBeansType.VALIDATION, PROXY_HANDLER_VALUE_DEFAULT);
> +        proxyHandlerMap.put(WebBeansType.VALIDATIONFACT, PROXY_HANDLER_VALUE_DEFAULT);
> +        if (s != null && !s.equalsIgnoreCase("default"))
> +        {
> +            int i;
> +            String name;
> +            String value;
> +            String mapStrings[] = s.split(";");
> +            for(i=0; i<mapStrings.length; i++)
> +            {
> +                name = null;
> +                value = null;
> +                String pair[] = mapStrings[i].trim().split(":");
> +                if (pair.length == 2) 
> +                {
> +                    name = pair[0].trim();
> +                    value = pair[1].trim();
> +                }
> +                if (name == null || value == null || value.equalsIgnoreCase(PROXY_HANDLER_VALUE_DEFAULT)) 
> +                {
> +                    continue;
> +                }
> +                if (name.contains("UserTransaction"))
> +                {
> +                    proxyHandlerMap.put(WebBeansType.USERTRANSACTION, value);
> +                } 
> +                else if (name.contains("Principal"))
> +                {
> +                    proxyHandlerMap.put(WebBeansType.PRINCIPAL, value);
> +                }
> +                else if (name.contains("Validation"))
> +                {
> +                    proxyHandlerMap.put(WebBeansType.VALIDATION, value);
> +                } 
> +                else if (name.contains("ValidationFactory"))
> +                {
> +                    proxyHandlerMap.put(WebBeansType.VALIDATIONFACT, value);
> +                }
> +            } 
> +        } 
> +        return true;
> +    }
> +
> +    protected BuildInOwbBean(WebBeansType webBeanType)
> +    {
> +        this(webBeanType, null);
> +    }
> +
> +    @SuppressWarnings("unchecked")
> +    protected BuildInOwbBean(WebBeansType webBeansType, Class<T> returnType)
> +    {
> +        super(webBeansType, returnType);
> +        this.handlerClassName = proxyHandlerMap.get(this.getWebBeansType());
> +        if (handlerClassName.equalsIgnoreCase(PROXY_HANDLER_VALUE_NONE) ||
> +                handlerClassName.equalsIgnoreCase(PROXY_HANDLER_VALUE_DEFAULT)) 
> +        {
> +            return;
> +        }
> +
> +        // initialize the custom proxy handler class and its constructor.
> +        AccessController.doPrivileged(new PrivilegedAction<T>() 
> +        {
> +            BuildInOwbBean<T> buildinBean;
> +            
> +            public T run()
> +            {
> +                try 
> +                {
> +                    buildinBean.handlerClass = Class.forName(name);
> +                    buildinBean.handlerContructor = buildinBean.handlerClass.getConstructor(BuildInOwbBean.class, Object.class);
> +                    return null;
> +                } 
> +                catch (ClassNotFoundException e) 
> +                {
> +                    logger.error(e);
> +                } 
> +                catch (SecurityException e) 
> +                {
> +                    logger.error(e);
> +                } 
> +                catch (NoSuchMethodException e) 
> +                {
> +                    logger.error(e);
> +                }
> +                buildinBean.handlerClass = null;
> +                buildinBean.handlerContructor = null;
> +                return null;
> +            }
> +            
> +            protected PrivilegedAction<T> setBuildInBean(BuildInOwbBean<T> b) 
> +            {
> +                this.buildinBean = b;
> +                return this;
> +            }
> +            
> +        }.setBuildInBean(this));
> +    }
> +        
> +    /**
> +     * Create a dependent proxy wrapper around the actual build in bean instance.
> +     * 
> +     * @param actualInstance
> +     * @param creationalContext
> +     * @return
> +     */
> +    protected T createProxyWrapper(T actualInstance, CreationalContext<T> creationalContext)
> +    {
> +        if (handlerClassName.equals(PROXY_HANDLER_VALUE_NONE))
> +        {
> +            return actualInstance;
> +        }
> +        
> +        T proxy = (T)JavassistProxyFactory.getInstance().createBuildInBeanProxy(this);
> +        if (handlerClassName.equals(PROXY_HANDLER_VALUE_DEFAULT)) 
> +        {
> +            ((ProxyObject)proxy).setHandler(new BuildInBeanMethodHandler(this, actualInstance));
> +            return proxy;
> +        } 
> +        else if (handlerContructor != null)
> +        {
> +            try 
> +            {
> +                ((ProxyObject)proxy).setHandler( (MethodHandler)(handlerContructor.newInstance(this, actualInstance)));
> +                return proxy;
> +            } 
> +            catch (Exception e) 
> +            {
> +                logger.error(e);
> +            }
> +        }
> +        return null;
> +    }
> +    
> +
> +    protected abstract T createActualInstance(CreationalContext<T> creationalContext);
> +    
> +    
> +    /**
> +     * The default build in bean handler. 
> +     * 
> +     * @author yingwang
> +     *
> +     * @param <T>
> +     */
> +    public static class BuildInBeanMethodHandler<T> implements MethodHandler, Serializable
> +    {
> +
> +        /**
> +         * 
> +         */
> +        private static final long serialVersionUID = -2442900183095535369L;
> +
> +        BuildInOwbBean<T> bean;
> +        
> +        private T actualObject = null;
> +        
> +        //DO NOT REMOVE, used by failover and passivation.
> +        public BuildInBeanMethodHandler()
> +        {
> +        }
> +
> +        public BuildInBeanMethodHandler(BuildInOwbBean<T> bean, T actualObject) 
> +        {
> +            this.bean = bean;
> +            this.actualObject = actualObject;
> +        }    
> +        
> +        @Override
> +        public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable
> +        {
> +            if(proceed != null)       
> +            {
> +                return proceed.invoke(actualObject,args);
> +            } 
> +            else 
> +            {
> +                //interface method.
> +                return thisMethod.invoke(actualObject,args);
> +            }            
> +        }
> +
> +        private  void writeObject(ObjectOutputStream s) throws IOException
> +        {
> +            s.writeLong(serialVersionUID);
> +            s.writeObject(bean.getId());
> +        }    
> +        
> +        private  void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException
> +        {
> +            if(s.readLong() == serialVersionUID) 
> +            {
> +                String id = (String)s.readObject();
> +                bean = (BuildInOwbBean<T>)BeanManagerImpl.getManager().getPassivationCapableBean(id);
> +                // create new real instance after deserialized.
> +                actualObject = bean.createActualInstance(null);
> +            } 
> +            else 
> +            {
> +                throw new IOException("Serial version uid does not match.");
> +            }
> +        }    
> +
> +    }
> +}
> 
> Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
> URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java?rev=1057407&r1=1057406&r2=1057407&view=diff
> ==============================================================================
> --- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java (original)
> +++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java Mon Jan 10 22:44:57 2011
> @@ -60,6 +60,7 @@ public final class JavassistProxyFactory
> 
>     }
> 
> +    private ConcurrentMap<OwbBean<?>, Class<?>> buildInBeanProxyClasses = new ConcurrentHashMap<OwbBean<?>, Class<?>>();    
>     private ConcurrentMap<OwbBean<?>, Class<?>> normalScopedBeanProxyClasses = new ConcurrentHashMap<OwbBean<?>, Class<?>>();    
>     private ConcurrentMap<OwbBean<?>, Class<?>> dependentScopedBeanProxyClasses = new ConcurrentHashMap<OwbBean<?>, Class<?>>();    
>     private ConcurrentMap<OwbBean<?>, Class<?>> interceptorProxyClasses = new ConcurrentHashMap<OwbBean<?>, Class<?>>();
> @@ -221,6 +222,28 @@ public final class JavassistProxyFactory
>         return result;
>     }
> 
> +    public Object createBuildInBeanProxy(OwbBean<?> bean) 
> +    {
> +        Object result = null;
> +        try
> +        {
> +            Class<?> proxyClass = buildInBeanProxyClasses.get(bean);
> +            if (proxyClass == null)
> +            {
> +                ProxyFactory fact = createProxyFactory(bean);
> +                proxyClass = getProxyClass(fact);
> +                buildInBeanProxyClasses.putIfAbsent(bean, proxyClass);
> +            }
> +            result = proxyClass.newInstance();
> +        }
> +        catch (Exception e)
> +        {
> +            WebBeansUtil.throwRuntimeExceptions(e);
> +        }
> +        return result;
> +    }
> +
> +    
>     public  Object createDependentScopedBeanProxy(OwbBean<?> bean, Object actualInstance, CreationalContext<?> creastionalContext)
>     {
>         Object result = null;
> 
>