You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2010/08/05 21:32:40 UTC
svn commit: r982743 [3/3] - in /myfaces/core/trunk/impl: ./
src/main/java/org/apache/myfaces/commons/
src/main/java/org/apache/myfaces/commons/discovery/
src/main/java/org/apache/myfaces/commons/discovery/jdk/
src/main/java/org/apache/myfaces/commons/d...
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/EnvironmentCache.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/EnvironmentCache.java?rev=982743&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/EnvironmentCache.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/EnvironmentCache.java Thu Aug 5 19:32:38 2010
@@ -0,0 +1,122 @@
+/*
+ * 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.myfaces.commons.discovery.tools;
+
+import java.util.HashMap;
+
+import org.apache.myfaces.commons.discovery.jdk.JDKHooks;
+
+
+/**
+ * Cache by a 'key' unique to the environment:
+ *
+ * - ClassLoader::groupContext::Object Cache
+ * Cache : HashMap
+ * Key : Thread Context Class Loader (<code>ClassLoader</code>)
+ * Value : groupContext::SPI Cache (<code>HashMap</code>)
+ *
+ * //- groupContext::Object Cache
+ * // Cache : HashMap
+ * // Key : groupContext (<code>String</code>)
+ * // Value : <code>Object</code>
+ *
+ * When we 'release', it is expected that the caller of the 'release'
+ * have the same thread context class loader... as that will be used
+ * to identify cached entries to be released.
+ *
+ * @author Richard A. Sitze
+ */
+public class EnvironmentCache {
+ /**
+ * Allows null key, important as default groupContext is null.
+ *
+ * We will manage synchronization directly, so all caches are implemented
+ * as HashMap (unsynchronized).
+ *
+ */
+ private static final HashMap root_cache = new HashMap();
+
+ /**
+ * Initial hash size for SPI's, default just seem TO big today..
+ */
+ public static final int smallHashSize = 13;
+
+ /**
+ * Get object keyed by classLoader.
+ */
+ public static synchronized Object get(ClassLoader classLoader)
+ {
+ /**
+ * 'null' (bootstrap/system class loader) thread context class loader
+ * is ok... Until we learn otherwise.
+ */
+ return root_cache.get(classLoader);
+ }
+
+ /**
+ * Put service keyed by spi & classLoader.
+ */
+ public static synchronized void put(ClassLoader classLoader, Object object)
+ {
+ /**
+ * 'null' (bootstrap/system class loader) thread context class loader
+ * is ok... Until we learn otherwise.
+ */
+ if (object != null) {
+ root_cache.put(classLoader, object);
+ }
+ }
+
+
+ /********************** CACHE-MANAGEMENT SUPPORT **********************/
+
+ /**
+ * Release all internal references to previously created service
+ * instances associated with the current thread context class loader.
+ * The <code>release()</code> method is called for service instances that
+ * implement the <code>Service</code> interface.
+ *
+ * This is useful in environments like servlet containers,
+ * which implement application reloading by throwing away a ClassLoader.
+ * Dangling references to objects in that class loader would prevent
+ * garbage collection.
+ */
+ public static synchronized void release() {
+ /**
+ * 'null' (bootstrap/system class loader) thread context class loader
+ * is ok... Until we learn otherwise.
+ */
+ root_cache.remove(JDKHooks.getJDKHooks().getThreadContextClassLoader());
+ }
+
+
+ /**
+ * Release any internal references to a previously created service
+ * instance associated with the current thread context class loader.
+ * If the SPI instance implements <code>Service</code>, then call
+ * <code>release()</code>.
+ */
+ public static synchronized void release(ClassLoader classLoader) {
+ /**
+ * 'null' (bootstrap/system class loader) thread context class loader
+ * is ok... Until we learn otherwise.
+ */
+ root_cache.remove(classLoader);
+ }
+}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/ManagedProperties.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/ManagedProperties.java?rev=982743&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/ManagedProperties.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/ManagedProperties.java Thu Aug 5 19:32:38 2010
@@ -0,0 +1,362 @@
+/*
+ * 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.myfaces.commons.discovery.tools;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.myfaces.commons.discovery.jdk.JDKHooks;
+
+
+
+/**
+ * <p>This class may disappear in the future, or be moved to another project..
+ * </p>
+ *
+ * <p>Extend the concept of System properties to a hierarchical scheme
+ * based around class loaders. System properties are global in nature,
+ * so using them easily violates sound architectural and design principles
+ * for maintaining separation between components and runtime environments.
+ * Nevertheless, there is a need for properties broader in scope than
+ * class or class instance scope.
+ * </p>
+ *
+ * <p>This class is one solution.
+ * </p>
+ *
+ * <p>Manage properties according to a secure
+ * scheme similar to that used by classloaders:
+ * <ul>
+ * <li><code>ClassLoader</code>s are organized in a tree hierarchy.</li>
+ * <li>each <code>ClassLoader</code> has a reference
+ * to a parent <code>ClassLoader</code>.</li>
+ * <li>the root of the tree is the bootstrap <code>ClassLoader</code>er.</li>
+ * <li>the youngest decendent is the thread context class loader.</li>
+ * <li>properties are bound to a <code>ClassLoader</code> instance
+ * <ul>
+ * <li><i>non-default</i> properties bound to a parent <code>ClassLoader</code>
+ * instance take precedence over all properties of the same name bound
+ * to any decendent.
+ * Just to confuse the issue, this is the default case.</li>
+ * <li><i>default</i> properties bound to a parent <code>ClassLoader</code>
+ * instance may be overriden by (default or non-default) properties of
+ * the same name bound to any decendent.
+ * </li>
+ * </ul>
+ * </li>
+ * <li>System properties take precedence over all other properties</li>
+ * </ul>
+ * </p>
+ *
+ * <p>This is not a perfect solution, as it is possible that
+ * different <code>ClassLoader</code>s load different instances of
+ * <code>ScopedProperties</code>. The 'higher' this class is loaded
+ * within the <code>ClassLoader</code> hierarchy, the more usefull
+ * it will be.
+ * </p>
+ *
+ * @author Richard A. Sitze
+ */
+public class ManagedProperties {
+ private static Logger log = Logger.getLogger(ManagedProperties.class.getName());
+ public static void setLog(Logger _log) {
+ log = _log;
+ }
+
+ /**
+ * Cache of Properties, keyed by (thread-context) class loaders.
+ * Use <code>HashMap</code> because it allows 'null' keys, which
+ * allows us to account for the (null) bootstrap classloader.
+ */
+ private static final HashMap propertiesCache = new HashMap();
+
+
+ /**
+ * Get value for property bound to the current thread context class loader.
+ *
+ * @param propertyName property name.
+ * @return property value if found, otherwise default.
+ */
+ public static String getProperty(String propertyName) {
+ return getProperty(getThreadContextClassLoader(), propertyName);
+ }
+
+ /**
+ * Get value for property bound to the current thread context class loader.
+ * If not found, then return default.
+ *
+ * @param propertyName property name.
+ * @param dephault default value.
+ * @return property value if found, otherwise default.
+ */
+ public static String getProperty(String propertyName, String dephault) {
+ return getProperty(getThreadContextClassLoader(), propertyName, dephault);
+ }
+
+ /**
+ * Get value for property bound to the class loader.
+ *
+ * @param classLoader
+ * @param propertyName property name.
+ * @return property value if found, otherwise default.
+ */
+ public static String getProperty(ClassLoader classLoader, String propertyName) {
+ String value = JDKHooks.getJDKHooks().getSystemProperty(propertyName);
+ if (value == null) {
+ Value val = getValueProperty(classLoader, propertyName);
+ if (val != null) {
+ value = val.value;
+ }
+ } else if (log.isLoggable(Level.FINE)) {
+ log.fine("found System property '" + propertyName + "'" +
+ " with value '" + value + "'.");
+ }
+ return value;
+ }
+
+ /**
+ * Get value for property bound to the class loader.
+ * If not found, then return default.
+ *
+ * @param classLoader
+ * @param propertyName property name.
+ * @param dephault default value.
+ * @return property value if found, otherwise default.
+ */
+ public static String getProperty(ClassLoader classLoader, String propertyName, String dephault) {
+ String value = getProperty(classLoader, propertyName);
+ return (value == null) ? dephault : value;
+ }
+
+ /**
+ * Set value for property bound to the current thread context class loader.
+ * @param propertyName property name
+ * @param value property value (non-default) If null, remove the property.
+ */
+ public static void setProperty(String propertyName, String value) {
+ setProperty(propertyName, value, false);
+ }
+
+ /**
+ * Set value for property bound to the current thread context class loader.
+ * @param propertyName property name
+ * @param value property value. If null, remove the property.
+ * @param isDefault determines if property is default or not.
+ * A non-default property cannot be overriden.
+ * A default property can be overriden by a property
+ * (default or non-default) of the same name bound to
+ * a decendent class loader.
+ */
+ public static void setProperty(String propertyName, String value, boolean isDefault) {
+ if (propertyName != null) {
+ synchronized (propertiesCache) {
+ ClassLoader classLoader = getThreadContextClassLoader();
+ HashMap properties = (HashMap)propertiesCache.get(classLoader);
+
+ if (value == null) {
+ if (properties != null) {
+ properties.remove(propertyName);
+ }
+ } else {
+ if (properties == null) {
+ properties = new HashMap();
+ propertiesCache.put(classLoader, properties);
+ }
+
+ properties.put(propertyName, new Value(value, isDefault));
+ }
+ }
+ }
+ }
+
+ /**
+ * Set property values for <code>Properties</code> bound to the
+ * current thread context class loader.
+ *
+ * @param newProperties name/value pairs to be bound
+ */
+ public static void setProperties(Map newProperties) {
+ setProperties(newProperties, false);
+ }
+
+
+ /**
+ * Set property values for <code>Properties</code> bound to the
+ * current thread context class loader.
+ *
+ * @param newProperties name/value pairs to be bound
+ * @param isDefault determines if properties are default or not.
+ * A non-default property cannot be overriden.
+ * A default property can be overriden by a property
+ * (default or non-default) of the same name bound to
+ * a decendent class loader.
+ */
+ public static void setProperties(Map newProperties, boolean isDefault) {
+ java.util.Iterator it = newProperties.entrySet().iterator();
+
+ /**
+ * Each entry must be mapped to a Property.
+ * 'setProperty' does this for us.
+ */
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry)it.next();
+ setProperty( String.valueOf(entry.getKey()),
+ String.valueOf(entry.getValue()),
+ isDefault);
+ }
+ }
+
+
+ /**
+ * Return list of all property names. This is an expensive
+ * operation: ON EACH CALL it walks through all property lists
+ * associated with the current context class loader upto
+ * and including the bootstrap class loader.
+ */
+ public static Enumeration propertyNames() {
+ Hashtable allProps = new Hashtable();
+
+ ClassLoader classLoader = getThreadContextClassLoader();
+
+ /**
+ * Order doesn't matter, we are only going to use
+ * the set of all keys...
+ */
+ while (true) {
+ HashMap properties = null;
+
+ synchronized (propertiesCache) {
+ properties = (HashMap)propertiesCache.get(classLoader);
+ }
+
+ if (properties != null) {
+ allProps.putAll(properties);
+ }
+
+ if (classLoader == null) break;
+
+ classLoader = getParent(classLoader);
+ }
+
+ return allProps.keys();
+ }
+
+ /**
+ * This is an expensive operation.
+ * ON EACH CALL it walks through all property lists
+ * associated with the current context class loader upto
+ * and including the bootstrap class loader.
+ *
+ * @return Returns a <code>java.util.Properties</code> instance
+ * that is equivalent to the current state of the scoped
+ * properties, in that getProperty() will return the same value.
+ * However, this is a copy, so setProperty on the
+ * returned value will not effect the scoped properties.
+ */
+ public static Properties getProperties() {
+ Properties p = new Properties();
+
+ Enumeration names = propertyNames();
+ while (names.hasMoreElements()) {
+ String name = (String)names.nextElement();
+ p.put(name, getProperty(name));
+ }
+
+ return p;
+ }
+
+
+ /***************** INTERNAL IMPLEMENTATION *****************/
+
+ private static class Value {
+ final String value;
+ final boolean isDefault;
+
+ Value(String value, boolean isDefault) {
+ this.value = value;
+ this.isDefault = isDefault;
+ }
+ }
+
+ /**
+ * Get value for properties bound to the class loader.
+ * Explore up the tree first, as higher-level class
+ * loaders take precedence over lower-level class loaders.
+ */
+ private static final Value getValueProperty(ClassLoader classLoader, String propertyName) {
+ Value value = null;
+
+ if (propertyName != null) {
+ /**
+ * If classLoader isn't bootstrap loader (==null),
+ * then get up-tree value.
+ */
+ if (classLoader != null) {
+ value = getValueProperty(getParent(classLoader), propertyName);
+ }
+
+ if (value == null || value.isDefault) {
+ synchronized (propertiesCache) {
+ HashMap properties = (HashMap)propertiesCache.get(classLoader);
+
+ if (properties != null) {
+ Value altValue = (Value)properties.get(propertyName);
+
+ // set value only if override exists..
+ // otherwise pass default (or null) on..
+ if (altValue != null) {
+ value = altValue;
+
+ if (log.isLoggable(Level.FINE)) {
+ log.fine("found Managed property '" + propertyName + "'" +
+ " with value '" + value + "'" +
+ " bound to classloader " + classLoader + ".");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return value;
+ }
+
+ private static final ClassLoader getThreadContextClassLoader() {
+ return JDKHooks.getJDKHooks().getThreadContextClassLoader();
+ }
+
+ private static final ClassLoader getParent(final ClassLoader classLoader) {
+ return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ return classLoader.getParent();
+ } catch (SecurityException se){
+ return null;
+ }
+ }
+ });
+ }
+}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/PropertiesHolder.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/PropertiesHolder.java?rev=982743&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/PropertiesHolder.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/PropertiesHolder.java Thu Aug 5 19:32:38 2010
@@ -0,0 +1,67 @@
+/*
+ * 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.myfaces.commons.discovery.tools;
+
+import java.util.Properties;
+
+import org.apache.myfaces.commons.discovery.resource.ClassLoaders;
+
+
+/**
+ * Holder for a default class.
+ *
+ * Class may be specified by name (String) or class (Class).
+ * Using the holder complicates the users job, but minimized # of API's.
+ *
+ * @author Richard A. Sitze
+ */
+public class PropertiesHolder {
+ private Properties properties;
+ private final String propertiesFileName;
+
+ public PropertiesHolder(Properties properties) {
+ this.properties = properties;
+ this.propertiesFileName = null;
+ }
+
+ public PropertiesHolder(String propertiesFileName) {
+ this.properties = null;
+ this.propertiesFileName = propertiesFileName;
+ }
+
+ /**
+ * @param spi Optional SPI (may be null).
+ * If provided, an attempt is made to load the
+ * property file as-per Class.getResource().
+ *
+ * @param loaders Used only if properties need to be loaded.
+ *
+ * @return Properties. Load the properties if necessary.
+ */
+ public Properties getProperties(SPInterface spi, ClassLoaders loaders) {
+ if (properties == null) {
+ properties = ResourceUtils.loadProperties(spi.getSPClass(), getPropertiesFileName(), loaders);
+ }
+ return properties;
+ }
+
+ public String getPropertiesFileName() {
+ return propertiesFileName;
+ }
+}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/ResourceUtils.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/ResourceUtils.java?rev=982743&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/ResourceUtils.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/ResourceUtils.java Thu Aug 5 19:32:38 2010
@@ -0,0 +1,153 @@
+/*
+ * 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.myfaces.commons.discovery.tools;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.apache.myfaces.commons.discovery.DiscoveryException;
+import org.apache.myfaces.commons.discovery.Resource;
+import org.apache.myfaces.commons.discovery.ResourceIterator;
+import org.apache.myfaces.commons.discovery.resource.ClassLoaders;
+import org.apache.myfaces.commons.discovery.resource.DiscoverResources;
+
+
+/**
+ * Mechanisms to locate and load a class.
+ * The load methods locate a class only.
+ * The find methods locate a class and verify that the
+ * class implements an given interface or extends a given class.
+ *
+ * @author Richard A. Sitze
+ * @author Craig R. McClanahan
+ * @author Costin Manolache
+ */
+public class ResourceUtils {
+ /**
+ * Get package name.
+ * Not all class loaders 'keep' package information,
+ * in which case Class.getPackage() returns null.
+ * This means that calling Class.getPackage().getName()
+ * is unreliable at best.
+ */
+ public static String getPackageName(Class clazz) {
+ Package clazzPackage = clazz.getPackage();
+ String packageName;
+ if (clazzPackage != null) {
+ packageName = clazzPackage.getName();
+ } else {
+ String clazzName = clazz.getName();
+ packageName = new String(clazzName.toCharArray(), 0, clazzName.lastIndexOf('.'));
+ }
+ return packageName;
+ }
+
+
+ /**
+ * Load the resource <code>resourceName</code>.
+ * Try each classloader in succession,
+ * until first succeeds, or all fail.
+ * If all fail and <code>resouceName</code> is not absolute
+ * (doesn't start with '/' character), then retry with
+ * <code>packageName/resourceName</code> after changing all
+ * '.' to '/'.
+ *
+ * @param resourceName The name of the resource to load.
+ */
+ public static Resource getResource(Class spi,
+ String resourceName,
+ ClassLoaders loaders)
+ throws DiscoveryException
+ {
+ DiscoverResources explorer = new DiscoverResources(loaders);
+ ResourceIterator resources = explorer.findResources(resourceName);
+
+ if (spi != null &&
+ !resources.hasNext() &&
+ resourceName.charAt(0) != '/')
+ {
+ /**
+ * If we didn't find the resource, and if the resourceName
+ * isn't an 'absolute' path name, then qualify with
+ * package name of the spi.
+ */
+ resourceName = getPackageName(spi).replace('.','/') + "/" + resourceName;
+ resources = explorer.findResources(resourceName);
+ }
+
+ return resources.hasNext()
+ ? resources.nextResource()
+ : null;
+ }
+
+ /**
+ * Load named property file, optionally qualifed by spi's package name
+ * as per Class.getResource.
+ *
+ * A property file is loaded using the following sequence of class loaders:
+ * <ul>
+ * <li>Thread Context Class Loader</li>
+ * <li>DiscoverSingleton's Caller's Class Loader</li>
+ * <li>SPI's Class Loader</li>
+ * <li>DiscoverSingleton's (this class) Class Loader</li>
+ * <li>System Class Loader</li>
+ * </ul>
+ *
+ * @param propertiesFileName The property file name.
+ *
+ * @return Instance of a class implementing the SPI.
+ *
+ * @exception DiscoveryException Thrown if the name of a class implementing
+ * the SPI cannot be found, if the class cannot be loaded and
+ * instantiated, or if the resulting class does not implement
+ * (or extend) the SPI.
+ */
+ public static Properties loadProperties(Class spi,
+ String propertiesFileName,
+ ClassLoaders classLoaders)
+ throws DiscoveryException
+ {
+ Properties properties = null;
+
+ if (propertiesFileName != null) {
+ try {
+ Resource resource = getResource(spi, propertiesFileName, classLoaders);
+ if (resource != null) {
+ InputStream stream = resource.getResourceAsStream();
+
+ if (stream != null) {
+ properties = new Properties();
+ try {
+ properties.load(stream);
+ } finally {
+ stream.close();
+ }
+ }
+ }
+ } catch (IOException e) {
+ // ignore
+ } catch (SecurityException e) {
+ // ignore
+ }
+ }
+
+ return properties;
+ }
+}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/SPInterface.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/SPInterface.java?rev=982743&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/SPInterface.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/SPInterface.java Thu Aug 5 19:32:38 2010
@@ -0,0 +1,160 @@
+/*
+ * 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.myfaces.commons.discovery.tools;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.myfaces.commons.discovery.DiscoveryException;
+
+
+/**
+ * Represents a Service Programming Interface (spi).
+ * - SPI's name
+ * - SPI's (provider) class
+ * - SPI's (alternate) override property name
+ *
+ * In addition, while there are many cases where this is NOT
+ * usefull, for those in which it is:
+ *
+ * - expected constructor argument types and parameters values.
+ *
+ * @author Richard A. Sitze
+ */
+public class SPInterface {
+ /**
+ * The service programming interface: intended to be
+ * an interface or abstract class, but not limited
+ * to those two.
+ */
+ private final Class spi;
+
+ /**
+ * The property name to be used for finding the name of
+ * the SPI implementation class.
+ */
+ private final String propertyName;
+
+
+ private Class paramClasses[] = null;
+ private Object params[] = null;
+
+
+ /**
+ * Construct object representing Class <code>provider</code>.
+ *
+ * @param provider The SPI class
+ */
+ public SPInterface(Class provider) {
+ this(provider, provider.getName());
+ }
+
+ /**
+ * Construct object representing Class <code>provider</code>.
+ *
+ * @param spi The SPI class
+ *
+ * @param propertyName when looking for the name of a class implementing
+ * the provider class, a discovery strategy may involve looking for
+ * (system or other) properties having either the name of the class
+ * (provider) or the <code>propertyName</code>.
+ */
+ public SPInterface(Class spi, String propertyName) {
+ this.spi = spi;
+ this.propertyName = propertyName;
+ }
+
+ /**
+ * Construct object representing Class <code>provider</code>.
+ *
+ * @param provider The SPI class
+ *
+ * @param constructorParamClasses classes representing the
+ * constructor argument types.
+ *
+ * @param constructorParams objects representing the
+ * constructor arguments.
+ */
+ public SPInterface(Class provider,
+ Class constructorParamClasses[],
+ Object constructorParams[])
+ {
+ this(provider,
+ provider.getName(),
+ constructorParamClasses,
+ constructorParams);
+ }
+
+ /**
+ * Construct object representing Class <code>provider</code>.
+ *
+ * @param spi The SPI class
+ *
+ * @param propertyName when looking for the name of a class implementing
+ * the provider class, a discovery strategy may involve looking for
+ * (system or other) properties having either the name of the class
+ * (provider) or the <code>propertyName</code>.
+ *
+ * @param constructorParamClasses classes representing the
+ * constructor argument types.
+ *
+ * @param constructorParams objects representing the
+ * constructor arguments.
+ */
+ public SPInterface(Class spi,
+ String propertyName,
+ Class constructorParamClasses[],
+ Object constructorParams[])
+ {
+ this.spi = spi;
+ this.propertyName = propertyName;
+ this.paramClasses = constructorParamClasses;
+ this.params = constructorParams;
+ }
+
+ public String getSPName() {
+ return spi.getName();
+ }
+
+ public Class getSPClass() {
+ return spi;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ /**
+ * Instantiate a new
+ */
+ public Object newInstance(Class impl)
+ throws DiscoveryException,
+ InstantiationException,
+ IllegalAccessException,
+ NoSuchMethodException,
+ InvocationTargetException
+ {
+ verifyAncestory(impl);
+
+ return ClassUtils.newInstance(impl, paramClasses, params);
+ }
+
+ public void verifyAncestory(Class impl) {
+ ClassUtils.verifyAncestory(spi, impl);
+ }
+}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/Service.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/Service.java?rev=982743&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/Service.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/commons/discovery/tools/Service.java Thu Aug 5 19:32:38 2010
@@ -0,0 +1,123 @@
+/*
+ * 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.myfaces.commons.discovery.tools;
+
+import java.util.Enumeration;
+
+import org.apache.myfaces.commons.discovery.ResourceClass;
+import org.apache.myfaces.commons.discovery.ResourceClassIterator;
+import org.apache.myfaces.commons.discovery.ResourceNameIterator;
+import org.apache.myfaces.commons.discovery.resource.ClassLoaders;
+import org.apache.myfaces.commons.discovery.resource.classes.DiscoverClasses;
+import org.apache.myfaces.commons.discovery.resource.names.DiscoverServiceNames;
+
+
+/**
+ * [this was ServiceDiscovery12... the 1.1 versus 1.2 issue
+ * has been abstracted to org.apache.commons.discover.jdk.JDKHooks]
+ *
+ * <p>Implement the JDK1.3 'Service Provider' specification.
+ * ( http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html )
+ * </p>
+ *
+ * This class supports any VM, including JDK1.1, via
+ * org.apache.commons.discover.jdk.JDKHooks.
+ *
+ * The caller will first configure the discoverer by adding ( in the desired
+ * order ) all the places to look for the META-INF/services. Currently
+ * we support loaders.
+ *
+ * The findResources() method will check every loader.
+ *
+ * @author Richard A. Sitze
+ * @author Craig R. McClanahan
+ * @author Costin Manolache
+ * @author James Strachan
+ */
+public class Service
+{
+ /** Construct a new service discoverer
+ */
+ protected Service() {
+ }
+
+ /**
+ * as described in
+ * sun/jdk1.3.1/docs/guide/jar/jar.html#Service Provider,
+ * Except this uses <code>Enumeration</code>
+ * instead of <code>Interator</code>.
+ *
+ * @return Enumeration of class instances (<code>Object</code>)
+ */
+ public static Enumeration providers(Class spiClass) {
+ return providers(new SPInterface(spiClass), null);
+ }
+
+ /**
+ * This version lets you specify constructor arguments..
+ *
+ * @param spi SPI to look for and load.
+ * @param loaders loaders to use in search.
+ * If <code>null</code> then use ClassLoaders.getAppLoaders().
+ */
+ public static Enumeration providers(final SPInterface spi,
+ ClassLoaders loaders)
+ {
+ if (loaders == null) {
+ loaders = ClassLoaders.getAppLoaders(spi.getSPClass(),
+ Service.class,
+ true);
+ }
+
+ ResourceNameIterator servicesIter =
+ (new DiscoverServiceNames(loaders)).findResourceNames(spi.getSPName());
+
+ final ResourceClassIterator services =
+ (new DiscoverClasses(loaders)).findResourceClasses(servicesIter);
+
+ return new Enumeration() {
+ private Object object = null;
+
+ public boolean hasMoreElements() {
+ if (object == null) {
+ object = getNextClassInstance();
+ }
+ return object != null;
+ }
+
+ public Object nextElement() {
+ Object obj = object;
+ object = null;
+ return obj;
+ }
+
+ private Object getNextClassInstance() {
+ while (services.hasNext()) {
+ ResourceClass info = services.nextResourceClass();
+ try {
+ return spi.newInstance(info.loadClass());
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ return null;
+ }
+ };
+ }
+}
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/annotation/DefaultLifecycleProviderFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/annotation/DefaultLifecycleProviderFactory.java?rev=982743&r1=982742&r2=982743&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/annotation/DefaultLifecycleProviderFactory.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/annotation/DefaultLifecycleProviderFactory.java Thu Aug 5 19:32:38 2010
@@ -25,10 +25,10 @@ import java.security.PrivilegedActionExc
import java.security.PrivilegedExceptionAction;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.apache.commons.discovery.resource.ClassLoaders;
-import org.apache.commons.discovery.resource.names.DiscoverServiceNames;
-import org.apache.commons.discovery.ResourceNameIterator;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
+import org.apache.myfaces.commons.discovery.ResourceNameIterator;
+import org.apache.myfaces.commons.discovery.resource.ClassLoaders;
+import org.apache.myfaces.commons.discovery.resource.names.DiscoverServiceNames;
import org.apache.myfaces.shared_impl.util.ClassUtils;
import javax.faces.FacesException;
@@ -37,9 +37,6 @@ import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
-import org.apache.commons.discovery.ResourceNameIterator;
-import org.apache.commons.discovery.resource.ClassLoaders;
-import org.apache.commons.discovery.resource.names.DiscoverServiceNames;
import org.apache.myfaces.shared_impl.util.ClassUtils;
/*
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/annotation/LifecycleProviderFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/annotation/LifecycleProviderFactory.java?rev=982743&r1=982742&r2=982743&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/annotation/LifecycleProviderFactory.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/annotation/LifecycleProviderFactory.java Thu Aug 5 19:32:38 2010
@@ -21,7 +21,7 @@ package org.apache.myfaces.config.annota
import java.security.AccessController;
import java.security.PrivilegedActionException;
-import org.apache.commons.discovery.tools.DiscoverSingleton;
+import org.apache.myfaces.commons.discovery.tools.DiscoverSingleton;
import javax.faces.FacesException;
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java?rev=982743&r1=982742&r2=982743&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java Thu Aug 5 19:32:38 2010
@@ -37,8 +37,8 @@ import javax.servlet.http.HttpSessionBin
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
-import org.apache.commons.discovery.tools.DiscoverSingleton;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
+import org.apache.myfaces.commons.discovery.tools.DiscoverSingleton;
import org.apache.myfaces.shared_impl.util.ClassUtils;
/**