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 <[email protected]>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, [email protected] 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; > > > > > >
