Always merge new MetaDataFactory settings with any previous settings

because many of its properties are often set implicitly and aren't meant to
erase other settings.



git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@489520 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
A. Abram White 2006-12-22 00:21:17 +00:00
parent aecff50b27
commit 8b6406724b
4 changed files with 123 additions and 16 deletions
openjpa-lib/src
main/java/org/apache/openjpa/lib/conf
test/java/org/apache/openjpa/lib/conf
openjpa-persistence/src/main/java/org/apache/openjpa/persistence

View File

@ -99,6 +99,41 @@ public class Configurations {
return clsName + "(" + props + ")";
}
/**
* Return a plugin string that combines the properties of the given plugin
* strings, where properties of <code>override</code> will override the
* same properties of <code>orig</code>.
*/
public static String combinePlugins(String orig, String override) {
if (StringUtils.isEmpty(orig))
return override;
if (StringUtils.isEmpty(override))
return orig;
String origCls = getClassName(orig);
String overrideCls = getClassName(override);
String cls;
if (StringUtils.isEmpty(origCls))
cls = overrideCls;
else if (StringUtils.isEmpty(overrideCls))
cls = origCls;
else if (!origCls.equals(overrideCls))
return override; // completely different plugin
else
cls = origCls;
String origProps = getProperties(orig);
String overrideProps = getProperties(override);
if (StringUtils.isEmpty(origProps))
return getPlugin(cls, overrideProps);
if (StringUtils.isEmpty(overrideProps))
return getPlugin(cls, origProps);
Properties props = parseProperties(origProps);
props.putAll(parseProperties(overrideProps));
return getPlugin(cls, serializeProperties(props));
}
/**
* Create the instance with the given class name, using the given
* class loader. No configuration of the instance is performed by

View File

@ -12,6 +12,9 @@
*/
package org.apache.openjpa.lib.conf;
import java.util.HashMap;
import java.util.Map;
import org.apache.openjpa.lib.test.AbstractTestCase;
import org.apache.openjpa.lib.util.Options;
@ -77,6 +80,62 @@ public class TestConfigurations extends AbstractTestCase {
assertEquals("baz baz", opts.getProperty("biz"));
}
public void testCombinePlugins() {
assertPluginsCombined("jpa", null,
null, null,
"jpa", null);
assertPluginsCombined("jpa", null,
"jpa", null,
"jpa", null);
assertPluginsCombined("jdo", null,
"jpa", null,
"jpa", null);
assertPluginsCombined("jdo", new String[] { "foo", "bar" },
"jpa", null,
"jpa", null);
assertPluginsCombined("jdo", new String[] { "foo", "bar" },
"jpa", new String[] { "biz", "baz" },
"jpa", new String[] { "biz", "baz" });
assertPluginsCombined("jdo", new String[] { "foo", "bar" },
null, new String[] { "biz", "baz" },
"jdo", new String[] { "foo", "bar", "biz", "baz" });
assertPluginsCombined(null, new String[] { "foo", "bar" },
null, new String[] { "biz", "baz" },
null, new String[] { "foo", "bar", "biz", "baz" });
assertPluginsCombined(null, new String[] { "foo", "bar" },
"jpa", new String[] { "biz", "baz" },
"jpa", new String[] { "foo", "bar", "biz", "baz" });
assertPluginsCombined("jpa", new String[] { "foo", "bar" },
"jpa", new String[] { "biz", "baz" },
"jpa", new String[] { "foo", "bar", "biz", "baz" });
assertPluginsCombined("jpa", new String[] { "foo", "bar" },
"jpa", new String[] { "foo", "baz" },
"jpa", new String[] { "foo", "baz" });
}
private void assertPluginsCombined(String cls1, String[] props1,
String cls2, String[] props2, String expCls, String[] expProps) {
String plugin1 = Configurations.getPlugin(cls1,
Configurations.serializeProperties(toProperties(props1)));
String plugin2 = Configurations.getPlugin(cls2,
Configurations.serializeProperties(toProperties(props2)));
String res = Configurations.combinePlugins(plugin1, plugin2);
String resCls = Configurations.getClassName(res);
Map resProps = Configurations.parseProperties(Configurations.
getProperties(res));
assertEquals(expCls, resCls);
assertEquals(toProperties(expProps), resProps);
}
private static Map toProperties(String[] props) {
Map map = new HashMap();
if (props != null)
for (int i = 0; i < props.length; i++)
map.put(props[i], props[++i]);
return map;
}
public static void main(String[] args) {
main(TestConfigurations.class);
}

View File

@ -32,10 +32,11 @@ import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
import org.apache.openjpa.conf.OpenJPAProductDerivation;
import org.apache.openjpa.lib.conf.AbstractProductDerivation;
import org.apache.openjpa.lib.conf.ProductDerivations;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.ConfigurationProvider;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.conf.MapConfigurationProvider;
import org.apache.openjpa.lib.conf.ProductDerivations;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.meta.XMLMetaDataParser;
import org.apache.openjpa.lib.util.Localizer;
@ -382,10 +383,27 @@ public class PersistenceProductDerivation
@Override
public void setInto(Configuration conf) {
if (conf instanceof OpenJPAConfiguration)
((OpenJPAConfiguration) conf).setSpecification(SPEC_JPA);
super.setInto(conf, null);
if (conf instanceof OpenJPAConfiguration) {
OpenJPAConfiguration oconf = (OpenJPAConfiguration) conf;
oconf.setSpecification(SPEC_JPA);
// we merge several persistence.xml elements into the
// MetaDataFactory property implicitly. if the user has a
// global openjpa.xml with this property set, its value will
// get overwritten by our implicit setting. so instead, combine
// the global value with our settings
String orig = oconf.getMetaDataFactory();
if (!StringUtils.isEmpty(orig)) {
String key = ProductDerivations.getConfigurationKey
("MetaDataFactory", getProperties());
Object override = getProperties().get(key);
if (override instanceof String)
addProperty(key, Configurations.combinePlugins(orig,
(String) override));
}
}
super.setInto(conf, null);
Log log = conf.getConfigurationLog();
if (log.isTraceEnabled()) {
String src = (_source == null) ? "?" : _source;

View File

@ -33,6 +33,7 @@ import javax.sql.DataSource;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.conf.ProductDerivations;
import org.apache.openjpa.lib.meta.SourceTracker;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.MultiClassLoader;
@ -404,20 +405,14 @@ public class PersistenceUnitInfoImpl
}
metaFactoryProps.put("Resources", rsrcs.toString());
}
// set persistent class locations as properties of metadata factory,
// combining them with any existing metadata factory props
if (!metaFactoryProps.isEmpty()) {
// set persistent class locations as properties of metadata factory
String factory = (String) Configurations.getProperty
String key = ProductDerivations.getConfigurationKey
("MetaDataFactory", map);
if (factory == null)
factory = Configurations.serializeProperties(metaFactoryProps);
else {
String clsName = Configurations.getClassName(factory);
metaFactoryProps.putAll(Configurations.parseProperties
(Configurations.getProperties(factory)));
factory = Configurations.getPlugin(clsName,
Configurations.serializeProperties(metaFactoryProps));
}
map.put("openjpa.MetaDataFactory", factory);
map.put(key, Configurations.combinePlugins((String) map.get(key),
Configurations.serializeProperties(metaFactoryProps)));
}
// always record provider name for product derivations to access