Hi! I now committed a simplified version with the same functionality. But remember that only can have 2 SingletonService for the WHOLE VM! So if you like to set a custom SingletonService twice, the WebBeansFinder will throw a ConfigurationException!
LieGrue, strub ----- Original Message ---- > From: Mark Struberg <[email protected]> > To: [email protected] > Sent: Thu, August 5, 2010 3:38:05 PM > Subject: Re: svn commit: r982578 - in >/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans: >config/WebBeansFinder.java corespi/DefaultSingletonService.java > > +1 for the idea in general, but the FINDER stuff looks a bit broken. What is >the > > reason to introduce aa anyway static member which acts as an indirection to >the > > SingletonService. There is only one instance allowed this way anyway, so we >can > > simply switch to make the singletonService member itself static. There is > imo >no > > difference - beside being slower and worse to read. > > And I'd prefer to have some configuration for defining the SingletonService. > > I know that it's not possible to use the 'singleton' ConfigService because >this > > needs the SingletonService , but I'll try to do a trick with 'manually' > bootstrapping the ConfigService first. > > LieGrue, > strub > > > > > ----- Original Message ---- > > From: "[email protected]" <[email protected]> > > To: [email protected] > > Sent: Thu, August 5, 2010 2:37:02 PM > > Subject: svn commit: r982578 - in > >/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans: > >config/WebBeansFinder.java corespi/DefaultSingletonService.java > > > > Author: gerdogdu > > Date: Thu Aug 5 12:37:01 2010 > > New Revision: 982578 > > > > URL: http://svn.apache.org/viewvc?rev=982578&view=rev > > Log: > > [OWB-432] Create Singleton Service SPI > > > > Added: > > >>openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/DefaultSingletonService.java >a > > > (with props) > > Modified: > > >>openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansFinder.java >a > > > > > > Modified: >>openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansFinder.java >a > > > > URL: : >>http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansFinder.java?rev=982578&r1=982577&r2=982578&view=diff >f > > > > >============================================================================== > > ; --- >>openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansFinder.java >a > > a (original) > > +++ >>openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansFinder.java >a > > Thu Aug 5 12:37:01 2010 > > @@ -18,14 +18,8 @@ > > */ > > package org.apache.webbeans.config; > > > > -import java.util.HashMap; > > -import java.util.IdentityHashMap; > > -import java.util.Map; > > -import java.util.Map.Entry; > > - > > -import org.apache.webbeans.exception.WebBeansException; > > -import org.apache.webbeans.util.Asserts; > > -import org.apache.webbeans.util.ClassUtil; > > +import org.apache.webbeans.corespi.DefaultSingletonService; > > +import org.apache.webbeans.spi.SingletonService; > > import org.apache.webbeans.util.WebBeansUtil; > > > > /** > > @@ -35,16 +29,15 @@ import org.apache.webbeans.util.WebBeans > > * @version $Rev$ $Date$ > > * > > */ > > -public final class WebBeansFinder > > +public final class WebBeansFinder implements SingletonService > > { > > - /** > > - * Keys --> ClassLoaders > > - * Values --> Maps of singleton class name with object > > - */ > > - private static Map<ClassLoader, Map<String, Object>> singletonMap = >new > > >HashMap<ClassLoader, Map<String,Object>>(); > > + //How you use singleton provider , > > + //As a default we use ClassLoader --> Object > > + private SingletonService singletonService = new > >DefaultSingletonService(); > > + > > + //VM based singleton finder instance > > + private static final WebBeansFinder FINDER = new WebBeansFinder(); > > > > - private static Map<Object, ClassLoader> objectToClassLoaderMap = new > > > >IdentityHashMap<Object, ClassLoader>(); > > - > > /** > > * No instantiate. > > */ > > @@ -53,138 +46,70 @@ public final class WebBeansFinder > > //No action > > } > > > > - /** > > - * Gets signelton instance. > > - * @param singletonName singleton class name > > - * @return singleton instance > > - */ > > public static Object getSingletonInstance(String singletonName) > > { > > - return getSingletonInstance(singletonName, > >WebBeansUtil.getCurrentClassLoader()); > > + return getSingletonInstance(singletonName, > >WebBeansUtil.getCurrentClassLoader()); > > } > > > > - /** > > - * Gets singleton instance for deployment. > > - * @param singletonName singleton class name > > - * @param classLoader classloader of the deployment > > - * @return signelton instance for this deployment > > - */ > > public static Object getSingletonInstance(String singletonName, > >ClassLoader classLoader) > > { > > - Object object = null; > > - > > - synchronized (singletonMap) > > - { > > - Map<String, Object> managerMap = >singletonMap.get(classLoader); > > - > > - if (managerMap == null) > > - { > > - managerMap = new HashMap<String, Object>(); > > - singletonMap.put(classLoader, managerMap); > > - } > > - > > - object = managerMap.get(singletonName); > > - /* No singleton for this application, create one */ > > - if (object == null) > > - { > > - try > > - { > > - //Load class > > - Class<?> clazz = > >ClassUtil.getClassFromName(singletonName); > > - if(clazz == null) > > - { > > - throw new ClassNotFoundException("Class with >name: " > > >+ singletonName + " is not found in the system"); > > - } > > - > > - //Create instance > > - object = clazz.newInstance(); > > - > > - //Save it > > - managerMap.put(singletonName, object); > > - > > - //Save it object --> classloader > > - objectToClassLoaderMap.put(object, classLoader); > > - > > - } > > - catch (InstantiationException e) > > - { > > - throw new WebBeansException("Unable to instantiate >class > > >: " + singletonName, e); > > - } > > - catch (IllegalAccessException e) > > - { > > - throw new WebBeansException("Illegal access >exception in > > >creating instance with class : " + singletonName, e); > > - } > > - catch (ClassNotFoundException e) > > - { > > - throw new WebBeansException("Class not found >exception > > >in creating instance with class : " + singletonName, e); > > - } > > - } > > - } > > - > > - return object; > > + return FINDER.get(classLoader, singletonName); > > } > > > > - /** > > - * Gets singleton instance if one already exists > > - * @param singletonName singleton class name > > - * @param cl classloader of the deployment > > - * @return singleton instance or null if one doesn't already exist > > - */ > > + > > public static Object getExistingSingletonInstance(String >singletonName, > > >ClassLoader cl) > > { > > - Object object = null; > > - synchronized (singletonMap) > > - { > > - Map<String, Object> managerMap = singletonMap.get(cl); > > - if (managerMap == null) > > - { > > - return null; > > - } > > - else > > - { > > - object = managerMap.get(singletonName); > > - } > > - } > > - return object; > > + return FINDER.getExist(cl, singletonName); > > } > > > > - /** > > - * Clear all deployment instances when the application is undeployed. > > - * @param classLoader of the deployment > > - */ > > public static void clearInstances(ClassLoader classLoader) > > { > > - Asserts.assertNotNull(classLoader, "classloader is null"); > > - synchronized (singletonMap) > > - { > > - Map<String, Object> objects = >singletonMap.remove(classLoader); > > - if(objects != null) > > - { > > - for(Entry<String, Object> entry : objects.entrySet()) > > - { > > - objectToClassLoaderMap.remove(entry.getValue()); > > - } > > - } > > - } > > + FINDER.clear(classLoader); > > } > > > > - /** > > - * Gets classloader with given singelton instance. > > - * @param object singleton instance > > - * @return the classloader that instance is created within > > - */ > > - public static ClassLoader getSingletonClassLoader(Object object) > > + public static Object getSingletonClassLoader(Object object) > > { > > - Asserts.assertNotNull(object, "object is null"); > > - synchronized (objectToClassLoaderMap) > > - { > > - if(objectToClassLoaderMap.containsKey(object)) > > - { > > - return objectToClassLoaderMap.get(object); > > - } > > - } > > - > > - return null; > > + return FINDER.getKey(object); > > } > > + > > + //Thirdt pary frameworks can set singleton instance > > + //For example, OpenEJB could provide its own provider > > + //Based on deployment > > + public synchronized void setSingletonService(SingletonService > >singletonService) > > + { > > + FINDER.singletonService = singletonService; > > + } > > + > > + @Override > > + public void clear(Object key) > > + { > > + this.singletonService.clear(key); > > + } > > + > > + @Override > > + public Object get(Object key, String singletonClassName) > > + { > > + return this.singletonService.get(key, singletonClassName); > > + } > > + > > + @Override > > + public Object getExist(Object key, String singletonClassName) > > + { > > + return this.singletonService.getExist(key, singletonClassName); > > + } > > + > > + @Override > > + public Object getKey(Object singleton) > > + { > > + return this.singletonService.getKey(singleton); > > + } > > + > > + @Override > > + public boolean isExist(Object key, String singletonClassName) > > + { > > + return this.singletonService.isExist(key, singletonClassName); > > + } > > + > > + > > > > } > > \ No newline at end of file > > > > Added: >>openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/DefaultSingletonService.java >a > > > > URL: >>http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/DefaultSingletonService.java?rev=982578&view=auto >o > > > > >============================================================================== > > ; --- - >>openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/DefaultSingletonService.java >a > > (added) > > +++ >>openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/DefaultSingletonService.java >a > > Thu Aug 5 12:37:01 2010 > > @@ -0,0 +1,239 @@ > > +/* > > + * 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.corespi; > > + > > +import java.util.HashMap; > > +import java.util.IdentityHashMap; > > +import java.util.Map; > > +import java.util.Map.Entry; > > + > > +import org.apache.webbeans.exception.WebBeansException; > > +import org.apache.webbeans.spi.SingletonService; > > +import org.apache.webbeans.util.Asserts; > > +import org.apache.webbeans.util.ClassUtil; > > +import org.apache.webbeans.util.WebBeansUtil; > > + > > +public class DefaultSingletonService implements SingletonService > > +{ > > + /** > > + * Keys --> ClassLoaders > > + * Values --> Maps of singleton class name with object > > + */ > > + private final Map<ClassLoader, Map<String, Object>> singletonMap = >new > > >HashMap<ClassLoader, Map<String,Object>>(); > > + > > + private final Map<Object, ClassLoader> objectToClassLoaderMap = new > >IdentityHashMap<Object, ClassLoader>(); > > + > > + > > + /** > > + * Gets signelton instance. > > + * @param singletonName singleton class name > > + * @return singleton instance > > + */ > > + public Object getSingletonInstance(String singletonName) > > + { > > + return getSingletonInstance(singletonName, > >WebBeansUtil.getCurrentClassLoader()); > > + } > > + > > + /** > > + * Gets singleton instance for deployment. > > + * @param singletonName singleton class name > > + * @param classLoader classloader of the deployment > > + * @return signelton instance for this deployment > > + */ > > + public Object getSingletonInstance(String singletonName, ClassLoader > >classLoader) > > + { > > + Object object = null; > > + > > + synchronized (singletonMap) > > + { > > + Map<String, Object> managerMap = >singletonMap.get(classLoader); > > + > > + if (managerMap == null) > > + { > > + managerMap = new HashMap<String, Object>(); > > + singletonMap.put(classLoader, managerMap); > > + } > > + > > + object = managerMap.get(singletonName); > > + /* No singleton for this application, create one */ > > + if (object == null) > > + { > > + try > > + { > > + //Load class > > + Class<?> clazz = > >ClassUtil.getClassFromName(singletonName); > > + if(clazz == null) > > + { > > + throw new ClassNotFoundException("Class with >name: " > > >+ singletonName + " is not found in the system"); > > + } > > + > > + //Create instance > > + object = clazz.newInstance(); > > + > > + //Save it > > + managerMap.put(singletonName, object); > > + > > + //Save it object --> classloader > > + objectToClassLoaderMap.put(object, classLoader); > > + > > + } > > + catch (InstantiationException e) > > + { > > + throw new WebBeansException("Unable to instantiate >class > > >: " + singletonName, e); > > + } > > + catch (IllegalAccessException e) > > + { > > + throw new WebBeansException("Illegal access >exception in > > >creating instance with class : " + singletonName, e); > > + } > > + catch (ClassNotFoundException e) > > + { > > + throw new WebBeansException("Class not found >exception > > >in creating instance with class : " + singletonName, e); > > + } > > + } > > + } > > + > > + return object; > > + } > > + > > + /** > > + * Gets singleton instance if one already exists > > + * @param singletonName singleton class name > > + * @param cl classloader of the deployment > > + * @return singleton instance or null if one doesn't already exist > > + */ > > + public Object getExistingSingletonInstance(String singletonName, > >ClassLoader cl) > > + { > > + Object object = null; > > + synchronized (singletonMap) > > + { > > + Map<String, Object> managerMap = singletonMap.get(cl); > > + if (managerMap == null) > > + { > > + return null; > > + } > > + else > > + { > > + object = managerMap.get(singletonName); > > + } > > + } > > + return object; > > + } > > + > > + /** > > + * Clear all deployment instances when the application is >undeployed. > > + * @param classLoader of the deployment > > + */ > > + public void clearInstances(ClassLoader classLoader) > > + { > > + Asserts.assertNotNull(classLoader, "classloader is null"); > > + synchronized (singletonMap) > > + { > > + Map<String, Object> objects = >singletonMap.remove(classLoader); > > + if(objects != null) > > + { > > + for(Entry<String, Object> entry : objects.entrySet()) > > + { > > + objectToClassLoaderMap.remove(entry.getValue()); > > + } > > + } > > + } > > + } > > + > > + /** > > + * Gets classloader with given singelton instance. > > + * @param object singleton instance > > + * @return the classloader that instance is created within > > + */ > > + public ClassLoader getSingletonClassLoader(Object object) > > + { > > + Asserts.assertNotNull(object, "object is null"); > > + synchronized (objectToClassLoaderMap) > > + { > > + if(objectToClassLoaderMap.containsKey(object)) > > + { > > + return objectToClassLoaderMap.get(object); > > + } > > + } > > + > > + return null; > > + } > > + > > + > > + /** > > + * {...@inheritdoc} > > + */ > > + @Override > > + public void clear(Object classLoader) > > + { > > + assertClassLoaderKey(classLoader); > > + clearInstances((ClassLoader)classLoader); > > + } > > + > > + /** > > + * {...@inheritdoc} > > + */ > > + @Override > > + public Object get(Object key, String singletonClassName) > > + { > > + assertClassLoaderKey(key); > > + return getSingletonInstance(singletonClassName, (ClassLoader)key); > > + } > > + > > + /** > > + * {...@inheritdoc} > > + */ > > + @Override > > + public Object getExist(Object key, String singletonClassName) > > + { > > + assertClassLoaderKey(key); > > + return getExistingSingletonInstance(singletonClassName, > >(ClassLoader)key); > > + } > > + > > + /** > > + * {...@inheritdoc} > > + */ > > + @Override > > + public boolean isExist(Object key, String singletonClassName) > > + { > > + assertClassLoaderKey(key); > > + return getExistingSingletonInstance(singletonClassName, > >(ClassLoader)key) != null ? true : false; > > + } > > + > > + /** > > + * {...@inheritdoc} > > + */ > > + @Override > > + public ClassLoader getKey(Object singleton) > > + { > > + return getSingletonClassLoader(singleton); > > + } > > + > > + /** > > + * Assert that key is classloader instance. > > + * @param key key > > + */ > > + private void assertClassLoaderKey(Object key) > > + { > > + if(!(key instanceof ClassLoader)) > > + { > > + throw new IllegalArgumentException("Key instance must be > >ClassLoader for using DefaultSingletonService"); > > + } > > + } > > + > > +} > > > > Propchange: >>openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/DefaultSingletonService.java >a > > > > >------------------------------------------------------------------------------ > > ; svn:eol-style = native > > > > > > > > > >
