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; > >
