You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by st...@apache.org on 2013/11/19 20:02:39 UTC
git commit: DELTASPIKE-442 improve PersistenceConfigurationProvider
Updated Branches:
refs/heads/master db666c570 -> 4c410f32f
DELTASPIKE-442 improve PersistenceConfigurationProvider
also implement PropertyLoader (taken from Apache OpenWebBeans)
and tweak it to take ProjectStage into account.
Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/4c410f32
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/4c410f32
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/4c410f32
Branch: refs/heads/master
Commit: 4c410f32f951085a0f03d256649c833cd00996a6
Parents: db666c5
Author: Mark Struberg <st...@apache.org>
Authored: Tue Nov 19 19:59:14 2013 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 19 19:59:14 2013 +0100
----------------------------------------------------------------------
.../core/api/config/PropertyLoader.java | 264 +++++++++++++++++++
.../test/api/config/PropertyLoaderTest.java | 79 ++++++
.../core/api/src/test/resources/test.properties | 21 ++
.../test/resources/test2-UnitTest.properties | 22 ++
.../api/src/test/resources/test2.properties | 21 ++
.../PersistenceConfigurationProviderImpl.java | 11 +-
6 files changed, 415 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4c410f32/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyLoader.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyLoader.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyLoader.java
new file mode 100644
index 0000000..32590e9
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyLoader.java
@@ -0,0 +1,264 @@
+/*
+ * 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.deltaspike.core.api.config;
+
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+import org.apache.deltaspike.core.util.ClassUtils;
+import org.apache.deltaspike.core.util.ProjectStageProducer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * <p>Utility class to load configuration properties via a list of
+ * artibrary property files by a well defined order.</p>
+ *
+ * <p>This will also pick up property files which are post-fixed with
+ * a -$projectStage.properties </p>
+ * <p>User configurations should start with 'configuration.ordinal'
+ * greater than 100.</p>
+ *
+ */
+public class PropertyLoader
+{
+ public static final int CONFIGURATION_ORDINAL_DEFAULT_VALUE = 100;
+
+
+ private static final String FILE_EXTENSION = ".properties";
+
+
+ private static final Logger LOG = Logger.getLogger(PropertyLoader.class.getName());
+
+
+ private PropertyLoader()
+ {
+ // utility class doesn't have a public ct
+ }
+
+ /**
+ * <p>Look for all property files with the given name (e.g. 'myconfig.properties') in
+ * the classpath. Then load all properties files and sort them by their ascending
+ * configuration order and apply them in this order.</p>
+ *
+ * <p>The idea is to be able to 'override' properties by just providing
+ * a new properties file with the same name but a higher 'deltaspike_ordinal'
+ * than the old one.</p>
+ *
+ * <p>If a property file defines no 'configuration.ordinal' property than a default
+ * value of {@link #CONFIGURATION_ORDINAL_DEFAULT_VALUE} is assumed. Any sensitive
+ * default which is provided by the system parsing for the configuration should
+ * have a 'configuration.ordinal' value lower than 10. In most cases a value of 1</p>
+ *
+ * <p>If 2 property files have the same ordinal 'configuraiton.order' the outcome
+ * is not really defined. The Properties file which got found first will be
+ * processed first and thus get overwritten by the one found later.</p>
+ *
+ * @param propertyFileName the name of the properties file, without the extension '.properties'
+ * @return the final property values
+ */
+ public static synchronized Properties getProperties(String propertyFileName)
+ {
+ if (propertyFileName == null)
+ {
+ throw new IllegalArgumentException("propertyFileName must not be null!");
+ }
+
+ try
+ {
+ if (propertyFileName.endsWith(FILE_EXTENSION))
+ {
+ // if the given propertyFileName already contains the extension, then remove it.
+ propertyFileName = propertyFileName.substring(0, propertyFileName.length() - FILE_EXTENSION.length());
+ }
+
+ List<Properties> allProperties = loadAllProperties(propertyFileName);
+ if (allProperties == null)
+ {
+ return null;
+ }
+
+ List<Properties> sortedProperties = sortProperties(allProperties);
+ Properties properties = mergeProperties(sortedProperties);
+ return properties;
+ }
+ catch (IOException e)
+ {
+ LOG.log(Level.SEVERE, "Error while loading the propertyFile " + propertyFileName, e);
+ return null;
+ }
+ }
+
+ private static List<Properties> loadAllProperties(String propertyFileName)
+ throws IOException
+ {
+ ClassLoader cl = ClassUtils.getClassLoader(null);
+
+ List<Properties> properties = new ArrayList<Properties>();
+
+ // read the normal property file names
+ Enumeration<URL> propertyUrls = cl.getResources(propertyFileName + FILE_EXTENSION);
+ while (propertyUrls != null && propertyUrls.hasMoreElements())
+ {
+ URL propertyUrl = propertyUrls.nextElement();
+ fillProperties(properties, propertyUrl);
+ }
+
+ // and also read the ones post-fixed with the projectStage
+ ProjectStage ps = ProjectStageProducer.getInstance().getProjectStage();
+
+ propertyUrls = cl.getResources(propertyFileName + "-" + ps + FILE_EXTENSION);
+ while (propertyUrls != null && propertyUrls.hasMoreElements())
+ {
+ URL propertyUrl = propertyUrls.nextElement();
+ fillProperties(properties, propertyUrl);
+ }
+
+ if (properties.isEmpty())
+ {
+ if (LOG.isLoggable(Level.INFO))
+ {
+ LOG.info("could not find any property files with name " + propertyFileName);
+ }
+
+ return null;
+ }
+
+ return properties;
+ }
+
+ private static void fillProperties(List<Properties> properties, URL propertyUrl) throws IOException
+ {
+ InputStream is = null;
+ try
+ {
+ is = propertyUrl.openStream();
+ Properties prop = new Properties();
+ prop.load(is);
+ properties.add(prop);
+
+ // a bit debugging output
+ int ordinal = getConfigurationOrdinal(prop);
+ if (LOG.isLoggable(Level.FINE))
+ {
+ LOG.fine("loading properties with ordinal " + ordinal + " from file " + propertyUrl.getFile());
+ }
+ }
+ finally
+ {
+ if (is != null)
+ {
+ is.close();
+ }
+ }
+ }
+
+ /**
+ * Implement a quick and dirty sorting mechanism for the given Properties.
+ * @param allProperties
+ * @return the Properties list sorted by it's 'configuration.ordinal' in ascending order.
+ */
+ private static List<Properties> sortProperties(List<Properties> allProperties)
+ {
+ List<Properties> sortedProperties = new ArrayList<Properties>();
+ for (Properties p : allProperties)
+ {
+ int configOrder = getConfigurationOrdinal(p);
+
+ int i;
+ for (i = 0; i < sortedProperties.size(); i++)
+ {
+ int listConfigOrder = getConfigurationOrdinal(sortedProperties.get(i));
+ if (listConfigOrder > configOrder)
+ {
+ // only go as far as we found a higher priority Properties file
+ break;
+ }
+ }
+ sortedProperties.add(i, p);
+ }
+ return sortedProperties;
+ }
+
+ /**
+ * Determine the 'configuration.ordinal' of the given properties.
+ * {@link #CONFIGURATION_ORDINAL_DEFAULT_VALUE} if
+ * {@link ConfigSource#DELTASPIKE_ORDINAL} is not set in the
+ * Properties file.
+ *
+ * @param p the Properties from the file.
+ * @return the ordinal number of the given Properties file.
+ */
+ private static int getConfigurationOrdinal(Properties p)
+ {
+ int configOrder = CONFIGURATION_ORDINAL_DEFAULT_VALUE;
+
+ String configOrderString = p.getProperty(ConfigSource.DELTASPIKE_ORDINAL);
+ if (configOrderString != null && configOrderString.length() > 0)
+ {
+ try
+ {
+ configOrder = Integer.parseInt(configOrderString);
+ }
+ catch (NumberFormatException nfe)
+ {
+ LOG.severe(ConfigSource.DELTASPIKE_ORDINAL + " must be an integer value!");
+ throw nfe;
+ }
+ }
+
+ return configOrder;
+ }
+
+ /**
+ * Merge the given Properties in order of appearance.
+ * @param sortedProperties
+ * @return the merged Properties
+ */
+ private static Properties mergeProperties(List<Properties> sortedProperties)
+ {
+ Properties mergedProperties = new Properties();
+ for (Properties p : sortedProperties)
+ {
+ for (Map.Entry<?,?> entry : p.entrySet())
+ {
+ String key = (String) entry.getKey();
+ String value = (String) entry.getValue();
+
+ if (!key.equals(ConfigSource.DELTASPIKE_ORDINAL))
+ {
+ // simply overwrite the old properties with the new ones.
+ mergedProperties.setProperty(key, value);
+ }
+ }
+ }
+
+ return mergedProperties;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4c410f32/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/PropertyLoaderTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/PropertyLoaderTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/PropertyLoaderTest.java
new file mode 100644
index 0000000..3dcb23a
--- /dev/null
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/PropertyLoaderTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.deltaspike.test.api.config;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.api.config.PropertyLoader;
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+import org.apache.deltaspike.core.util.ProjectStageProducer;
+import org.apache.deltaspike.test.category.SeCategory;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.util.Properties;
+
+public class PropertyLoaderTest
+{
+ @Before
+ public void init()
+ {
+ ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
+ }
+
+
+ @Test
+ public void testNotExistingPropertyLoading() throws Exception
+ {
+ Assert.assertNull(PropertyLoader.getProperties("notexistingProperty"));
+ Assert.assertNull(PropertyLoader.getProperties("notexistingProperty.properties"));
+ }
+
+ @Test
+ public void testStandardPropertyLoading() throws Exception
+ {
+ checkProperties("test", "1");
+ checkProperties("test.properties", "1");
+ }
+
+ @Test
+ public void testProjectStagedPropertyLoading() throws Exception
+ {
+ checkProperties("test2", "2");
+ checkProperties("test2.properties", "2");
+ }
+
+
+ private void checkProperties(String propertyFile, String expectedValue)
+ {
+ Properties p = PropertyLoader.getProperties(propertyFile);
+ Assert.assertNotNull(p);
+ Assert.assertEquals(1, p.size());
+ Assert.assertEquals(expectedValue, p.get("test.value"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4c410f32/deltaspike/core/api/src/test/resources/test.properties
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/resources/test.properties b/deltaspike/core/api/src/test/resources/test.properties
new file mode 100644
index 0000000..77365f4
--- /dev/null
+++ b/deltaspike/core/api/src/test/resources/test.properties
@@ -0,0 +1,21 @@
+#####################################################################################
+# 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.
+#####################################################################################
+
+
+test.value=1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4c410f32/deltaspike/core/api/src/test/resources/test2-UnitTest.properties
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/resources/test2-UnitTest.properties b/deltaspike/core/api/src/test/resources/test2-UnitTest.properties
new file mode 100644
index 0000000..c586672
--- /dev/null
+++ b/deltaspike/core/api/src/test/resources/test2-UnitTest.properties
@@ -0,0 +1,22 @@
+#####################################################################################
+# 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.
+#####################################################################################
+
+deltaspike_ordinal=120
+
+test.value=2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4c410f32/deltaspike/core/api/src/test/resources/test2.properties
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/resources/test2.properties b/deltaspike/core/api/src/test/resources/test2.properties
new file mode 100644
index 0000000..77365f4
--- /dev/null
+++ b/deltaspike/core/api/src/test/resources/test2.properties
@@ -0,0 +1,21 @@
+#####################################################################################
+# 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.
+#####################################################################################
+
+
+test.value=1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4c410f32/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/PersistenceConfigurationProviderImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/PersistenceConfigurationProviderImpl.java b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/PersistenceConfigurationProviderImpl.java
index f99c870..9aec0d6 100644
--- a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/PersistenceConfigurationProviderImpl.java
+++ b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/PersistenceConfigurationProviderImpl.java
@@ -23,10 +23,12 @@ import javax.enterprise.context.ApplicationScoped;
import java.util.Properties;
+import org.apache.deltaspike.core.api.config.PropertyLoader;
import org.apache.deltaspike.jpa.spi.entitymanager.PersistenceConfigurationProvider;
/**
- * Default implementation of the PersistenceConfigurationProvider
+ * Default implementation of the PersistenceConfigurationProvider.
+ *
*/
@ApplicationScoped
public class PersistenceConfigurationProviderImpl implements PersistenceConfigurationProvider
@@ -34,9 +36,12 @@ public class PersistenceConfigurationProviderImpl implements PersistenceConfigur
@Override
public Properties getEntityManagerFactoryConfiguration(String persistenceUnitName)
{
- Properties unitProperties = new Properties();
+ Properties unitProperties = PropertyLoader.getProperties("persistence-" + persistenceUnitName);
- //X TODO fill properties
+ if (unitProperties == null)
+ {
+ unitProperties = new Properties();
+ }
return unitProperties;
}