[maven-release-plugin]  copy for tag 2.1.0

git-svn-id: https://svn.apache.org/repos/asf/openjpa/tags/2.1.0@1071316 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
index a73586d..a3474de 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
@@ -343,8 +343,10 @@
             supportsLockingWithInnerJoin = true;
             supportsLockingWithOuterJoin = true;
             forUpdateClause = "WITH RR USE AND KEEP UPDATE LOCKS";
-            if (maj >=9)
+            
+            if (maj >= 9) {
                 supportsXMLColumn = true;
+            }
         }
 
         // platform specific settings
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InformixDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InformixDictionary.java
index c702811..ebc549e 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InformixDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/InformixDictionary.java
@@ -27,6 +27,8 @@
 import java.sql.Types;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.openjpa.jdbc.identifier.DBIdentifier;
 import org.apache.openjpa.jdbc.identifier.DBIdentifier.DBIdentifierType;
@@ -393,12 +395,60 @@
         // SQL State of IX000 is a general purpose Informix error code
         // category, so only return Boolean.TRUE if we match SQL Codes
         // recoverable = Boolean.FALSE;
-        if ((subtype == StoreException.LOCK && ex.getErrorCode() == -154) 
+        if ((subtype == StoreException.LOCK && checkNestedErrorCodes(ex, "IX000", -154)) 
           ||(subtype == StoreException.QUERY && ex.getErrorCode() == -213)) {
             return false;
         }
         
         return super.isFatalException(subtype, ex);
     }
-}
 
+    /**
+     * Specialized matchErrorState method for Informix.  Informix exceptions are
+     * typically nested multiple levels deep.  Correct determination of the exception type requires
+     * inspection of nested exceptions to determine the root cause. A list of Informix (IDS v10) error codes
+     * can be found here:
+     * 
+     * http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.em.doc/errors_ids100.html
+     * 
+     * @param errorStates classification of SQL error states by their specific nature. The keys of the
+     * map represent one of the constants defined in {@link StoreException}. The value corresponding to
+     * a key represent the set of SQL Error States representing specific category of database error. 
+     * This supplied map is sourced from <code>sql-error-state-codes.xml</xml> and filtered the
+     * error states for the current database.
+     * 
+     * @param ex original SQL Exception as raised by the database driver.
+     * 
+     * @return A constant indicating the category of error as defined in {@link StoreException}.
+     */
+    protected int matchErrorState(Map<Integer,Set<String>> errorStates, SQLException ex) {
+        // Informix SQLState IX000 is a general SQLState that applies to many possible conditions
+        // If the underlying cause is also an IX000 with error code: 
+        // -107 ISAM error: record is locked. || -154 ISAM error: Lock Timeout Expired.
+        // the exception type is LOCK.
+        if (checkNestedErrorCodes(ex, "IX000", -107, -154)) {
+           return StoreException.LOCK;
+        }
+        return super.matchErrorState(errorStates, ex);
+    }
+    
+    private boolean checkNestedErrorCodes(SQLException ex, String sqlState, int...errorCodes) {
+        SQLException cause = ex;
+        int level = 0;
+        // Query at most 5 exceptions deep to prevent infinite iteration exception loops
+        // Typically, the root exception is at level 3.
+        while (cause != null && level < 5) {
+            String errorState = cause.getSQLState();
+            if (sqlState == null || sqlState.equals(errorState)) {
+                for (int ec : errorCodes) {
+                    if (cause.getErrorCode() == ec) {
+                        return true;
+                    }
+                }
+            }
+            cause = cause.getNextException();
+            level++;
+        }
+        return false;
+    }
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
index c92d753..dbe121c 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
@@ -22,13 +22,9 @@
 import java.sql.Clob;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
-import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.sql.Timestamp;
 import java.sql.Types;
-import java.util.Calendar;
-import java.util.Set;
 
 import org.apache.openjpa.jdbc.identifier.DBIdentifier;
 import org.apache.openjpa.jdbc.kernel.JDBCStore;
@@ -95,7 +91,7 @@
                         // MSSQL 2008 supports new date, time and datetime2 types
                         // Use DATETIME2 which has 100ns vs. 3.333msec precision
                         dateTypeName = "DATETIME2";
-                        timeTypeName = "DATETIME";
+                        timeTypeName = "DATETIME2";
                         timestampTypeName = "DATETIME2";
                     }
                 } else {
@@ -262,7 +258,7 @@
     }
 
     private void appendXmlValue(SQLBuffer buf, FilterValue val) {
-        Class rc = Filters.wrap(val.getType());
+        Class<?> rc = Filters.wrap(val.getType());
         int type = getJDBCType(JavaTypes.getTypeCode(rc), false);
         boolean isXmlAttribute = (val.getXmlMapping() == null)
             ? false : val.getXmlMapping().isXmlAttribute();
diff --git a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties
index 59c7316..11d08e5 100644
--- a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties
+++ b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties
@@ -134,7 +134,8 @@
 	its "{1}" primary key field does not use a simple mapping.
 unmapped-datastore-value: Instances of type "{0}" are not valid query \
 	parameters because the type is not mapped.
+cant-set-value: Field "{1}" of "{0}" can not be set to "{2}" value.
 multi-column-version-unsupported:You have specified more than one column for \
 	version data, but the "{1}" version strategy does not support multi-column \
 	versioning.
-not-enum-field: Field "{0}" is expected to be a enum but actually is of type "{1}".
\ No newline at end of file
+not-enum-field: Field "{0}" is expected to be a enum but actually is of type "{1}".
diff --git a/openjpa-persistence-jdbc/pom.xml b/openjpa-persistence-jdbc/pom.xml
index c2d0335..dbcece5 100644
--- a/openjpa-persistence-jdbc/pom.xml
+++ b/openjpa-persistence-jdbc/pom.xml
@@ -615,6 +615,74 @@
             </repositories>
         </profile>
 
+        <!-- Profile for testing Informix with the Informix JDBC Driver -->
+        <profile>
+            <!--
+                Example Informix profile. You can use this profile if you:
+                1) have the Informix JDBC artifacts installed in a local repo and 
+                supply the URL:
+                  -Dids.maven.repo=http://my.local.repo
+                2) have a copy of the Informix driver and run the following
+                commands :
+                    mvn install:install-file -Dfile=${path to ifxjdbc.jar} \
+                                             -DgroupId=com.informix \
+                                             -DartifactId=informix-driver \ 
+                                             -Dversion=3.70 \
+                                             -Dpackaging=jar
+
+                You must also set the following properties:
+                    -Dopenjpa.ids.url=jdbc:informix-sqli://<HOST>:<PORT>:informixserver=<INFORMIXSERVER>;database=<DBNAME>
+                    -Dopenjpa.ids.username=<ids_uid>
+                    -Dopenjpa.ids.password=<ids_pwd>
+
+                Optionally, you can override the default Informix groupId,
+                artifactIds and version by also supplying the following
+                properties:
+                    -Dids.groupid=com.informix
+                    -Dids.driver.artifactid=informix-driver
+                    -Dids.version=3.70
+            -->
+            <id>test-ids-informix</id>
+            <activation>
+                <property>
+                    <name>test-ids-informix</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>${ids.groupid}</groupId>
+                    <artifactId>${ids.driver.artifactid}</artifactId>
+                    <version>${ids.version}</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+            <properties>
+                <ids.maven.repo>http://not.a.real.repository</ids.maven.repo>
+                <ids.groupid>com.informix</ids.groupid>
+                <ids.driver.artifactid>informix-driver</ids.driver.artifactid>
+                <ids.version>3.70</ids.version>
+                <connection.driver.name>com.informix.jdbc.IfxDriver</connection.driver.name>
+                <connection.url>${openjpa.ids.url}</connection.url>
+                <connection.username>${openjpa.ids.username}</connection.username>
+                <connection.password>${openjpa.ids.password}</connection.password>
+            </properties>
+            <repositories>
+                <repository>
+                    <id>ids.repository</id>
+                    <name>Informix Repository</name>
+                    <url>${ids.maven.repo}</url>
+                    <layout>default</layout>
+                    <snapshots>
+                        <enabled>false</enabled>
+                    </snapshots>
+                    <releases>
+                        <enabled>true</enabled>
+                        <checksumPolicy>ignore</checksumPolicy>
+                    </releases>
+                </repository>
+            </repositories>
+        </profile>
+
         <!-- Profile for testing with Oracle DB -->
         <profile>
             <!--
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java
index ea2cba3..cbde67d 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java
@@ -221,6 +221,16 @@
     		buf.append(s).append("\r\n");
     	return buf.toString();
     }
+    
+    /**
+     * Returns the last SQL executed or the empty string if the list is
+     * empty.
+    */ 
+    public String getLastSQL(List<String> list) {
+        if (list != null && list.size() > 0)
+            return list.get(list.size() -1);
+        return "";
+    }
 
     public enum SQLAssertType {
         SQL, NotSQL, ContainsSQL, AllSQLInOrder, AllExactSQLInOrder, 
diff --git a/openjpa-persistence-locking/pom.xml b/openjpa-persistence-locking/pom.xml
index 3fb0d22..67556cb 100644
--- a/openjpa-persistence-locking/pom.xml
+++ b/openjpa-persistence-locking/pom.xml
@@ -594,6 +594,74 @@
             </repositories>
         </profile>
 
+        <!-- Profile for testing Informix with the Informix JDBC Driver -->
+        <profile>
+            <!--
+                Example Informix profile. You can use this profile if you:
+                1) have the Informix JDBC artifacts installed in a local repo and 
+                supply the URL:
+                  -Dids.maven.repo=http://my.local.repo
+                2) have a copy of the Informix driver and run the following
+                commands :
+                    mvn install:install-file -Dfile=${path to ifxjdbc.jar} \
+                                             -DgroupId=com.informix \
+                                             -DartifactId=informix-driver \ 
+                                             -Dversion=3.70 \
+                                             -Dpackaging=jar
+
+                You must also set the following properties:
+                    -Dopenjpa.ids.url=jdbc:informix-sqli://<HOST>:<PORT>:informixserver=<INFORMIXSERVER>;database=<DBNAME>
+                    -Dopenjpa.ids.username=<ids_uid>
+                    -Dopenjpa.ids.password=<ids_pwd>
+
+                Optionally, you can override the default Informix groupId,
+                artifactIds and version by also supplying the following
+                properties:
+                    -Dids.groupid=com.informix
+                    -Dids.driver.artifactid=informix-driver
+                    -Dids.version=3.70
+            -->
+            <id>test-ids-informix</id>
+            <activation>
+                <property>
+                    <name>test-ids-informix</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>${ids.groupid}</groupId>
+                    <artifactId>${ids.driver.artifactid}</artifactId>
+                    <version>${ids.version}</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+            <properties>
+                <ids.maven.repo>http://not.a.real.repository</ids.maven.repo>
+                <ids.groupid>com.informix</ids.groupid>
+                <ids.driver.artifactid>informix-driver</ids.driver.artifactid>
+                <ids.version>3.70</ids.version>
+                <connection.driver.name>com.informix.jdbc.IfxDriver</connection.driver.name>
+                <connection.url>${openjpa.ids.url}</connection.url>
+                <connection.username>${openjpa.ids.username}</connection.username>
+                <connection.password>${openjpa.ids.password}</connection.password>
+            </properties>
+            <repositories>
+                <repository>
+                    <id>ids.repository</id>
+                    <name>Informix Repository</name>
+                    <url>${ids.maven.repo}</url>
+                    <layout>default</layout>
+                    <snapshots>
+                        <enabled>false</enabled>
+                    </snapshots>
+                    <releases>
+                        <enabled>true</enabled>
+                        <checksumPolicy>ignore</checksumPolicy>
+                    </releases>
+                </repository>
+            </repositories>
+        </profile>
+
         <!-- Profile for testing with Oracle DB -->
         <profile>
             <!-- 
diff --git a/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java b/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java
index 061cb3d..9f99cf9 100644
--- a/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java
+++ b/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java
@@ -40,6 +40,7 @@
 import org.apache.openjpa.jdbc.sql.DB2Dictionary;
 import org.apache.openjpa.jdbc.sql.DBDictionary;
 import org.apache.openjpa.jdbc.sql.DerbyDictionary;
+import org.apache.openjpa.jdbc.sql.InformixDictionary;
 import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.persistence.LockTimeoutException;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
@@ -396,14 +397,14 @@
         String firstName1 = (String) q1.getSingleResult();
         //Expected sql for Derby is:
         //SELECT t0.firstName FROM Employee t0 WHERE (t0.id = CAST(? AS BIGINT)) FOR UPDATE WITH RR
-        String SQL1 = toString(sql);
+        String SQL1 = getLastSQL(sql);
         
         // run the second time
         resetSQL();
         Query q2 = em.createQuery(jpql);
         q2.setLockMode(LockModeType.PESSIMISTIC_WRITE);
         String firstName2 = (String) q2.getSingleResult();
-        String SQL2 = toString(sql);
+        String SQL2 = getLastSQL(sql);
         assertEquals(SQL1, SQL2);
         em.getTransaction().commit();
     }
@@ -422,10 +423,18 @@
         // Only run this test on DB2 and Derby for now.  It could cause
         // the test to hang on other platforms.
         if (!(dict instanceof DerbyDictionary ||
-              dict instanceof DB2Dictionary)) {
+              dict instanceof DB2Dictionary ||
+              dict instanceof InformixDictionary)) {
             return;
         }
         
+        // Informix currently requires the lock timeout to be set directly on the dictionary
+        if (dict instanceof InformixDictionary) {
+            InformixDictionary ifxDict = (InformixDictionary)((JDBCConfiguration)emf.getConfiguration()).getDBDictionaryInstance();
+            ifxDict.lockModeEnabled = true;
+            ifxDict.lockWaitSeconds = 5;
+        }
+
         EntityManager em = emf.createEntityManager();
         
         resetSQL();
@@ -459,8 +468,11 @@
             Map<String,Object> props = new HashMap<String,Object>();
             // This property does not have any effect on Derby for the locking
             // condition produced by this test.  Instead, Derby uses the 
-            // lock timeout value specified in the config (pom.xml)
-            props.put("javax.persistence.lock.timeout", 5000);
+            // lock timeout value specified in the config (pom.xml).  On Informix,
+            // the dictionary level timeout (set above) will be used.
+            if (!(dict instanceof InformixDictionary)) {
+                props.put("javax.persistence.lock.timeout", 5000);
+            }
             em.getTransaction().begin();
             getLog().trace("Main: refresh with force increment");
             em.refresh(ve, LockModeType.PESSIMISTIC_FORCE_INCREMENT, props);  
diff --git a/openjpa-project/CHANGES.txt b/openjpa-project/CHANGES.txt
index eac87c9..2bf9feb 100644
--- a/openjpa-project/CHANGES.txt
+++ b/openjpa-project/CHANGES.txt
@@ -245,7 +245,8 @@
     * [OPENJPA-1911] - InvalidStateException is thrown when merge an entity with derived identiy
     * [OPENJPA-1918] - MetaDataRepository.preload() ignores class loader returned by PersistenceUnitInfo.getClassLoader()
     * [OPENJPA-1923] - Allow flexible (non-standard) syntax for collection-valued parameters in IN() expresseion of  JPQL query
-
+    * [OPENJPA-1935] - Informix lock exceptions are not mapped properly by OpenJPA
+    * [OPENJPA-1938] - Typo of time data type in SQLServerdictionary for MSSQL 2008
 
 Improvement
 -----------
diff --git a/openjpa-project/RELEASE-NOTES.html b/openjpa-project/RELEASE-NOTES.html
index 2d94fbe..bb9bb30 100644
--- a/openjpa-project/RELEASE-NOTES.html
+++ b/openjpa-project/RELEASE-NOTES.html
@@ -388,6 +388,10 @@
 </li>
 <li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1923'>OPENJPA-1923</a>] -         Allow flexible (non-standard) syntax for collection-valued parameters in IN() expresseion of  JPQL query
 </li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1935'>OPENJPA-1935</a>] -         Informix lock exceptions are not mapped properly by OpenJPA
+</li>
+<li>[<a href='https://issues.apache.org/jira/browse/OPENJPA-1938'>OPENJPA-1938</a>] -         Typo of time data type in SQLServerdictionary for MSSQL 2008
+</li>
 </ul>
         
 <h2>        Improvement
diff --git a/openjpa-project/src/doc/manual/migration_considerations.xml b/openjpa-project/src/doc/manual/migration_considerations.xml
index 83dcb2a..898c5c1 100644
--- a/openjpa-project/src/doc/manual/migration_considerations.xml
+++ b/openjpa-project/src/doc/manual/migration_considerations.xml
@@ -143,20 +143,20 @@
                     enhancement and at runtime.
                 </para>
             </section>
-            <section id="setParameters">
+            <section id="setParameter">
                 <title>
-                    Query.setParameteres()
+                    Query.setParameter()
                 </title>
                 <!-- See OPENJPA-1213 for details. -->
                 <para>
-                    The Query interface setParameters() method behavior has
-                    changed to throw an IllegalArgumentException if more
-                    parameter substitutions are supplied than defined in the
-                    createQuery() or createNamedQuery() call, as required by
-                    the JPA2 specification.
-                    OpenJPA 1.2.x and prior versions would silently ignore the
-                    supplied parameter substitutions and allow the Query to be
-                    processed.
+                    The Query interface setParameter() method behavior has
+                    changed to throw an IllegalArgumentException (as required 
+                    by the JPA specification) if more parameter substitutions 
+                    are supplied than defined in the createQuery(), 
+                    createNamedQuery(), or createNativeQuery() invocation.
+                    OpenJPA 1.2.x and prior versions silently ignored these
+                    extraneous parameter substitutions and allowed the Query
+                    to be processed.
                 </para>
             </section>
             <section id="serialization">