You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by so...@apache.org on 2014/04/16 20:38:28 UTC
svn commit: r1588021 - in /myfaces/trinidad/trunk: ./
trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/
trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/
trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/
Author: sobryan
Date: Wed Apr 16 18:38:28 2014
New Revision: 1588021
URL: http://svn.apache.org/r1588021
Log:
TRINIDAD-2439: Plugable configuration parameter provider
*Thanks for the patch Dave
Added:
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/ConfigPropertyService.java (with props)
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/PropertyValueProvider.java (with props)
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/TestPropertyValueProvider.java (with props)
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigPropertyServiceImpl.java (with props)
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/DefaultValueProvider.java (with props)
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ServletConfigValueProvider.java (with props)
Modified:
myfaces/trinidad/trunk/pom.xml
myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts
myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java
Modified: myfaces/trinidad/trunk/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/pom.xml?rev=1588021&r1=1588020&r2=1588021&view=diff
==============================================================================
--- myfaces/trinidad/trunk/pom.xml (original)
+++ myfaces/trinidad/trunk/pom.xml Wed Apr 16 18:38:28 2014
@@ -409,6 +409,7 @@ Create A Branch (http://maven.apache.org
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
+ <version>2.17</version>
<inherited>true</inherited>
<configuration>
<parallel>true</parallel>
Added: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/ConfigPropertyService.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/ConfigPropertyService.java?rev=1588021&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/ConfigPropertyService.java (added)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/ConfigPropertyService.java Wed Apr 16 18:38:28 2014
@@ -0,0 +1,112 @@
+/*
+ * 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.trinidad.config;
+
+import java.beans.PropertyChangeListener;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
+/**
+ * This class allows access to configuration properties supplied by a plugable
+ * property value provider. Using a plugable property value provider separates
+ * access to property values from where the values are stored, allowing different
+ * property storage and configuration schemes to be used without impacting code
+ * that uses the property values.
+ * <p>
+ * See {@link PropertyValueProvider PropertyValueProvider} for information
+ * on configuring a property value provider.
+ * <p>
+ * Implementation os this class are required to be thread safe allowing multiple
+ * threads to invoke methods on an instance concurrently.
+ */
+public abstract class ConfigPropertyService
+{
+ /**
+ * Obtain a reference to the service.
+ *
+ * @param externalContext container context object.
+ * @return service object for obtaining property values.
+ */
+ public static ConfigPropertyService getInstance(ExternalContext externalContext)
+ {
+ ConfigPropertyService service =
+ (ConfigPropertyService) externalContext.getApplicationMap().get(CONFIG_PROPERTY_SERVICE_KEY);
+ if (service == null)
+ {
+ throw new IllegalStateException(_LOG.getMessage("CONFIG_PROPERTY_SERVICE_NOT_INITIALIZED"));
+ }
+ return service;
+ }
+
+ /**
+ * @param externalContext container context object.
+ * @param name name of the requested property.
+ * @return the value of the property or <code>null</code> if the property was not found.
+ * @throws NullPointerException is the specified name is null.
+ */
+ public abstract String getProperty(ExternalContext externalContext, String name);
+
+ /**
+ * Register a listener to be informed if/when a property value is changed.
+ * <p>
+ * The {@link ConfigPropertyService ConfigPropertyService} will be specified as the
+ * 'source' attribute of any change events the listener receives.
+ *
+ * @param listener the listener to be notified of property value changes.
+ */
+ public abstract void addPropertyChangeListener(PropertyChangeListener listener);
+
+ /**
+ * Unregister a property change listener.
+ * @param listener the listener to unregister.
+ */
+ public abstract void removePropertyChangeListener(PropertyChangeListener listener);
+
+ /**
+ * Get the test value provider. If one is not currently in the collection of value providers a
+ * new instance will be created and added to the collection. An implementation of this class
+ * should not allow more than one instance of {@ TestPropertyValueProvider TestPropertyValueProvider}
+ * in its collection of value providers.
+ *
+ * @return a test value provider.
+ */
+ protected abstract TestPropertyValueProvider getTestProvider();
+
+ /**
+ * Notify value change listeners of a config property value change.
+ * @param name the name of the property who's value changed.
+ * @param oldValue the previous value of the property.
+ * @param newValue the new value of the property.
+ */
+ //
+ // Note: this method is not public because it's expected to only be invoked by
+ // PropertyValueProvider which is in the same package.
+ //
+ protected abstract void notifyValueChange(ExternalContext externalContext, String name, String oldValue);
+
+ /**
+ * Key used to store the application's ConfigPropertyService instance in the applicationScope map.
+ */
+ protected static final String CONFIG_PROPERTY_SERVICE_KEY =
+ "org.apache.myfaces.trinidad.config.CONFIG_PROPERTY_SERVICE_INSTANCE";
+
+ static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(ConfigPropertyService.class);
+}
Propchange: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/ConfigPropertyService.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/ConfigPropertyService.java
------------------------------------------------------------------------------
svn:executable = *
Added: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/PropertyValueProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/PropertyValueProvider.java?rev=1588021&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/PropertyValueProvider.java (added)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/PropertyValueProvider.java Wed Apr 16 18:38:28 2014
@@ -0,0 +1,76 @@
+/*
+ * 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.trinidad.config;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
+/**
+ * Abstract base class for configurable property value providers.
+ * <p>
+ * A PropertyValueProvider can be registered by placing
+ * <code>/META-INF/services/org.apache.myfaces.trinidad.config.PropertyValueProvider</code>
+ * on the classpath containing the fully qualified name of the implementation class.
+ * <p>
+ * Note: at this time the framework only supports one PropertyValueProvider being registered
+ * to avoid provider ordering issues.
+ * <p>
+ * Implementation os this class are required to be thread safe allowing multiple
+ * threads to invoke methods on an instance concurrently.
+ */
+public abstract class PropertyValueProvider
+{
+ /**
+ * Constructor.
+ */
+ protected PropertyValueProvider()
+ {
+ }
+
+ /**
+ * Fetch a property value. There is no concurrency control provided by the property service so
+ * all implementations of this method are required to be thread safe or to perform their own
+ * concurrency control.
+ * @param externalContext container context object.
+ * @param name name of the requested property.
+ * @return the value of the property or <code>null</code> if the property was not found.
+ * @throws NullPointerException if the supplied property name is null.
+ */
+ public abstract String getValue(ExternalContext externalContext, String name);
+
+ /**
+ * Implementations of this class are required to call this method when a property value is changed.
+ * @param externalContext container context object.
+ * @param name the name of the property who's value changed.
+ * @param oldValue the previous value of the property.
+ * @param newValue the new value of the property.
+ */
+ protected final void notifyValueChanged(ExternalContext externalContext, String name, String oldValue)
+ {
+ ConfigPropertyService service = ConfigPropertyService.getInstance(externalContext);
+ if (service == null)
+ {
+ throw new IllegalStateException(_LOG.getMessage("CONFIG_PROPERTY_SERVICE_NOT_INITIALIZED"));
+ }
+ service.notifyValueChange(externalContext, name, oldValue);
+ }
+
+ static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(PropertyValueProvider.class);
+}
Propchange: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/PropertyValueProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/PropertyValueProvider.java
------------------------------------------------------------------------------
svn:executable = *
Added: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/TestPropertyValueProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/TestPropertyValueProvider.java?rev=1588021&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/TestPropertyValueProvider.java (added)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/TestPropertyValueProvider.java Wed Apr 16 18:38:28 2014
@@ -0,0 +1,142 @@
+/*
+ * 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.trinidad.config;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
+/**
+ * A {@link PropertyValueProvider PropertyValueProvider} that allows runtime modification
+ * of property values to support unit testing code. By using this class a unit test can
+ * exercise a piece of code with a number of different property values without needing to
+ * change property values in their underlaying source.
+ * <p>
+ * This class maintains an in-memory collection of property values supplied by calling the
+ * {@link TestPropertyValueProvider#setProperty setProperty} method. When a value is requested
+ * by the {@link ConfigPropertyService ConfigPropertyService} the in-memory collection of
+ * values are consulted first. If a value has been supplied that will be returned, otherwise
+ * the property value will be fetched from the configured property value provider.
+ * <p>
+ * When this class is used it will coordinate with the {@link ConfigPropertyService ConfigPropertyService}
+ * to ensure values are obained from this class.
+ */
+public final class TestPropertyValueProvider
+ extends PropertyValueProvider
+{
+ public TestPropertyValueProvider()
+ {
+ }
+
+ /**
+ * Obtain a reference to the test value provider. Calling this method will also result
+ * in the test property value provider being installed with the
+ * {@link ConfigPropertyService ConfigPropertyService}.
+ *
+ * @return a test value provider.
+ */
+ public static TestPropertyValueProvider getInstance(ExternalContext externalContext)
+ {
+ ConfigPropertyService service = ConfigPropertyService.getInstance(externalContext);
+ if (service == null)
+ {
+ throw new IllegalStateException(_LOG.getMessage("CONFIG_PROPERTY_SERVICE_NOT_INITIALIZED"));
+ }
+ return service.getTestProvider();
+ }
+
+ /**
+ * Used by the {@link ConfigPropertyService ConfigPropertyService} to obtain a property value.
+ * If a value has been specified by calling the {@link TestPropertyValueProvider#setProperty setProperty}
+ * method that value will be returned, otherwise the request will be delegated to the configured
+ * property value provider.
+ *
+ * @param extCtx {@inheritDoc}
+ * @param name {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String getValue(ExternalContext extCtx, String name)
+ {
+ String value;
+ if (name != null)
+ {
+ value = _testValues.get(name);
+ }
+ else
+ {
+ throw new NullPointerException(_LOG.getMessage("NULL_CONFIG_PROPERTY_NAME"));
+ }
+ return value;
+ }
+
+ /**
+ * Set the value of a property. Calling this method only updates the in-memory value used for
+ * test purposes. The value is not propagated to any underlying storage.
+ * <p>
+ * Any PropertyChangeListener reqiested with the {@link ConfigPropertyService ConfigPropertyService}
+ * will be notified of the value change when this method is called.
+ *
+ * @param externalContext container context object.
+ * @param name name of the property.
+ * @param value value of the property.
+ * @throws NullPointerException if the property name is null.
+ */
+ public void setProperty(ExternalContext externalContext, String name, String value)
+ {
+ if (name == null)
+ {
+ throw new NullPointerException(_LOG.getMessage("NULL_CONFIG_PROPERTY_NAME"));
+ }
+ String oldValue = ConfigPropertyService.getInstance(externalContext).getProperty(externalContext, name);
+ _testValues.put(name, value);
+ notifyValueChanged(externalContext, name, oldValue);
+ }
+
+ /**
+ * Remove a property value from the test value provider.
+ * @param name name of the property.
+ * @throws NullPointerException if the property name is null.
+ */
+ public void removeProperty(ExternalContext externalContext, String name)
+ {
+ if (name == null)
+ {
+ throw new NullPointerException(_LOG.getMessage("NULL_CONFIG_PROPERTY_NAME"));
+ }
+ String oldValue = ConfigPropertyService.getInstance(externalContext).getProperty(externalContext, name);
+ _testValues.remove(name);
+ notifyValueChanged(externalContext, name, oldValue);
+ }
+
+ /**
+ * Removes all in-memory property values specified by calling
+ * {@link TestPropertyValueProvider#setProperty setProperty}, returning them to their original values.
+ */
+ public void resetValues()
+ {
+ _testValues.clear();
+ }
+
+ private final ConcurrentHashMap<String, String> _testValues = new ConcurrentHashMap<String, String>();
+
+ static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(TestPropertyValueProvider.class);
+}
Propchange: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/TestPropertyValueProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/TestPropertyValueProvider.java
------------------------------------------------------------------------------
svn:executable = *
Modified: myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts?rev=1588021&r1=1588020&r2=1588021&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts Wed Apr 16 18:38:28 2014
@@ -566,5 +566,8 @@
<resource key="INVALID_RESOURCE_SIZE">Invalid resource size detected. The resource at '{0}' appears to be {1} bytes, but URLConnection.getContentLength() for this resource reports {2}.</resource>
<resource key="RESOURCE_SIZE_CHANGED">Resource size changed. A new content length of {0} bytes has been detected for the resource {1}. Removing resource from cache.</resource>
+<resource key="MULTIPLE_CONFIG_PROPERTY_PROVIDERS_FOUND">Multiple PropertyValueProviders configured on the classpath, only one is allowed.</resource>
+<resource key="NULL_CONFIG_PROPERTY_NAME">Config property name can not be null.</resource>
+<resource key="CONFIG_PROPERTY_SERVICE_NOT_INITIALIZED">The config property service has not been initialized.</resource>
</resources>
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigPropertyServiceImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigPropertyServiceImpl.java?rev=1588021&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigPropertyServiceImpl.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigPropertyServiceImpl.java Wed Apr 16 18:38:28 2014
@@ -0,0 +1,170 @@
+/*
+ * 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.trinidadinternal.config;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.trinidad.config.ConfigPropertyService;
+import org.apache.myfaces.trinidad.config.PropertyValueProvider;
+import org.apache.myfaces.trinidad.config.TestPropertyValueProvider;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
+
+/**
+ * This class allows access to configuration properties supplied by a plugable
+ * property value provider. Using a plugable property value provider separates
+ * access to property values from where the values are stored, allowing different
+ * property storage and configuration schemes to be used without impacting code
+ * that uses the property values.
+ * <p>
+ * See {@link PropertyValueProvider PropertyValueProvider} for information
+ * on configuring a property value provider.
+ */
+public final class ConfigPropertyServiceImpl
+ extends ConfigPropertyService
+{
+ /**
+ * Constructor.
+ */
+ private ConfigPropertyServiceImpl(List<PropertyValueProvider> valueProviders)
+ {
+ _valueProviders = new CopyOnWriteArrayList<PropertyValueProvider>(valueProviders);
+ }
+
+ @Override
+ public String getProperty(ExternalContext externalContext, String name)
+ {
+ if (name == null)
+ {
+ throw new NullPointerException(_LOG.getMessage("NULL_CONFIG_PROPERTY_NAME"));
+ }
+
+ //
+ // Iterate through the list of value providers and return the first non-null value
+ // returned.
+ //
+ String result = null;
+ for (PropertyValueProvider provider: _valueProviders)
+ {
+ result = provider.getValue(externalContext, name);
+ if (result != null)
+ {
+ break;
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void addPropertyChangeListener(PropertyChangeListener listener)
+ {
+ _changeListeners.add(listener);
+ }
+
+ @Override
+ public void removePropertyChangeListener(PropertyChangeListener listener)
+ {
+ _changeListeners.remove(listener);
+ }
+
+ @Override
+ protected synchronized TestPropertyValueProvider getTestProvider()
+ {
+ if (_testProvider == null)
+ {
+ _testProvider = new TestPropertyValueProvider();
+
+ //
+ // Add the test provider to the front of the providers list so it's
+ // checked first.
+ //
+ _valueProviders.add(0, _testProvider);
+ }
+ return _testProvider;
+ }
+
+ @Override
+ protected void notifyValueChange(ExternalContext externalContext, String name, String oldValue)
+ {
+ String newValue = getProperty(externalContext, name);
+ PropertyChangeEvent event = new PropertyChangeEvent(this, name, oldValue, newValue);
+ for (PropertyChangeListener listener: _changeListeners)
+ {
+ listener.propertyChange(event);
+ }
+ }
+
+ /**
+ * This method initializes the collection of value providers. The caller must ensure
+ * this method is called only once during the application's lifecycle to initialize the
+ * application's instance.
+ */
+ static void initialize(ExternalContext externalContext)
+ {
+ ArrayList<PropertyValueProvider> valueProviders = new ArrayList<PropertyValueProvider>(5);
+
+ //
+ // The first value provider is always the servlet config value provider.
+ //
+ valueProviders.add(new ServletConfigValueProvider());
+
+ //
+ // Next see if there is a value provider SPI registered on the classpath.
+ //
+ List<PropertyValueProvider> list = ClassLoaderUtils.getServices(_PROPERTY_PROVIDER_URL);
+ if (list.size() > 1)
+ {
+ throw new RuntimeException(_LOG.getMessage("MULTIPLE_CONFIG_PROPERTY_PROVIDERS_FOUND"));
+ }
+ else if (list.size() == 1)
+ {
+ valueProviders.add(list.get(0));
+ }
+
+ //
+ // The last value provider is always the default value provider.
+ //
+ valueProviders.add(new DefaultValueProvider());
+
+ //
+ // Create the instance and place it in the applicationScope map.
+ //
+ ConfigPropertyServiceImpl instance = new ConfigPropertyServiceImpl(valueProviders);
+ externalContext.getApplicationMap().put(ConfigPropertyService.CONFIG_PROPERTY_SERVICE_KEY, instance);
+ }
+
+ private TestPropertyValueProvider _testProvider = null;
+
+ private final List<PropertyValueProvider> _valueProviders;
+
+ private final Set<PropertyChangeListener> _changeListeners = new CopyOnWriteArraySet<PropertyChangeListener>();
+
+ static private final String _PROPERTY_PROVIDER_URL = "org.apache.myfaces.trinidad.config.PropertyValueProvider";
+
+ static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(ConfigPropertyServiceImpl.class);
+}
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigPropertyServiceImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigPropertyServiceImpl.java
------------------------------------------------------------------------------
svn:executable = *
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/DefaultValueProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/DefaultValueProvider.java?rev=1588021&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/DefaultValueProvider.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/DefaultValueProvider.java Wed Apr 16 18:38:28 2014
@@ -0,0 +1,58 @@
+/*
+ * 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.trinidadinternal.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.trinidad.config.PropertyValueProvider;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
+/**
+ * Provider of default configuration property values. These values are what are returned
+ * when a value has not been specified by any other value provider.
+ */
+final class DefaultValueProvider
+ extends PropertyValueProvider
+{
+ public DefaultValueProvider()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getValue(ExternalContext extCtx, String name)
+ {
+ if (name == null)
+ {
+ throw new NullPointerException(_LOG.getMessage("NULL_CONFIG_PROPERTY_NAME"));
+ }
+ String result = DEFAULT_VALUES.get(name);
+ return result;
+ }
+
+ // Map of default config property name/value pairs.
+ private static final Map<String, String> DEFAULT_VALUES = new HashMap<String, String>();
+
+ static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(DefaultValueProvider.class);
+}
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/DefaultValueProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/DefaultValueProvider.java
------------------------------------------------------------------------------
svn:executable = *
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java?rev=1588021&r1=1588020&r2=1588021&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java Wed Apr 16 18:38:28 2014
@@ -71,7 +71,7 @@ import org.apache.myfaces.trinidadintern
* the Trindad developer.
*
* @see org.apache.myfaces.trinidad.config.Configurator
- * @version $Revision$ $Date$
+ * @version $Revision: daschnei_20131204_er17813713/3 $ $Date: 2014/01/21 13:53:38 $
*/
public final class GlobalConfiguratorImpl
extends Configurator
@@ -265,16 +265,16 @@ public final class GlobalConfiguratorImp
@Override
public void destroy()
{
-
+
if (_initialized.get())
- {
+ {
try
{
//Forces atomic operations with init. If we are in the middle of an init or another destroy, we'll
//wait on this lock until our operations are complete. We then have to recheck our initialized state.
-
+
_initLock.lock();
- if(_initialized.get())
+ if (_initialized.get())
{
for (final Configurator config: _services)
{
@@ -317,7 +317,7 @@ public final class GlobalConfiguratorImp
{
try
{
- _endRequest(ec, state);
+ _endRequest(ec, state);
}
finally
{
@@ -343,7 +343,7 @@ public final class GlobalConfiguratorImp
{
RequestStateMap state = RequestStateMap.getInstance(ec);
RequestType type = (RequestType) state.get(_REQUEST_TYPE);
-
+
//Install the URLEncoder plugin system
ec = new URLEncoderExternalContext(ec);
@@ -376,7 +376,7 @@ public final class GlobalConfiguratorImp
ec = config.getExternalContext(ec);
}
}
-
+
//After all this request wrapping there is just one more thing we want to handle. IF we are not in a PPR
//request AND we are in a processAction, we need to be able to track when a redirect is performed. The
//reason for this is that if a redirect is performed during the processAction then we need to remember this
@@ -384,7 +384,7 @@ public final class GlobalConfiguratorImp
//at the end of ProcessAction so the subsequent render will start fresh. In the PPR case, and the case where
//we do not have a performAction, we can skip this wrapper. This information will be saved and removed from
//the request.
- if(RequestType.ACTION.equals(type))
+ if (RequestType.ACTION.equals(type))
{
//We have an action, add the wrapper.
ec = new RecordRedirectExternalContext(ec);
@@ -409,7 +409,7 @@ public final class GlobalConfiguratorImp
public void init(ExternalContext ec)
{
assert ec != null;
-
+
if (!_initialized.get())
{
try
@@ -419,43 +419,46 @@ public final class GlobalConfiguratorImp
//is checked again for validity.
_initLock.lock();
//Check the AtomicBoolean for a change
- if(!_initialized.get())
- {
- _services = ClassLoaderUtils.getServices(Configurator.class.getName());
+ if (!_initialized.get())
+ {
+ _services = ClassLoaderUtils.getServices(Configurator.class.getName());
- // set up the RequestContext Factory as needed.
- _setupRequestContextFactory();
+ // set up the RequestContext Factory as needed.
+ _setupRequestContextFactory();
- // Create a new SkinFactory if needed.
- if (SkinFactory.getFactory() == null)
- {
- SkinFactory.setFactory(new SkinFactoryImpl());
- }
+ // Create a new SkinFactory if needed.
+ if (SkinFactory.getFactory() == null)
+ {
+ SkinFactory.setFactory(new SkinFactoryImpl());
+ }
- // init external skin provider
- // this has to be done before SkinProviderRegistry, because SkinProviderRegistry uses this
- Object externalSkinProvider = ec.getApplicationMap().get(ExternalSkinProvider.EXTERNAL_SKIN_PROVIDER_KEY);
+ // init external skin provider
+ // this has to be done before SkinProviderRegistry, because SkinProviderRegistry uses this
+ Object externalSkinProvider = ec.getApplicationMap().get(ExternalSkinProvider.EXTERNAL_SKIN_PROVIDER_KEY);
- if (externalSkinProvider == null)
- ec.getApplicationMap().put(ExternalSkinProvider.EXTERNAL_SKIN_PROVIDER_KEY, new ExternalSkinProvider());
+ if (externalSkinProvider == null)
+ ec.getApplicationMap().put(ExternalSkinProvider.EXTERNAL_SKIN_PROVIDER_KEY, new ExternalSkinProvider());
- // init trinidad skin provider
- // this has to be done before SkinProviderRegistry, because SkinProviderRegistry uses this
- Object trinidadSkinProvider = ec.getApplicationMap().get(TrinidadSkinProvider.TRINDIAD_SKIN_PROVIDER_KEY);
+ // init trinidad skin provider
+ // this has to be done before SkinProviderRegistry, because SkinProviderRegistry uses this
+ Object trinidadSkinProvider = ec.getApplicationMap().get(TrinidadSkinProvider.TRINDIAD_SKIN_PROVIDER_KEY);
- if (trinidadSkinProvider == null)
- ec.getApplicationMap().put(TrinidadSkinProvider.TRINDIAD_SKIN_PROVIDER_KEY, new TrinidadSkinProvider());
+ if (trinidadSkinProvider == null)
+ ec.getApplicationMap().put(TrinidadSkinProvider.TRINDIAD_SKIN_PROVIDER_KEY, new TrinidadSkinProvider());
- // init skin provider
- Object provider = ec.getApplicationMap().get(SkinProvider.SKIN_PROVIDER_INSTANCE_KEY);
+ // init skin provider
+ Object provider = ec.getApplicationMap().get(SkinProvider.SKIN_PROVIDER_INSTANCE_KEY);
- if (provider == null)
- ec.getApplicationMap().put(SkinProvider.SKIN_PROVIDER_INSTANCE_KEY, new SkinProviderRegistry());
+ if (provider == null)
+ ec.getApplicationMap().put(SkinProvider.SKIN_PROVIDER_INSTANCE_KEY, new SkinProviderRegistry());
- for (final Configurator config: _services)
- {
- config.init(ec);
- }
+ // init the config property service
+ ConfigPropertyServiceImpl.initialize(ec);
+
+ for (final Configurator config: _services)
+ {
+ config.init(ec);
+ }
// we do not register the skin extensions found in trinidad-skins.xml eagerly.
// with SkinProvider SPI we are lazy loading skins as and when required
@@ -509,7 +512,7 @@ public final class GlobalConfiguratorImp
}
/**
- * Setup request context factory as needed.
+ * Setup request context factory as needed.
*/
private void _setupRequestContextFactory()
{
@@ -517,7 +520,8 @@ public final class GlobalConfiguratorImp
return;
RequestContextFactory requestContextFactory = null;
- List<RequestContextFactory> factories = ClassLoaderUtils.getServices(RequestContextFactory.class.getName());;
+ List<RequestContextFactory> factories = ClassLoaderUtils.getServices(RequestContextFactory.class.getName());
+ ;
if (factories.isEmpty())
requestContextFactory = new RequestContextFactoryImpl();
else
@@ -585,15 +589,16 @@ public final class GlobalConfiguratorImp
private void _endConfiguratorServiceRequest(ExternalContext ec, RequestStateMap state)
{
boolean isRedirected = (null != ec.getRequestMap().remove(_REDIRECT_ISSUED));
-
+
try
{
//Only end services at the end of a writable response. This will
//generally be RENDER, RESOURCE, and SERVLET.
-
+
//WE had to add a check to see if a redirect was issued in order to handle a bug where endRequest was not
//executed on a redirect.
- if ((ExternalContextUtils.isResponseWritable(ec) || isRedirected) && !Boolean.TRUE.equals(state.get(_CONFIGURATORS_ABORTED)))
+ if ((ExternalContextUtils.isResponseWritable(ec) || isRedirected) &&
+ !Boolean.TRUE.equals(state.get(_CONFIGURATORS_ABORTED)))
{
_endConfiguratorServices(ec);
}
@@ -601,7 +606,7 @@ public final class GlobalConfiguratorImp
finally
{
//If redirect was issued, we do not want to save the state. Let it burn.. :D
- if(!isRedirected)
+ if (!isRedirected)
{
state.saveState(ec);
}
@@ -620,7 +625,7 @@ public final class GlobalConfiguratorImp
_finishComponentReferenceInitialization(ec);
}
}
-
+
private void _releaseThreadLocals(ExternalContext ec)
{
try
@@ -663,26 +668,26 @@ public final class GlobalConfiguratorImp
private void _finishComponentReferenceInitialization(ExternalContext ec)
{
Map<String, Object> requestMap = ec.getRequestMap();
-
- Collection<ComponentReference<?>> initializeList = (Collection<ComponentReference<?>>)
- requestMap.get(_FINISH_INITIALIZATION_LIST_KEY);
-
+
+ Collection<ComponentReference<?>> initializeList =
+ (Collection<ComponentReference<?>>) requestMap.get(_FINISH_INITIALIZATION_LIST_KEY);
+
if ((initializeList != null) && !initializeList.isEmpty())
{
RuntimeException initializationException = null;
- for (ComponentReference<?> reference : initializeList)
+ for (ComponentReference<?> reference: initializeList)
{
try
{
- reference.ensureInitialization();
- }
+ reference.ensureInitialization();
+ }
catch (RuntimeException rte)
{
initializationException = rte;
}
}
-
+
// we've initialized everything, so we're done
initializeList.clear();
@@ -737,22 +742,22 @@ public final class GlobalConfiguratorImp
}
}
}
-
+
private boolean _beginWindowManagerRequest(ExternalContext ec)
{
WindowManager wm = RequestContext.getCurrentInstance().getWindowManager();
- boolean cont = true;
-
+ boolean cont = true;
+
try
{
cont = wm.beginRequest(ec);
}
- catch(IOException e)
+ catch (IOException e)
{
_LOG.severe(e);
}
-
- return cont;
+
+ return cont;
}
static private boolean _isSetRequestBugPresent(ExternalContext ec)
@@ -788,7 +793,8 @@ public final class GlobalConfiguratorImp
// This handles an issue with the ExternalContext object prior to
// JSF1.2_04.
- static private class ClearRequestExternalContext extends ExternalContextDecorator
+ static private class ClearRequestExternalContext
+ extends ExternalContextDecorator
{
private ExternalContext _ec;
private Map<String, Object> _requestCookieMap;
@@ -884,8 +890,7 @@ public final class GlobalConfiguratorImp
_checkRequest();
if (_requestParameterValuesMap == null)
{
- _requestParameterValuesMap =
- new ServletRequestParameterValuesMap((ServletRequest) getRequest());
+ _requestParameterValuesMap = new ServletRequestParameterValuesMap((ServletRequest) getRequest());
}
return _requestParameterValuesMap;
}
@@ -910,66 +915,64 @@ public final class GlobalConfiguratorImp
}
}
- static private class RecordRedirectExternalContext extends ExternalContextDecorator
+ static private class RecordRedirectExternalContext
+ extends ExternalContextDecorator
{
public RecordRedirectExternalContext(ExternalContext ec)
{
- assert(ec != null);
+ assert (ec != null);
_ec = ec;
}
-
+
@Override
public void redirect(String url)
throws IOException
{
super.redirect(url);
-
+
//We set a parameter on the request saying that we indeed have a redirect.
_ec.getRequestMap().put(_REDIRECT_ISSUED, AppliedClass.APPLIED);
}
-
+
@Override
protected ExternalContext getExternalContext()
{
return _ec;
}
-
+
private ExternalContext _ec;
}
private static volatile boolean _sSetRequestBugTested = false;
private static boolean _sHasSetRequestBug = false;
-
+
private final ReentrantLock _initLock = new ReentrantLock();
private AtomicBoolean _initialized = new AtomicBoolean(false);
private List<Configurator> _services;
static private final Map<ClassLoader, GlobalConfiguratorImpl> _CONFIGURATORS =
new HashMap<ClassLoader, GlobalConfiguratorImpl>();
- static private final String _IN_REQUEST =
- GlobalConfiguratorImpl.class.getName() + ".IN_REQUEST";
- static private final String _REQUEST_CONTEXT =
- GlobalConfiguratorImpl.class.getName() + ".REQUEST_CONTEXT";
- static private final String _REQUEST_TYPE =
- GlobalConfiguratorImpl.class.getName() + ".REQUEST_TYPE";
-
+ static private final String _IN_REQUEST = GlobalConfiguratorImpl.class.getName() + ".IN_REQUEST";
+ static private final String _REQUEST_CONTEXT = GlobalConfiguratorImpl.class.getName() + ".REQUEST_CONTEXT";
+ static private final String _REQUEST_TYPE = GlobalConfiguratorImpl.class.getName() + ".REQUEST_TYPE";
+
static private final String _CONFIGURATORS_ABORTED =
GlobalConfiguratorImpl.class.getName() + ".CONFIGURATORS_ABORTED";
//This should be saved on the ManagedRequestScope and needs to implement
//@ExcludeFromManagedRequestScope to be totally safe
- static private final String _REDIRECT_ISSUED =
- GlobalConfiguratorImpl.class.getName() + ".REDIRECT_ISSUED";
-
+ static private final String _REDIRECT_ISSUED = GlobalConfiguratorImpl.class.getName() + ".REDIRECT_ISSUED";
+
//This will ensure the property is removed on the next request. It should be used
//as the value for _REDIRECT_ISSUED.
+
@ExcludeFromManagedRequestScope
static private class AppliedClass
{
static public final AppliedClass APPLIED = new AppliedClass();
}
-
+
static private class TestRequest
extends ServletRequestWrapper
{
@@ -998,14 +1001,12 @@ public final class GlobalConfiguratorImp
}
// skanky duplication of key from ComponentReference Class
- private static final String _FINISH_INITIALIZATION_LIST_KEY = ComponentReference.class.getName() +
- "#FINISH_INITIALIZATION";
+ private static final String _FINISH_INITIALIZATION_LIST_KEY =
+ ComponentReference.class.getName() + "#FINISH_INITIALIZATION";
// hacky reference to the ThreadLocalResetter used to clean up request-scoped
// ThreadLocals
- private AtomicReference<ThreadLocalResetter> _threadResetter =
- new AtomicReference<ThreadLocalResetter>();
+ private AtomicReference<ThreadLocalResetter> _threadResetter = new AtomicReference<ThreadLocalResetter>();
- static private final TrinidadLogger _LOG =
- TrinidadLogger.createTrinidadLogger(GlobalConfiguratorImpl.class);
+ static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(GlobalConfiguratorImpl.class);
}
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ServletConfigValueProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ServletConfigValueProvider.java?rev=1588021&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ServletConfigValueProvider.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ServletConfigValueProvider.java Wed Apr 16 18:38:28 2014
@@ -0,0 +1,52 @@
+/*
+ * 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.trinidadinternal.config;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.trinidad.config.PropertyValueProvider;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
+/**
+ * A {@link PropertyValueProvider PropertyValueProvider} that returns ServletContext
+ * initialization parameter values.
+ */
+final class ServletConfigValueProvider
+ extends PropertyValueProvider
+{
+ ServletConfigValueProvider()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getValue(ExternalContext extCtx, String name)
+ {
+ if (name == null)
+ {
+ throw new NullPointerException(_LOG.getMessage("NULL_CONFIG_PROPERTY_NAME"));
+ }
+ String result = extCtx.getInitParameter(name);
+ return result;
+ }
+
+ static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(ServletConfigValueProvider.class);
+}
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ServletConfigValueProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ServletConfigValueProvider.java
------------------------------------------------------------------------------
svn:executable = *