You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/02/03 23:38:46 UTC

svn commit: r740492 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-kernel/src/main/resources/org/apache/openjpa/conf/ openjpa-kernel/src/test/java/org/apache/openjpa/conf/ openjpa-lib/src/main/java/org/apache/openjpa...

Author: ppoddar
Date: Tue Feb  3 22:38:45 2009
New Revision: 740492

URL: http://svn.apache.org/viewvc?rev=740492&view=rev
Log:
OPENJPA-857: Extend support for Specification through a more structured type to carry Version information. Will help Compatibitibility (and may be others) that needs to tune their behavior based on current Specification version as well as backward compatibie versions.

Added:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Specification.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/SpecificationPlugin.java
    openjpa/trunk/openjpa-kernel/src/test/java/org/apache/openjpa/conf/TestSpecification.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestSpecificationConfiguration.java
Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
    openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/conf/localizer.properties
    openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java
    openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java?rev=740492&r1=740491&r2=740492&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java Tue Feb  3 22:38:45 2009
@@ -24,12 +24,13 @@
 import org.apache.openjpa.datacache.DataCache;
 import org.apache.openjpa.datacache.DataCacheManager;
 import org.apache.openjpa.ee.ManagedRuntime;
+import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
+import org.apache.openjpa.event.BrokerFactoryEventManager;
 import org.apache.openjpa.event.OrphanedKeyAction;
 import org.apache.openjpa.event.RemoteCommitEventManager;
 import org.apache.openjpa.event.RemoteCommitProvider;
 import org.apache.openjpa.kernel.AutoClear;
 import org.apache.openjpa.kernel.AutoDetach;
-import org.apache.openjpa.kernel.Broker;
 import org.apache.openjpa.kernel.BrokerFactory;
 import org.apache.openjpa.kernel.BrokerImpl;
 import org.apache.openjpa.kernel.ConnectionRetainModes;
@@ -41,7 +42,6 @@
 import org.apache.openjpa.kernel.RestoreState;
 import org.apache.openjpa.kernel.SavepointManager;
 import org.apache.openjpa.kernel.Seq;
-import org.apache.openjpa.event.BrokerFactoryEventManager;
 import org.apache.openjpa.kernel.exps.AggregateListener;
 import org.apache.openjpa.kernel.exps.FilterListener;
 import org.apache.openjpa.lib.conf.Configuration;
@@ -213,20 +213,47 @@
     public Collection supportedOptions();
 
     /**
-     * A configuration can be set with defaults for a specific specification.
+     * Get a name of the Specification. Specification determines various 
+     * important default behaviors.
      */
     public String getSpecification();
     
     /**
+     * Get the Specification. Specification determines various important default 
+     * behaviors.
+     * 
+     * @since 2.0.0
+     */
+    public Specification getSpecificationInstance();
+    
+    /**
+     * Set the Specification that this configuration should use for the
+     * various properties that need to have different defaults for different
+     * specification environments..
+     * 
+     * @param fullname of the specification that possibly encodes major and
+     * minor version information. For encoding format
+     * @see Specification#create(String)
+     */
+    public boolean setSpecification(String spec);
+    
+    /**
      * Set the specification that this configuration should use for the
      * various properties that need to have different defaults for different
-     * spec environments. This should be invoked before any configuration
-     * options are set, as it will mutate various values.
+     * specification environments. The given specification also carry version
+     * information which can help for setting, for example, various
+     * {@link Compatibility compatibility} options during runtime.
+     *   
+     * This should be invoked before any configuration options are set, as it 
+     * will mutate various values.
      * You can only assign the specification once, though it is not fatal
      * to attempt to do so multiple times. Attempts to set to null will
      * be ignored.
+     * 
+     * @since 2.0.0
+     * 
      */
-    public boolean setSpecification(String spec);
+    public boolean setSpecification(Specification spec);
 
     /**
      * The plugin string for the {@link ClassResolver} to use for custom

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=740492&r1=740491&r2=740492&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 Tue Feb  3 22:38:45 2009
@@ -28,10 +28,11 @@
 import org.apache.openjpa.datacache.DataCacheManager;
 import org.apache.openjpa.datacache.DataCacheManagerImpl;
 import org.apache.openjpa.ee.ManagedRuntime;
+import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
+import org.apache.openjpa.event.BrokerFactoryEventManager;
 import org.apache.openjpa.event.OrphanedKeyAction;
 import org.apache.openjpa.event.RemoteCommitEventManager;
 import org.apache.openjpa.event.RemoteCommitProvider;
-import org.apache.openjpa.event.BrokerFactoryEventManager;
 import org.apache.openjpa.kernel.AutoClear;
 import org.apache.openjpa.kernel.BrokerImpl;
 import org.apache.openjpa.kernel.ConnectionRetainModes;
@@ -45,7 +46,16 @@
 import org.apache.openjpa.kernel.Seq;
 import org.apache.openjpa.kernel.exps.AggregateListener;
 import org.apache.openjpa.kernel.exps.FilterListener;
-import org.apache.openjpa.lib.conf.*;
+import org.apache.openjpa.lib.conf.BooleanValue;
+import org.apache.openjpa.lib.conf.ConfigurationImpl;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.conf.IntValue;
+import org.apache.openjpa.lib.conf.ObjectValue;
+import org.apache.openjpa.lib.conf.PluginListValue;
+import org.apache.openjpa.lib.conf.PluginValue;
+import org.apache.openjpa.lib.conf.ProductDerivations;
+import org.apache.openjpa.lib.conf.StringListValue;
+import org.apache.openjpa.lib.conf.StringValue;
 import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.MetaDataFactory;
@@ -54,7 +64,6 @@
 import org.apache.openjpa.util.ImplHelper;
 import org.apache.openjpa.util.ProxyManager;
 import org.apache.openjpa.util.StoreFacadeTypeRegistry;
-import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
 
 /**
  * Implementation of the {@link OpenJPAConfiguration} interface.
@@ -139,7 +148,8 @@
     public CacheMarshallersValue cacheMarshallerPlugins;
     public BooleanValue eagerInitialization;
     public PluginValue preparedQueryCachePlugin;
-
+    public ObjectValue specification;
+    
     // custom values
     public BrokerFactoryValue brokerFactoryPlugin;
     public RemoteCommitProviderValue remoteProviderPlugin;
@@ -529,6 +539,11 @@
         
         eagerInitialization = addBoolean("InitializeEagerly");
         
+        specification = new SpecificationPlugin("Specification", 
+            getConfigurationLog());
+        addValue(specification);
+        specification.setInstantiatingGetter("getSpecificationInstance");
+        
         // initialize supported options that some runtimes may not support
         supportedOptions.add(OPTION_NONTRANS_READ);
         supportedOptions.add(OPTION_OPTIMISTIC);
@@ -556,22 +571,38 @@
         return supportedOptions;
     }
 
+    /**
+     * Get the name of the Specification only (not the version or other 
+     * information) or an empty String if not set.
+     * 
+     */
     public String getSpecification() {
-        return spec;
+        Specification spec = getSpecificationInstance();
+        return spec == null ? "" : spec.getName();
+    }
+    
+    public Specification getSpecificationInstance() {
+        return (Specification)specification.get();
     }
 
+    /**
+     * Sets Specification from the given String.
+     * 
+     * @param spec should be encoded in the format specified in {@link 
+     * Specification#create(String)}.
+     */
     public boolean setSpecification(String spec) {
         if (spec == null)
             return false;
-
-        if (this.spec != null) {
-            if (!this.spec.equals(spec)
-                && getConfigurationLog().isWarnEnabled())
-                getConfigurationLog().warn(
-                    _loc.get("diff-specs", this.spec, spec));
+        specification.setString(spec);
+        ProductDerivations.afterSpecificationSet(this);
+        return true;
+    }
+    
+    public boolean setSpecification(Specification newSpec) {
+        if (newSpec == null)
             return false;
-        }
-        this.spec = spec;
+        specification.set(newSpec);
         ProductDerivations.afterSpecificationSet(this);
         return true;
     }

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Specification.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Specification.java?rev=740492&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Specification.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Specification.java Tue Feb  3 22:38:45 2009
@@ -0,0 +1,208 @@
+/*
+ * 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.conf;
+
+import java.text.MessageFormat;
+
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * An immutable representation of a Specification supported by OpenJPA.
+ * 
+ * Available via {@linkplain OpenJPAConfiguration#getSpecificationInstance()()} 
+ * for configuration that may depend on Specification version.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class Specification {
+    private String _name;
+    private int    _major;
+    private String _minor;
+    private String _description;
+    
+    static final MessageFormat _format = new MessageFormat("{0} {1}.{2}");
+    static final String _printableFormat = "<name> [<major>[.<minor>]]";
+    static final MessageFormat _vformat = new MessageFormat("{0}.{1}");
+    static final String _printableVersionFormat = "<major>[.<minor>]";
+    private static Localizer _loc = Localizer.forPackage(Specification.class);
+    
+    private Specification(String name, int major, String minor) {
+        this._name = name == null ? "" : name.trim();
+        this._major = major;
+        this._minor = minor == null ? "" : minor.trim();
+    }
+    
+    /**
+     * Construct from a String that encodes name and version fields.
+     * 
+     * @param fullName a encoded string in the following prescribed format.
+     * <code>name major.minor</code> e.g. <code>JPA 2.0-draft</code>
+     * Only the 'name' field is mandatory. 
+     * 'major' version defaults to 1 and must be an integer. 
+     * 'minor' version defaults to 0 and can be a String. 
+     */
+    public static Specification create(String fullName) {
+        try {
+            Object[] tokens = _format.parse(fullName);
+            return new Specification(tokens[0].toString(),
+                tokens.length > 1 ? Integer.parseInt(tokens[1].toString()) : 1,
+                tokens.length > 2 ? tokens[2].toString() : "0");
+        } catch (Exception e) {
+            throw new UserException(_loc.get("spec-wrong-format", 
+                fullName, _printableFormat));
+        }
+    }
+    
+    /**
+     * Construct from a String and version.
+     * 
+     * @param name is the name of the Specification.
+     * @param version a encoded string in the following prescribed format.
+     * <code>major.minor</code> e.g. <code>2.0-draft</code>
+     * 'major' version defaults to 1 and must be an integer. 
+     * 'minor' version defaults to 0 and can be a String. 
+     */
+    public static Specification create(String name, String version) {
+        try {
+            Object[] tokens = _vformat.parse(version);
+            return new Specification(name,
+                tokens.length > 0 ? Integer.parseInt(tokens[0].toString()) : 1,
+                tokens.length > 1 ? tokens[1].toString() : "0");
+        } catch (Exception e) {
+            throw new UserException(_loc.get("spec-wrong-version-format", 
+                version, _printableVersionFormat));
+        }
+    }
+    
+    /**
+     * Construct from a String and major and minor version.
+     * 
+     * @param name is the name of the Specification.
+     * @param version a encoded string in the following prescribed format.
+     * <code>major.minor</code> e.g. <code>2.0-draft</code>
+     * 'major' version defaults to 1 and must be an integer. 
+     * 'minor' version defaults to 0 and can be a String. 
+     */
+    public static Specification create(String name, int major, String minor) {
+        return new Specification(name, major, minor);
+    }
+    
+    /**
+     * Construct from a String and major and minor version.
+     * 
+     * @param name is the name of the Specification.
+     * @param version a encoded string in the following prescribed format.
+     * <code>major.minor</code> e.g. <code>2.0-draft</code>
+     * 'major' version defaults to 1 and must be an integer. 
+     * 'minor' version defaults to 0 and can be a String. 
+     */
+    public static Specification create(String name, int major) {
+        return new Specification(name, major, "0");
+    }
+
+    /**
+     * Construct from a String and major and minor version.
+     * 
+     * @param name is the name of the Specification.
+     * @param version a encoded string in the following prescribed format.
+     * <code>major.minor</code> e.g. <code>2.0-draft</code>
+     * 'major' version defaults to 1 and must be an integer. 
+     * 'minor' version defaults to 0 and can be a String. 
+     */
+    public static Specification create(String name, int major, int minor) {
+        return new Specification(name, major, ""+minor);
+    }
+    
+    public Specification setDescription(String desc) {
+        _description = desc;
+        return this;
+    }
+    
+    public String getName() {
+        return _name;
+    }
+
+    public int getMajorVersion() {
+        return _major;
+    }
+
+    public String getMinorVersion() {
+        return _minor;
+    }
+
+    public String getDescription() {
+        return _description;
+    }
+
+    /**
+     * Get the Specification encoding format in {@link MessageFormat} syntax.   
+     */
+    public static String getFormat() {
+        return _printableFormat;
+    }
+    
+    /**
+     * Get the Specification version encoding format in {@link MessageFormat} 
+     * syntax.   
+     */
+    public static String getVersionFormat() {
+        return _printableVersionFormat;
+    }
+    
+    /**
+     * Affirms if the given argument is equal to this receiver.
+     * They are equal if
+     *    other is a String that equals this receiver's name ignoring case and
+     *    any leading or trailing blank spaces.
+     *    other is a Specification whose name equals this receiver's name 
+     *    ignoring case and any leading or trailing blank spaces.
+     *    or if they are same reference (of course)
+     */
+    public boolean equals(Object other) {
+        if (this == other)
+            return true;
+        if (other == null)
+            return false;
+        if (other instanceof String)
+            return _name.equalsIgnoreCase(((String)other).trim());
+        if (other instanceof Specification)
+            return _name.equalsIgnoreCase((((Specification)other)._name)
+                .trim());
+        return false;
+    }
+    
+    /**
+     * Compares major version number of the given Specification with this 
+     * receiver.
+
+     * @return 0 if they are equal.
+     *       > 0 if this receiver is higher version.
+     *       < 0 if this receiver is lower version.
+     */
+    public int compareVersion(Specification other) {
+        return _major > other._major ? 1 : _major == other._major ? 0 : -1;
+        
+    }
+    
+    public String toString() {
+        return MessageFormat.format(_format.toPattern(), _name, _major, _minor);
+    }
+}

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/SpecificationPlugin.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/SpecificationPlugin.java?rev=740492&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/SpecificationPlugin.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/SpecificationPlugin.java Tue Feb  3 22:38:45 2009
@@ -0,0 +1,109 @@
+/*
+ * 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.conf;
+
+import org.apache.openjpa.lib.conf.ObjectValue;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * A plug-in for Specification that enforces certain overwriting rules.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class SpecificationPlugin extends ObjectValue {
+    private Log _log;
+    
+    protected static final Localizer _loc = Localizer.forPackage
+        (SpecificationPlugin.class);
+    
+    public SpecificationPlugin(String prop, Log log) {
+        super(prop);
+        _log = log; 
+    }
+    
+    @Override
+    public Class<?> getValueType() {
+        return Specification.class;
+    }
+    
+    /**
+     * Set a value from the given String after validating.
+     * 
+     * @param str can be null to set the Specification to null.
+     * If non-null, then the String must be in Specification format
+     * @see Specification#create(String)  
+     */
+    @Override
+    public void setString(String str) {
+        if (str == null)
+            set(null);
+        else {
+            this.set(Specification.create(str));
+        }
+    }
+    
+    /**
+     * Set a value from the given object after validating.
+     * 
+     * @param obj can be null to set the Specification to null.
+     */
+    @Override
+    public void set(Object obj) {
+        if (obj == null) {
+            super.set(null);
+            return;
+        }
+        if (obj instanceof Specification == false) {
+            throw new UserException(_loc.get("spec-wrong-obj", obj, 
+                obj.getClass())).setFatal(true);
+        }
+        validateOverwrite((Specification)obj);
+        super.set(obj);
+    }
+    
+    /**
+     * Validates if the currently Specification is set.
+     * Given newSpec must be equal to the current Specification and must have
+     * a major version number equal or less than the current one.
+     * 
+     * @exception fatal UserException if newSpec is not equal to the current
+     * Specification or has a higher major version.
+     * 
+     * @see Specification#equals(Object)
+     */
+    protected void validateOverwrite(Specification newSpec) {
+        Specification current = (Specification)get();
+        if (current != null) {
+            if (!current.equals(newSpec)) {
+                throw new UserException(_loc.get("spec-different", newSpec, 
+                    current)).setFatal(true);
+            }
+            if (current.compareVersion(newSpec) < 0) {
+                throw new UserException(_loc.get("spec-version-higher", 
+                    newSpec, current)).setFatal(true);
+            }
+            if (current.compareVersion(newSpec) > 0) {
+                _log.warn(_loc.get("spec-version-lower", newSpec, current));
+            }
+        }
+    }
+}

Modified: openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/conf/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/conf/localizer.properties?rev=740492&r1=740491&r2=740492&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/conf/localizer.properties (original)
+++ openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/conf/localizer.properties Tue Feb  3 22:38:45 2009
@@ -595,3 +595,16 @@
 	find the right marshaller to use to load and store cached data.
 cache-marshaller-not-found: No cache marshaller found for id {0}.
 cache-marshaller-found: Cache marshaller of type {1} found for id {0}.
+spec-different: Attempt to set a different Specification "{0}" failed. The \
+	Specification is already set to "{1}".
+spec-version-higher: Attempt to set a higer Specification "{0}" version failed.\
+	The Specification is already set to "{1}".
+spec-version-lower: Specification "{0}" is set to a lower version than the \
+	current default Specification "{1}".
+spec-wrong-format: "{0}" is not valid Specification. The correct format is \
+	"{1}" where <name> is the name of the Specification, <major> is the \
+	integer major version number and <minor> is a string.
+spec-wrong-version-format: "{0}" is not a valid version for Specification. The \
+	correct version format is "{1}" where <major> is the integer major version \
+	number and <minor> is a string. 	
+spec-wrong-obj: Can not set Specification from "{0}" of "{1}". 
\ No newline at end of file

Added: openjpa/trunk/openjpa-kernel/src/test/java/org/apache/openjpa/conf/TestSpecification.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/test/java/org/apache/openjpa/conf/TestSpecification.java?rev=740492&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/test/java/org/apache/openjpa/conf/TestSpecification.java (added)
+++ openjpa/trunk/openjpa-kernel/src/test/java/org/apache/openjpa/conf/TestSpecification.java Tue Feb  3 22:38:45 2009
@@ -0,0 +1,81 @@
+/*
+ * 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.conf;
+
+
+import junit.framework.TestCase;
+/**
+ * Test basics of Specification object.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class TestSpecification extends TestCase {
+    public void testStaticConstruction() {
+        Specification spec1 = Specification.create("JPA 2.3");
+        assertEquals("JPA", spec1.getName());
+        assertEquals(2, spec1.getMajorVersion());
+        assertEquals("3", spec1.getMinorVersion());
+
+        Specification spec2 = Specification.create("JPA", "1.1");
+        assertEquals("JPA", spec2.getName());
+        assertEquals(1, spec2.getMajorVersion());
+        assertEquals("1", spec2.getMinorVersion());
+        
+        Specification spec3 = Specification.create("JDO", 3, "ED");
+        assertEquals("JDO", spec3.getName());
+        assertEquals(3, spec3.getMajorVersion());
+        assertEquals("ED", spec3.getMinorVersion());
+        
+        Specification spec4 = Specification.create("JDO", 3, 5);
+        assertEquals("JDO", spec4.getName());
+        assertEquals(3, spec4.getMajorVersion());
+        assertEquals("5", spec4.getMinorVersion());
+    }
+    
+    public void testEquality() {
+        Specification spec1 = Specification.create("JPA 2.3");
+        Specification spec2 = Specification.create("JPA 1.0");
+        Specification spec3 = Specification.create("JDO 3.1");
+        
+        assertEquals(spec1, spec2);
+        assertTrue(spec1.equals("jpa"));
+        assertTrue(spec1.equals("JPA"));
+        assertTrue(spec1.equals("JPA "));
+        
+        assertTrue(spec2.equals("jpa"));
+        assertTrue(spec2.equals("JPA"));
+        assertTrue(spec2.equals("JPA "));
+        
+        assertFalse(spec1.equals(spec3));
+    }
+    
+    public void testVersionCompare() {
+        Specification spec1 = Specification.create("JPA 1.1");
+        Specification spec2 = Specification.create("JPA 2.2");
+        assertTrue(spec1.compareVersion(spec2) < 0);
+        assertTrue(spec2.compareVersion(spec1) > 0);
+        assertTrue(spec1.compareVersion(spec1) == 0);
+    }
+    
+    public void testFormat() {
+        assertEquals("<name> [<major>[.<minor>]]", Specification.getFormat());
+        assertEquals("<major>[.<minor>]", Specification.getVersionFormat());
+    }
+}

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=740492&r1=740491&r2=740492&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 Tue Feb  3 22:38:45 2009
@@ -703,6 +703,9 @@
      * Issue a warning that the specified property is not valid.
      */
     private void warnInvalidProperty(String propName) {
+        if (propName != null && propName.startsWith("java.") 
+            || propName.startsWith("sun.")) 
+            return;
         if (!isInvalidProperty(propName))
             return;
         Log log = getConfigurationLog();

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java?rev=740492&r1=740491&r2=740492&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java Tue Feb  3 22:38:45 2009
@@ -23,6 +23,7 @@
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.conf.OpenJPAProductDerivation;
+import org.apache.openjpa.conf.Specification;
 import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
 import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
 import org.apache.openjpa.lib.conf.AbstractProductDerivation;
@@ -67,22 +68,22 @@
             return false;
 
         JDBCConfigurationImpl conf = (JDBCConfigurationImpl) c;
-        String jpa = PersistenceProductDerivation.SPEC_JPA;
-        String ejb = PersistenceProductDerivation.ALIAS_EJB;
+        Specification jpa = PersistenceProductDerivation.SPEC_JPA;
+        Specification ejb = PersistenceProductDerivation.ALIAS_EJB;
 
-        conf.metaFactoryPlugin.setAlias(ejb,
+        conf.metaFactoryPlugin.setAlias(ejb.getName(),
             PersistenceMappingFactory.class.getName());
-        conf.metaFactoryPlugin.setAlias(jpa,
+        conf.metaFactoryPlugin.setAlias(jpa.getName(),
             PersistenceMappingFactory.class.getName());
 
-        conf.mappingFactoryPlugin.setAlias(ejb,
+        conf.mappingFactoryPlugin.setAlias(ejb.getName(),
             PersistenceMappingFactory.class.getName());
-        conf.mappingFactoryPlugin.setAlias(jpa,
+        conf.mappingFactoryPlugin.setAlias(jpa.getName(),
             PersistenceMappingFactory.class.getName());
 
-        conf.mappingDefaultsPlugin.setAlias(ejb,
+        conf.mappingDefaultsPlugin.setAlias(ejb.getName(),
             PersistenceMappingDefaults.class.getName());
-        conf.mappingDefaultsPlugin.setAlias(jpa,
+        conf.mappingDefaultsPlugin.setAlias(jpa.getName(),
             PersistenceMappingDefaults.class.getName());
         return true;
     }
@@ -92,12 +93,12 @@
         if (!(c instanceof JDBCConfigurationImpl))
             return false;
         JDBCConfigurationImpl conf = (JDBCConfigurationImpl) c;
-        String jpa = PersistenceProductDerivation.SPEC_JPA;
-        if (!jpa.equals(conf.getSpecification()))
+        Specification jpa = PersistenceProductDerivation.SPEC_JPA;
+        if (!jpa.equals(conf.getSpecificationInstance()))
             return false;
         
-        conf.mappingDefaultsPlugin.setDefault(jpa);
-        conf.mappingDefaultsPlugin.setString(jpa);
+        conf.mappingDefaultsPlugin.setDefault(jpa.getName());
+        conf.mappingDefaultsPlugin.setString(jpa.getName());
         return true;
     }
 }

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestSpecificationConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestSpecificationConfiguration.java?rev=740492&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestSpecificationConfiguration.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestSpecificationConfiguration.java Tue Feb  3 22:38:45 2009
@@ -0,0 +1,74 @@
+/*
+ * 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.conf;
+
+import javax.persistence.PersistenceException;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests Specification of Configuration.
+ * 
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class TestSpecificationConfiguration extends SingleEMFTestCase {
+    
+    public void testSpecificationIsSet() {
+        Specification spec = getSpecifcation();
+        assertNotNull(spec);
+    }
+    
+    public void testSpecificationIsJPA() {
+        Specification spec = getSpecifcation();
+        assertTrue(spec.equals("JPA"));
+        assertTrue(spec.equals("jpa"));
+    }
+    
+    public void testSpecificationVersionIsJPA2() {
+        Specification spec = getSpecifcation();
+        int major = spec.getMajorVersion();
+        assertEquals(2, major);
+        assertTrue(spec.equals("JPA"));
+    }
+    
+    public void testLowerVersionCanBeSet() {
+        super.setUp("openjpa.Specification", "jpa 1.0", 
+            "openjpa.Log", "DefaultLevel=WARN");
+        Specification spec = getSpecifcation();
+        
+        assertNotNull(spec);
+        assertEquals(1, spec.getMajorVersion());
+    }
+    
+    public void testHigherVersionCanNotBeSet() {
+        try {
+            super.setUp("openjpa.Specification", "jpa 3.0", 
+                "openjpa.Log", "DefaultLevel=WARN");
+            fail("Expected to fail with higher Spec version");
+        } catch (PersistenceException ex) {
+            // good
+        }
+    }
+    
+    public Specification getSpecifcation() {
+        return emf.getConfiguration().getSpecificationInstance();
+    }
+}

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java?rev=740492&r1=740491&r2=740492&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java Tue Feb  3 22:38:45 2009
@@ -113,7 +113,7 @@
         List<Class> types = new ArrayList<Class>();
         boolean prop = false;
         boolean fresh = false;
-        for (int i = 0; i < props.length; i++) {
+        for (int i = 0; props != null && i < props.length; i++) {
             if (props[i] == FRESH_EMF) {
                 fresh = true;
                 continue;
@@ -146,6 +146,8 @@
                 ? ","+map.get("openjpa.MetaDataFactory").toString() : "";
             map.put("openjpa.MetaDataFactory",
                 "jpa(Types=" + buf.toString() + oldValue + ")");
+        } else {
+            map.put("openjpa.MetaDataFactory", "jpa");
         }
         EMFKey key = new EMFKey(pu, map);
         OpenJPAEntityManagerFactorySPI oemf = _emfs.get(key);

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java?rev=740492&r1=740491&r2=740492&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java Tue Feb  3 22:38:45 2009
@@ -37,6 +37,7 @@
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
 import org.apache.openjpa.conf.OpenJPAProductDerivation;
+import org.apache.openjpa.conf.Specification;
 import org.apache.openjpa.lib.conf.AbstractProductDerivation;
 import org.apache.openjpa.lib.conf.Configuration;
 import org.apache.openjpa.lib.conf.ConfigurationProvider;
@@ -70,8 +71,8 @@
     extends AbstractProductDerivation
     implements OpenJPAProductDerivation {
 
-    public static final String SPEC_JPA = "jpa";
-    public static final String ALIAS_EJB = "ejb";
+    public static final Specification SPEC_JPA = Specification.create("jpa", 2);
+    public static final Specification ALIAS_EJB = Specification.create("ejb", 3);
     public static final String RSRC_GLOBAL = "META-INF/openjpa.xml";
     public static final String RSRC_DEFAULT = "META-INF/persistence.xml";
 
@@ -99,9 +100,9 @@
             return false;
         
         OpenJPAConfigurationImpl conf = (OpenJPAConfigurationImpl) c;
-        conf.metaFactoryPlugin.setAlias(ALIAS_EJB,
+        conf.metaFactoryPlugin.setAlias(ALIAS_EJB.getName(),
             PersistenceMetaDataFactory.class.getName());
-        conf.metaFactoryPlugin.setAlias(SPEC_JPA,
+        conf.metaFactoryPlugin.setAlias(SPEC_JPA.getName(),
             PersistenceMetaDataFactory.class.getName());
         
         conf.addValue(new EntityManagerFactoryValue());
@@ -115,8 +116,8 @@
           return false;
  
         OpenJPAConfigurationImpl conf = (OpenJPAConfigurationImpl) c;
-        conf.metaFactoryPlugin.setDefault(SPEC_JPA);
-        conf.metaFactoryPlugin.setString(SPEC_JPA);
+        conf.metaFactoryPlugin.setDefault(SPEC_JPA.getName());
+        conf.metaFactoryPlugin.setString(SPEC_JPA.getName());
         conf.lockManagerPlugin.setDefault("version");
         conf.lockManagerPlugin.setString("version");
         conf.nontransactionalWrite.setDefault("true");