Author: ppoddar
Date: Wed Jan 7 11:38:45 2009
New Revision: 732443
URL: http://svn.apache.org/viewvc?rev=732443&view=rev
Log:
OPENJPA-850: Add notion of equivalent property keys for configurable Value. Use
this facility to support new javax.persistence.* style property keys alongside
openjpa.* style property keys.
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/lib/conf/TestEquivalentConfiguration.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/lib/conf/META-INF/persistence-config.xml
- copied unchanged from r732418,
openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/lib/conf/META-INF/persistence.xml
Removed:
openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/lib/conf/META-INF/persistence.xml
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Value.java
openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties
openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/TestValue.java
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java?rev=732443&r1=732442&r2=732443&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
Wed Jan 7 11:38:45 2009
@@ -320,9 +320,17 @@
connectionUserName = addString("ConnectionUserName");
+ connectionUserName.addEquivalentKey("javax.persistence.jdbc.user");
+
connectionPassword = addString("ConnectionPassword");
+ connectionPassword.addEquivalentKey("javax.persistence.jdbc.password");
+
connectionURL = addString("ConnectionURL");
+ connectionURL.addEquivalentKey("javax.persistence.jdbc.url");
+
connectionDriverName = addString("ConnectionDriverName");
+ connectionDriverName.addEquivalentKey("javax.persistence.jdbc.driver");
+
connectionFactoryName = addString("ConnectionFactoryName");
connectionProperties = addString("ConnectionProperties");
connectionFactoryProperties = addString("ConnectionFactoryProperties");
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?rev=732443&r1=732442&r2=732443&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
Wed Jan 7 11:38:45 2009
@@ -2390,10 +2390,7 @@
}
public void valueChanged(Value val) {
- if (val == null)
- return;
- String key = val.getProperty();
- if ("DataCacheTimeout".equals(key)) {
+ if (val != null && val.matches("DataCacheTimeout")) {
_cacheTimeout = Integer.MIN_VALUE;
}
}
Modified:
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java?rev=732443&r1=732442&r2=732443&view=diff
==============================================================================
---
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java
(original)
+++
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java
Wed Jan 7 11:38:45 2009
@@ -248,8 +248,8 @@
// search backwards so that custom values added after construction
// are found quickly, since this will be the std way of accessing them
- for(Value val : _vals) {
- if (val.getProperty().equals(property))
+ for (Value val : _vals) {
+ if (val.matches(property))
return val;
}
return null;
@@ -327,10 +327,10 @@
if (_props != null) {
if (newString == null)
Configurations.removeProperty(val.getProperty(), _props);
- else if (Configurations.containsProperty(val.getProperty(), _props)
+ else if (Configurations.containsProperty(val, _props)
|| val.getDefault() == null
|| !val.getDefault().equals(newString))
- put(_props, val, newString);
+ setValue(_props, val, newString);
}
}
@@ -589,13 +589,13 @@
// if key in existing properties, we already know value is up
// to date
if (_props != null && Configurations.containsProperty
- (val.getProperty(), _props))
+ (val, _props))
continue;
str = val.getString();
if (str != null && (storeDefaults
|| !str.equals(val.getDefault())))
- put(clone, val, str);
+ setValue(clone, val, str);
}
if (_props == null)
_props = new HashMap(clone);
@@ -629,11 +629,10 @@
Map remaining = new HashMap(map);
boolean ser = true;
Object o;
- for(Value val : _vals) {
- o = get(map, val, true);
+ for (Value val : _vals) {
+ o = findValue(map, val);
if (o == null)
continue;
-
if (o instanceof String) {
if (!StringUtils.equals((String) o, val.getString()))
val.setString((String) o);
@@ -671,7 +670,7 @@
* Use this method instead of attempting to add the value directly because
* this will account for the property prefix.
*/
- private void put(Map map, Value val, Object o) {
+ private void setValue(Map map, Value val, Object o) {
Object key = val.getLoadKey();
if (key == null)
key = "openjpa." + val.getProperty();
@@ -679,14 +678,25 @@
}
/**
- * Look up the given value, testing all available prefixes.
- */
- private Object get(Map map, Value val, boolean setLoadKey) {
- String key = ProductDerivations.getConfigurationKey(
- val.getProperty(), map);
- if (map.containsKey(key) && setLoadKey)
- val.setLoadKey(key);
- return map.get(key);
+ * Look up the given value, testing all available prefixes and all possible
+ * property names. Detects if the given map contains multiple keys that
+ * are equivalent names for the given value.
+ */
+ private Object findValue(Map map, Value val) {
+ Object result = null;
+ List<String> partialKeys = val.getPropertyKeys();
+ for (String partialKey : partialKeys) {
+ String key = ProductDerivations.getConfigurationKey(
+ partialKey, map);
+ if (map.containsKey(key)) {
+ // do not return immediately. Looping through all equivalent
+ // property names will detect if the Map contains multiple keys
+ // that are equivalent as it tries to set load key.
+ val.setLoadKey(key);
+ result = map.get(key);
+ }
+ }
+ return result;
}
/**
Modified:
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java?rev=732443&r1=732442&r2=732443&view=diff
==============================================================================
---
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java
(original)
+++
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java
Wed Jan 7 11:38:45 2009
@@ -635,6 +635,22 @@
* Test whether the map contains the given partial key, prefixed with any
* possible configuration prefix.
*/
+ public static boolean containsProperty(Value value, Map props) {
+ if (value == null || props == null || props.isEmpty())
+ return false;
+ List<String> partialKeys = value.getPropertyKeys();
+ for (String partialKey : partialKeys) {
+ if (props.containsKey(
+ ProductDerivations.getConfigurationKey(partialKey, props)))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Test whether the map contains the given partial key, prefixed with any
+ * possible configuration prefix.
+ */
public static boolean containsProperty(String partialKey, Map props) {
if (partialKey == null || props == null || props.isEmpty())
return false;
Modified:
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java?rev=732443&r1=732442&r2=732443&view=diff
==============================================================================
---
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java
(original)
+++
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java
Wed Jan 7 11:38:45 2009
@@ -40,6 +40,7 @@
* Utilities for running product derivations.
*
* @author Abe White
+ * @author Pinaki Poddar
* @nojavadoc
*/
public class ProductDerivations {
@@ -133,18 +134,22 @@
}
/**
- * Determine the full key name for <code>key</code>, given the registered
- * prefixes and the entries in <code>map</code>. This method
+ * Determine the full key name for <code>partialKey</code>, given the
+ * registered prefixes and the entries in <code>map</code>. This method
* computes the appropriate configuration prefix to use by looking
* through <code>map</code> for a key starting with any of the known
- * configuration prefixes and ending with <code>key</code> and, if a
+ * configuration prefixes and ending with <code>partialKey</code> and, if a
* value is found, using the prefix of that key. Otherwise, it uses
* the first registered prefix.
*
+ * The given <code>partialKey</code> is first tested for containment in the
+ * given map without any prefix.
+ *
* @since 0.9.7
*/
public static String getConfigurationKey(String partialKey, Map map) {
- String firstKey = null;
+ String firstKey = (map != null && map.containsKey(partialKey))
+ ? partialKey : null;
for (int i = 0; map != null && i < _prefixes.length; i++) {
String fullKey = _prefixes[i] + "." + partialKey;
if (map.containsKey(fullKey)) {
Modified:
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Value.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Value.java?rev=732443&r1=732442&r2=732443&view=diff
==============================================================================
---
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Value.java
(original)
+++
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Value.java
Wed Jan 7 11:38:45 2009
@@ -21,8 +21,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.lib.util.Localizer;
@@ -32,7 +34,7 @@
* A configuration value.
*
* @author Marc Prud'hommeaux
- * @author Pinaki Poddar (added dynamic Value support)
+ * @author Pinaki Poddar
*/
public abstract class Value implements Cloneable {
@@ -49,6 +51,7 @@
private Class scope = null;
private boolean isDynamic = false;
private String originalValue = null;
+ private Set<String> otherNames = null;
/**
* Default constructor.
@@ -80,7 +83,56 @@
public void setProperty(String prop) {
this.prop = prop;
}
-
+
+ /**
+ * Adds a moniker that is equivalent to the original property key used
+ * during construction.
+ *
+ * @since 2.0.0
+ */
+ public void addEquivalentKey(String other) {
+ if (otherNames == null)
+ otherNames = new HashSet<String>();
+ otherNames.add(other);
+ }
+
+ /**
+ * Gets the unmodifiable view of the equivalent keys or an empty set if
+ * no equivalent key has been added.
+ *
+ * @since 2.0.0
+ */
+ public Set<String> getEquivalentKeys() {
+ return otherNames == null ? Collections.EMPTY_SET
+ : Collections.unmodifiableSet(otherNames);
+ }
+
+ /**
+ * Gets unmodifiable view of all the property keys set on this receiver.
+ * The 0-th element in the returned list is always the same as the
original
+ * key returned by {...@link #getProperty()} method.
+ *
+ * @since 2.0.0
+ */
+ public List<String> getPropertyKeys() {
+ List<String> result = new ArrayList<String>(1 +
+ (otherNames ==null ? 0 : otherNames.size()));
+ result.add(getProperty());
+ if (otherNames != null)
+ result.addAll(otherNames);
+ return Collections.unmodifiableList(result);
+ }
+
+ /**
+ * Affirms if the given key matches the property (or any of its
equivalent).
+ *
+ * @since 2.0.0
+ */
+ public boolean matches(String p) {
+ return getProperty().equals(p) ||
+ (otherNames != null && otherNames.contains(p));
+ }
+
/**
* The key under which this value was loaded, or null.
*/
@@ -89,10 +141,15 @@
}
/**
- * The key under which this value was loaded, or null.
- */
- public void setLoadKey(String loadKey) {
- this.loadKey = loadKey;
+ * Sets key under which this value was loaded.
+ * @exception if called with a non-null key which is different from an
+ * already loaded key.
+ */
+ public void setLoadKey(String key) {
+ if (this.loadKey != null && key != null && !this.loadKey.equals(key))
+ throw new ParseException(s_loc.get("multiple-load-key",
+ loadKey, key));
+ loadKey = key;
}
/**
Modified:
openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties?rev=732443&r1=732442&r2=732443&view=diff
==============================================================================
---
openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties
(original)
+++
openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties
Wed Jan 7 11:38:45 2009
@@ -114,4 +114,6 @@
veto-change: Can not modify "{0}" because the property is not dynamic and the \
current configuration is read-only.
-jndi-lookup-failed: JNDI lookup for "{0}" with key "{1}" returned null.
\ No newline at end of file
+jndi-lookup-failed: JNDI lookup for "{0}" with key "{1}" returned null.
+multiple-load-key: Equivalent property keys "{0}" and "{1}" are specified in \
+ configuration.
\ No newline at end of file
Modified:
openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/TestValue.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/TestValue.java?rev=732443&r1=732442&r2=732443&view=diff
==============================================================================
---
openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/TestValue.java
(original)
+++
openjpa/trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/conf/TestValue.java
Wed Jan 7 11:38:45 2009
@@ -54,4 +54,47 @@
sValue.getAliases()[1]);
assertEquals("Array of aliases not set by value", aName, aStrings[1]);
}
+
+ public void testEquivalentValueCanBeSet() {
+ SimpleValue v = new SimpleValue();
+ v.setProperty("main");
+ v.addEquivalentKey("eqivalent1");
+ v.addEquivalentKey("eqivalent2");
+ assertEquals(2, v.getEquivalentKeys().size());
+ assertEquals(3, v.getPropertyKeys().size());
+ assertEquals(v.getProperty(), v.getPropertyKeys().get(0));
+
+ assertTrue(v.matches("main"));
+ assertTrue(v.matches("eqivalent1"));
+ assertTrue(v.matches("eqivalent2"));
+ assertFalse(v.matches("eqivalent3"));
+ }
+
+ public void testEquivalentValuesAreUnmodifable() {
+ SimpleValue v = new SimpleValue();
+ v.setProperty("main");
+ v.addEquivalentKey("eqivalent1");
+ v.addEquivalentKey("eqivalent2");
+
+ try {
+ v.getPropertyKeys().add("extra");
+ fail();
+ } catch (UnsupportedOperationException ex) {
+ // good
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ fail();
+ }
+
+ try {
+ v.getEquivalentKeys().add("impossible");
+ fail();
+ } catch (UnsupportedOperationException ex) {
+ // good
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ fail();
+ }
+ }
+
}
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/lib/conf/TestEquivalentConfiguration.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/lib/conf/TestEquivalentConfiguration.java?rev=732443&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/lib/conf/TestEquivalentConfiguration.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/lib/conf/TestEquivalentConfiguration.java
Wed Jan 7 11:38:45 2009
@@ -0,0 +1,367 @@
+/*
+ * 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.openjpa.lib.conf;
+
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.enhance.TestEnhancementWithMultiplePUs;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.test.AllowFailure;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests that configuration properties can be specified both as new
+ * javax.persistence.* namespace and old openjpa.* namespace. The two style can
+ * also be mixed where one property is in javax.* namespace the other in
+ * openjpa.*. But same property can not be specified in both style.
+ *
+ * Tests with different configuration sources such as persistence.xml, System
+ * properties and runtime properties.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class TestEquivalentConfiguration extends TestCase {
+ private EntityManagerFactory emf;
+
+ private Properties _system;
+
+ private static final String OLD_STYLE_URL_KEY = "openjpa.ConnectionURL";
+ private static final String OLD_STYLE_DRIVER_KEY =
"openjpa.ConnectionDriverName";
+ private static final String NEW_STYLE_DRIVER_KEY =
"javax.persistence.jdbc.driver";
+ private static final String NEW_STYLE_URL_KEY =
"javax.persistence.jdbc.url";
+
+ private static final String[] KEYS = {
+ OLD_STYLE_DRIVER_KEY, OLD_STYLE_URL_KEY,
+ NEW_STYLE_DRIVER_KEY, NEW_STYLE_URL_KEY };
+
+ // NOTE: Non-standard naming because another test in the harness scans all
+ // META-INF/persistence.xml and fails as this file contains conflicting
+ // property keys for testing.
+ private static final String PERSISTENCE_UNIT =
"org/apache/openjpa/lib/conf/META-INF/persistence-config.xml";
+
+ private static final String OLD_STYLE_UNIT_NAME = "old-style";
+ private static final String NEW_STYLE_UNIT_NAME = "new-style";
+ private static final String MIXED_STYLE_UNIT_NAME = "mixed-style";
+ private static final String CONFLICT_STYLE_UNIT_NAME = "conflict-style";
+
+ private static final String SYSTEM_CONFIGURED_UNIT_NAME =
"system-configured";
+ private static final String RUNTIME_CONFIGURED_UNIT_NAME =
"runtime-configured";
+
+ private static final String URL =
"jdbc:derby:target/database/openjpa-test-database;create=true";
+ private static final String DRIVER =
"org.apache.derby.jdbc.EmbeddedDriver";
+
+ /**
+ * Erase that System properties to ensure they are not impacting the
+ * configuration as test harness inserts the System properties for
+ * connection parameters.
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ _system = backup();
+ clear(_system);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ restore(_system);
+ super.tearDown();
+ }
+
+ /**
+ * Tests that openjpa.* namespace can be used for persistence.xml.
+ */
+ public void testOldStylePersistenceUnitConfiguration() {
+ emf =
OpenJPAPersistence.createEntityManagerFactory(OLD_STYLE_UNIT_NAME,
+ PERSISTENCE_UNIT);
+
+ assertNotNull(emf);
+ assertTrue(containsProperty(OLD_STYLE_DRIVER_KEY));
+ assertTrue(containsProperty(OLD_STYLE_URL_KEY));
+ assertFalse(containsProperty(NEW_STYLE_DRIVER_KEY));
+ assertFalse(containsProperty(NEW_STYLE_URL_KEY));
+
+ verifyDatabaseConnection();
+ }
+
+ /**
+ * Tests that javax.* namespace can be used for persistence.xml.
+ */
+ public void testNewStylePersistenceUnitConfiguration() {
+ emf =
OpenJPAPersistence.createEntityManagerFactory(NEW_STYLE_UNIT_NAME,
+ PERSISTENCE_UNIT);
+
+ assertNotNull(emf);
+ assertTrue(containsProperty(NEW_STYLE_DRIVER_KEY));
+ assertTrue(containsProperty(NEW_STYLE_URL_KEY));
+ assertFalse(containsProperty(OLD_STYLE_DRIVER_KEY));
+ assertFalse(containsProperty(OLD_STYLE_URL_KEY));
+
+ verifyDatabaseConnection();
+ }
+
+ /**
+ * Tests that openjpa.* and javax.* namespace can both be used for
+ * persistence.xml.
+ */
+ public void testMixedStylePersistenceUnitConfiguration() {
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ MIXED_STYLE_UNIT_NAME, PERSISTENCE_UNIT);
+
+ assertNotNull(emf);
+ assertTrue(containsProperty(NEW_STYLE_DRIVER_KEY));
+ assertFalse(containsProperty(NEW_STYLE_URL_KEY));
+ assertFalse(containsProperty(OLD_STYLE_DRIVER_KEY));
+ assertTrue(containsProperty(OLD_STYLE_URL_KEY));
+
+ verifyDatabaseConnection();
+ }
+
+ /**
+ * Tests that openjpa.* and javax.* namespace can not both be used for the
+ * same property in persistence.xml.
+ *
+ */
+
+ public void testConflictStylePersistenceUnitConfiguration() {
+ try {
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ CONFLICT_STYLE_UNIT_NAME, PERSISTENCE_UNIT);
+ fail();
+ } catch (RuntimeException ex) {
+ // good
+ }
+ }
+
+ /**
+ * Tests that javax.* namespace can be used for System properties.
+ */
+ public void testNewStyleSystemPropertyConfiguration() {
+ try {
+ System.setProperty(NEW_STYLE_DRIVER_KEY, DRIVER);
+ System.setProperty(NEW_STYLE_URL_KEY, URL);
+
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ SYSTEM_CONFIGURED_UNIT_NAME, PERSISTENCE_UNIT);
+ } finally {
+ System.getProperties().remove(NEW_STYLE_DRIVER_KEY);
+ System.getProperties().remove(NEW_STYLE_URL_KEY);
+ }
+
+ assertNotNull(emf);
+ assertTrue(containsProperty(NEW_STYLE_DRIVER_KEY));
+ assertTrue(containsProperty(NEW_STYLE_URL_KEY));
+ assertFalse(containsProperty(OLD_STYLE_DRIVER_KEY));
+ assertFalse(containsProperty(OLD_STYLE_URL_KEY));
+
+ verifyDatabaseConnection();
+ }
+
+ /**
+ * Tests that openjpa.* namespace can be used for System properties.
+ */
+ public void testOldStyleSystemPropertyConfiguration() {
+ try {
+ System.setProperty(OLD_STYLE_DRIVER_KEY, DRIVER);
+ System.setProperty(OLD_STYLE_URL_KEY, URL);
+
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ SYSTEM_CONFIGURED_UNIT_NAME, PERSISTENCE_UNIT);
+ } finally {
+ System.getProperties().remove(OLD_STYLE_DRIVER_KEY);
+ System.getProperties().remove(OLD_STYLE_URL_KEY);
+ }
+ assertNotNull(emf);
+ assertFalse(containsProperty(NEW_STYLE_DRIVER_KEY));
+ assertFalse(containsProperty(NEW_STYLE_URL_KEY));
+ assertTrue(containsProperty(OLD_STYLE_DRIVER_KEY));
+ assertTrue(containsProperty(OLD_STYLE_URL_KEY));
+
+ verifyDatabaseConnection();
+ }
+
+ /**
+ * Tests that openjpa.* and javax.* namespace can both be used for System
+ * properties.
+ */
+ public void testMixedStyleSystemPropertyConfiguration() {
+ System.setProperty(OLD_STYLE_DRIVER_KEY, DRIVER);
+ System.setProperty(NEW_STYLE_URL_KEY, URL);
+ try {
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ SYSTEM_CONFIGURED_UNIT_NAME, PERSISTENCE_UNIT);
+ } finally {
+ System.getProperties().remove(OLD_STYLE_DRIVER_KEY);
+ System.getProperties().remove(NEW_STYLE_URL_KEY);
+ }
+
+ assertNotNull(emf);
+ assertFalse(containsProperty(NEW_STYLE_DRIVER_KEY));
+ assertTrue(containsProperty(NEW_STYLE_URL_KEY));
+ assertTrue(containsProperty(OLD_STYLE_DRIVER_KEY));
+ assertFalse(containsProperty(OLD_STYLE_URL_KEY));
+
+ verifyDatabaseConnection();
+ }
+
+ /**
+ * Tests that openjpa.* and javax.* namespace can not both be used for the
+ * same property in System configuration.
+ */
+ public void testConflictStyleSystemPropertyConfiguration() {
+ System.setProperty(OLD_STYLE_DRIVER_KEY, DRIVER);
+ System.setProperty(NEW_STYLE_DRIVER_KEY, DRIVER);
+ try {
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ SYSTEM_CONFIGURED_UNIT_NAME, PERSISTENCE_UNIT);
+ fail();
+ } catch (RuntimeException ex) {
+ // good
+ } finally {
+ System.getProperties().remove(OLD_STYLE_DRIVER_KEY);
+ System.getProperties().remove(NEW_STYLE_DRIVER_KEY);
+ }
+ }
+
+ /**
+ * Tests that openjpa.* namespace can be used for runtime configuration.
+ */
+ public void testOldStyleRuntimePropertyConfiguration() {
+ Properties conf = new Properties();
+ conf.setProperty(OLD_STYLE_DRIVER_KEY, DRIVER);
+ conf.setProperty(OLD_STYLE_URL_KEY, URL);
+
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ RUNTIME_CONFIGURED_UNIT_NAME, PERSISTENCE_UNIT, conf);
+
+ assertNotNull(emf);
+ assertTrue(containsProperty(OLD_STYLE_DRIVER_KEY));
+ assertTrue(containsProperty(OLD_STYLE_URL_KEY));
+ assertFalse(containsProperty(NEW_STYLE_DRIVER_KEY));
+ assertFalse(containsProperty(NEW_STYLE_URL_KEY));
+
+ verifyDatabaseConnection();
+ }
+
+ /**
+ * Tests that javax.* namespace can be used for runtime configuration.
+ */
+ public void testNewStyleRuntimePropertyConfiguration() {
+ Properties conf = new Properties();
+ conf.setProperty(NEW_STYLE_DRIVER_KEY, DRIVER);
+ conf.setProperty(NEW_STYLE_URL_KEY, URL);
+
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ RUNTIME_CONFIGURED_UNIT_NAME, PERSISTENCE_UNIT, conf);
+
+ assertNotNull(emf);
+ assertFalse(containsProperty(OLD_STYLE_DRIVER_KEY));
+ assertFalse(containsProperty(OLD_STYLE_URL_KEY));
+ assertTrue(containsProperty(NEW_STYLE_DRIVER_KEY));
+ assertTrue(containsProperty(NEW_STYLE_URL_KEY));
+
+ verifyDatabaseConnection();
+ }
+
+ /**
+ * Tests that openjpa.* and javax.* namespace can both be used for runtime
+ * configuration.
+ */
+ public void testMixedStyleRuntimePropertyConfiguration() {
+ Properties conf = new Properties();
+ conf.setProperty(OLD_STYLE_DRIVER_KEY, DRIVER);
+ conf.setProperty(NEW_STYLE_URL_KEY, URL);
+
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ RUNTIME_CONFIGURED_UNIT_NAME, PERSISTENCE_UNIT, conf);
+
+ assertNotNull(emf);
+ assertTrue(containsProperty(OLD_STYLE_DRIVER_KEY));
+ assertFalse(containsProperty(OLD_STYLE_URL_KEY));
+ assertFalse(containsProperty(NEW_STYLE_DRIVER_KEY));
+ assertTrue(containsProperty(NEW_STYLE_URL_KEY));
+
+ verifyDatabaseConnection();
+ }
+
+ /**
+ * Tests that openjpa.* and javax.* namespace can not both be used for the
+ * same property in runtime configuration.
+ */
+ public void testConflictStyleRuntimePropertyConfiguration() {
+ Properties conf = new Properties();
+ conf.setProperty(OLD_STYLE_DRIVER_KEY, DRIVER);
+ conf.setProperty(NEW_STYLE_DRIVER_KEY, DRIVER);
+
+ try {
+ emf = OpenJPAPersistence.createEntityManagerFactory(
+ RUNTIME_CONFIGURED_UNIT_NAME, PERSISTENCE_UNIT, conf);
+ fail();
+ } catch (RuntimeException ex) {
+ // good
+ }
+ }
+
+ void verifyDatabaseConnection() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ em.flush();
+ em.getTransaction().commit();
+ }
+
+ boolean containsProperty(String key) {
+ return getConfiguration().toProperties(true).containsKey(key);
+ }
+
+ OpenJPAConfiguration getConfiguration() {
+ return ((OpenJPAEntityManagerFactorySPI)OpenJPAPersistence.cast(emf))
+ .getConfiguration();
+ }
+
+ Properties backup() {
+ Properties p = new Properties();
+ for (String key : KEYS) {
+ if (System.getProperty(key) != null) {
+ p.setProperty(key, System.getProperty(key));
+ }
+ }
+ return p;
+ }
+
+ private void clear(Properties p) {
+ for (Object key : p.keySet()) {
+ System.getProperties().remove(key);
+ }
+ }
+
+ private void restore(Properties p) {
+ for (Object key : p.keySet()) {
+ System.setProperty(key.toString(), p.get(key).toString());
+ }
+ }
+}