You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-commits@db.apache.org by mb...@apache.org on 2021/05/20 18:55:48 UTC
[db-jdo] branch master updated: Jdo 709 (#20)
This is an automated email from the ASF dual-hosted git repository.
mbo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/db-jdo.git
The following commit(s) were added to refs/heads/master by this push:
new 7913371 Jdo 709 (#20)
7913371 is described below
commit 7913371a10da6e9bc7d33079ace023f0d37897d4
Author: Michael Bouschen <mb...@apache.org>
AuthorDate: Thu May 20 20:55:39 2021 +0200
Jdo 709 (#20)
* JDO-709: First TCK test case for attribute converters
* JDO-709: Added Query Test case
* JDO-709: Renamed PCRect2 to PCRectString, removed debug logging
* JDO-709: Apply suggestions from code review - fixed typos
Co-authored-by: Tobias Bouschen <to...@googlemail.com>
* JDO-709: Apply suggestions from code review - synchronized method and removed code in comment
Co-authored-by: Tobias Bouschen <to...@googlemail.com>
* JDO-709: Apply suggestions from code review - use SingleFieldIdentity for PCRectString class
Co-authored-by: Tilmann <ti...@apache.org>
* JDO-709: Apply suggestions from code review - fixed typo
Co-authored-by: Tobias Bouschen <to...@googlemail.com>
Co-authored-by: Tobias Bouschen <to...@googlemail.com>
* JDO-709: Improved AttributeConverter Test
- Added separate test cases for storing and reading a PCRectString instance
- Added new test case for modifying a PCRectString instance
- AttributeConverter implementation moved from static nested class of PCRectString to util package
- Added helper method to create PCRectString instances to TCK test class
- Removed author tag
* JDO-709: Added query test case using string parameter
* JDO-709: Added PC class using annotations to define the converter class
* JDO-709: update to latest DN
Co-authored-by: Tobias Bouschen <to...@googlemail.com>
Co-authored-by: Tilmann <ti...@apache.org>
---
tck/pom.xml | 20 +-
.../tck/api/converter/AttributeConverterTest.java | 375 +++++++++++++++++++++
.../java/org/apache/jdo/tck/pc/mylib/IPCRect.java | 28 ++
.../org/apache/jdo/tck/pc/mylib/PCRectString.java | 70 ++++
.../jdo/tck/pc/mylib/PCRectStringAnnotated.java | 86 +++++
.../java/org/apache/jdo/tck/pc/mylib/Point.java | 7 +-
.../jdo/tck/util/PointToStringConverter.java | 100 ++++++
tck/src/main/resources/conf/configurations.list | 1 +
tck/src/main/resources/conf/converter.conf | 23 ++
.../org/apache/jdo/tck/pc/mylib/package.jdo | 12 +
.../org/apache/jdo/tck/pc/mylib/package.jdo | 7 +
.../apache/jdo/tck/pc/mylib/package-standard.orm | 6 +
.../apache/jdo/tck/pc/mylib/package-standard.orm | 11 +
.../sql/derby/applicationidentity/schema.sql | 16 +
.../sql/derby/datastoreidentity/schema.sql | 18 +
15 files changed, 760 insertions(+), 20 deletions(-)
diff --git a/tck/pom.xml b/tck/pom.xml
index cb1ca6d..0dfa0e2 100644
--- a/tck/pom.xml
+++ b/tck/pom.xml
@@ -193,17 +193,17 @@
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
- <version>5.2.4</version>
+ <version>5.2.7</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-rdbms</artifactId>
- <version>5.2.4</version>
+ <version>5.2.7</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jdo</artifactId>
- <version>5.2.4</version>
+ <version>5.2.6</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
@@ -213,7 +213,7 @@
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jpa</artifactId>
- <version>5.2.5</version>
+ <version>5.2.6</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
@@ -243,18 +243,6 @@
<version>4.2.2</version>
</dependency>
</dependencies>
- <repositories>
- <repository>
- <releases>
- <enabled>false</enabled>
- </releases>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- <id>DataNucleus Nightly</id>
- <url>http://www.datanucleus.org/downloads/maven2-nightly</url>
- </repository>
- </repositories>
</profile>
</profiles>
diff --git a/tck/src/main/java/org/apache/jdo/tck/api/converter/AttributeConverterTest.java b/tck/src/main/java/org/apache/jdo/tck/api/converter/AttributeConverterTest.java
new file mode 100644
index 0000000..36f1b7b
--- /dev/null
+++ b/tck/src/main/java/org/apache/jdo/tck/api/converter/AttributeConverterTest.java
@@ -0,0 +1,375 @@
+/*
+ * 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.jdo.tck.api.converter;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.mylib.IPCRect;
+import org.apache.jdo.tck.pc.mylib.PCRectString;
+import org.apache.jdo.tck.pc.mylib.PCRectStringAnnotated;
+import org.apache.jdo.tck.pc.mylib.Point;
+import org.apache.jdo.tck.util.BatchTestRunner;
+import org.apache.jdo.tck.util.PointToStringConverter;
+
+import javax.jdo.JDOHelper;
+import javax.jdo.Query;
+import javax.jdo.Transaction;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+/**
+ *<B>Title:</B>AttributeConverterTest
+ *<BR>
+ *<B>Keywords:</B> mapping
+ *<BR>
+ *<B>Assertion ID:</B> [not identified]
+ *<BR>
+ *<B>Assertion Description: </B>
+ * A IPCRect instance refers two Point instances, that are stored as strings in the datastore.
+ * A Point instance is converted using an AttributeConverter.
+ */
+public class AttributeConverterTest extends JDO_Test {
+
+ private static final int UL_X = 1;
+ private static final int UL_Y = 10;
+ private static final int LR_X = 10;
+ private static final int LR_Y = 1;
+
+ /**
+ * The <code>main</code> is called when the class
+ * is directly executed from the command line.
+ * @param args The arguments passed to the program.
+ */
+ public static void main(String[] args) {
+ BatchTestRunner.run(AttributeConverterTest.class);
+ }
+
+ /**
+ * @see org.apache.jdo.tck.JDO_Test#localSetUp()
+ */
+ @Override
+ protected void localSetUp() {
+ addTearDownClass(PCRectString.class);
+ addTearDownClass(PCRectStringAnnotated.class);
+ }
+
+ /**
+ * Test method creating and storing a PCRectString instance.
+ */
+ public void testStorePCRectStringInstance() {
+ runStoreIPCRectInstance(PCRectString.class);
+ }
+
+ /**
+ * Test method reading a PCRectString instance from the datastore.
+ */
+ public void testReadPCRectStringInstance() {
+ runReadIPCRectInstance(PCRectString.class);
+ }
+
+ /**
+ * Test method modifying a PCRectString instance and storing in the datastore.
+ */
+ public void testModifyPCRectStringInstance() {
+ runModifyIPCRectInstance(PCRectString.class);
+ }
+
+ /**
+ * Test method running a PCRectString query with a query parameter of type Point.
+ */
+ public void testPCRectStringQueryWithPointParam() throws Exception {
+ runQueryWithPointParameter(PCRectString.class);
+ }
+
+ /**
+ * Test method running a PCRectString query with a query parameter of type String.
+ */
+ public void testPCRectStringQueryWithStringParam() throws Exception {
+ runQueryWithStringParameter(PCRectString.class);
+ }
+
+ /**
+ * Test method creating and storing a PCRectStringAnnotated instance.
+ */
+ public void testStorePCRectStringAnnotatedInstance() {
+ runStoreIPCRectInstance(PCRectStringAnnotated.class);
+ }
+
+ /**
+ * Test method reading a PCRectStringAnnotated instance from the datastore.
+ */
+ public void testReadPCRectStringAnnotatedInstance() {
+ runReadIPCRectInstance(PCRectStringAnnotated.class);
+ }
+
+ /**
+ * Test method modifying a PCRectStringAnnotated instance and storing in the datastore.
+ */
+ public void testModifyPCRectStringAnnotatedInstance() {
+ runModifyIPCRectInstance(PCRectStringAnnotated.class);
+ }
+
+ /**
+ * Test method running a PCRectStringAnnotated query with a query parameter of type String.
+ */
+ public void testPCRectStringAnnotatedQueryWithPointParam() throws Exception {
+ runQueryWithPointParameter(PCRectStringAnnotated.class);
+ }
+
+ /**
+ * Test method running a PCRectStringAnnotated query with a query parameter of type Point.
+ */
+ public void testPCRectStringAnnotatedQueryWithStringParam() throws Exception {
+ runQueryWithStringParameter(PCRectStringAnnotated.class);
+ }
+
+ // Helper methods
+
+ /**
+ * Helper method creating a IPCRect instance.
+ * It should call AttributeConverter method convertToDatastore.
+ */
+ private <T extends IPCRect> void runStoreIPCRectInstance(Class<T> pcrectClass) {
+ int nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
+ int nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
+
+ // Create a persistent IPCRect instance and store its oid
+ // AttributeConverter method convertToDatastore is called when persisting instance
+ createIPCRectInstances(pcrectClass, 1);
+
+ // convertToDatastore should be called twice
+ assertEquals(2, PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
+ // convertToAttribute should not be called
+ assertEquals(0, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
+ }
+
+ /**
+ * Helper method reading a IPCRect instance from the datastore.
+ * It should call AttributeConverter method convertToAttribute.
+ */
+ private <T extends IPCRect> void runReadIPCRectInstance(Class<T> pcrectClass) {
+ IPCRect rect;
+ Object oid;
+ int nrOfDbCalls;
+ int nrOfAttrCalls;
+
+ // Create a persistent IPCRect instance and store its oid
+ oid = createIPCRectInstances(pcrectClass, 1);
+
+ // Cleanup the 2nd-level cache and close the pm to make sure PCRect instances are not cached
+ pm.getPersistenceManagerFactory().getDataStoreCache().evictAll(false, pcrectClass);
+ pm.close();
+ pm = null;
+
+ nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
+ nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
+ pm = getPM();
+ pm.currentTransaction().begin();
+ // Read the IPCRect instance from the datastore, this should call convertToAttribute
+ rect = (IPCRect)pm.getObjectById(oid);
+ Point ul = rect.getUpperLeft();
+ Point lr = rect.getLowerRight();
+ pm.currentTransaction().commit();
+
+ // convertToDatastore should not be called
+ assertEquals(0, PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
+ // convertToAttribute should be called twice
+ assertEquals(2, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
+ // Check the values of the associated Point instances
+ assertEquals(UL_X, ul.getX());
+ assertEquals(UL_Y, ul.getY() == null ? 0 : ul.getY().intValue());
+ assertEquals(LR_X, lr.getX());
+ assertEquals(LR_Y, lr.getY() == null ? 0 : lr.getY().intValue());
+ }
+
+ /**
+ * Helper method modifying a IPCRect instance.
+ * It should call AttributeConverter method convertToDatastore.
+ */
+ private <T extends IPCRect> void runModifyIPCRectInstance(Class<T> pcrectClass) {
+ Transaction tx;
+ IPCRect rect;
+ Object oid;
+ int nrOfDbCalls;
+ int nrOfAttrCalls;
+
+ // Create a persistent IPCRect instance and store its oid
+ oid = createIPCRectInstances(pcrectClass, 1);
+
+ nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
+ nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
+ pm = getPM();
+ tx = pm.currentTransaction();
+ tx.begin();
+ rect = (IPCRect)pm.getObjectById(oid);
+ // Update IPCRect instance, this should call convertToDatastore
+ rect.setUpperLeft(new Point(UL_X + 1, UL_Y + 1));
+ rect.setLowerRight(new Point(LR_X + 1, LR_Y + 1));
+ // IPCRect instance should be dirty
+ assertTrue(JDOHelper.isDirty(rect));
+ tx.commit();
+
+ // convertToDatastore should be called twice
+ assertEquals(2, PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
+ // convertToAttribute should not be called
+ assertEquals(0, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
+ }
+
+ /**
+ * Helper method running a query with a Point parameter.
+ * The parameter value is converted using the AttributeConverter.
+ * @throws Exception
+ */
+ private <T extends IPCRect> void runQueryWithPointParameter(Class<T> pcrectClass) throws Exception {
+ int nrOfDbCalls;
+ int nrOfAttrCalls;
+
+ nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
+ nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
+ createIPCRectInstances(pcrectClass, 5);
+ // convertToDatastore should be called twice per instance = 10 times
+ assertEquals(10, PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
+ // convertToAttribute should not be called
+ assertEquals(0, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
+
+ // Cleanup the 2nd-level cache and close the pm to make sure PCRect instances are not cached
+ pm.getPersistenceManagerFactory().getDataStoreCache().evictAll(false, pcrectClass);
+ pm.close();
+ pm = null;
+
+ nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
+ nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
+ pm = getPM();
+ pm.currentTransaction().begin();
+ try (Query<T> q = pm.newQuery(pcrectClass, "this.upperLeft == :point")) {
+ q.setParameters(new Point(UL_X + 1, UL_Y + 1));
+ // AttributeConverter method convertToAttribute is called when loading instance from the datastore
+ List<T> res = q.executeList();
+ assertEquals(1, res.size());
+ IPCRect rect = res.get(0);
+ Point ul = rect.getUpperLeft();
+ Point lr = rect.getLowerRight();
+
+ // Check the coordinates of the associated Point instances
+ assertEquals(UL_X+1, ul.getX());
+ assertEquals(UL_Y+1, ul.getY() == null ? 0 : ul.getY().intValue());
+ assertEquals(LR_X+1, lr.getX());
+ assertEquals(LR_Y+1, lr.getY() == null ? 0 : lr.getY().intValue());
+ } catch (Exception e) {
+ fail(e.getMessage());
+ } finally {
+ pm.currentTransaction().commit();
+ }
+
+ // convertToDatastore should be called to handle the query parameter
+ assertTrue(PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls >= 1);
+ // convertToAttribute should be called at least twice
+ assertTrue(PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls >= 2);
+ }
+
+ /**
+ * Helper method running a query with a Point parameter.
+ * The string parameter is compared to the converted Point field.
+ * @throws Exception
+ */
+ private <T extends IPCRect> void runQueryWithStringParameter(Class<T> pcrectClass) throws Exception {
+ int nrOfDbCalls;
+ int nrOfAttrCalls;
+
+ nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
+ nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
+ createIPCRectInstances(pcrectClass,5);
+ // convertToDatastore should be called twice per instance = 10 times
+ assertEquals(10, PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
+ // convertToAttribute should not be called
+ assertEquals(0, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
+
+ // Cleanup the 2nd-level cache and close the pm to make sure PCRect instances are not cached
+ pm.getPersistenceManagerFactory().getDataStoreCache().evictAll(false, pcrectClass);
+ pm.close();
+ pm = null;
+
+ nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
+ nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
+ pm = getPM();
+ pm.currentTransaction().begin();
+ try (Query<T> q = pm.newQuery(pcrectClass, "this.upperLeft == str")) {
+ q.declareParameters("String str");
+ q.setParameters("3:12");
+ // AttributeConverter method convertToAttribute is called when loading instance from the datastore
+ List<T> res = q.executeList();
+ assertEquals(1, res.size());
+ IPCRect rect = res.get(0);
+ Point ul = rect.getUpperLeft();
+ Point lr = rect.getLowerRight();
+
+ // Check the coordinates of the associated Point instances
+ assertEquals(UL_X+2, ul.getX());
+ assertEquals(UL_Y+2, ul.getY() == null ? 0 : ul.getY().intValue());
+ assertEquals(LR_X+2, lr.getX());
+ assertEquals(LR_Y+2, lr.getY() == null ? 0 : lr.getY().intValue());
+ } finally {
+ pm.currentTransaction().commit();
+ }
+
+ // convertToDatastore should not be called
+ assertTrue(PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls == 0);
+ // convertToAttribute should be called at least twice
+ assertTrue(PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls >= 2);
+
+ }
+
+ /**
+ * Helper method to create IPCRect instances.
+ * @param pcrectClass class instance of the IPCRect implementation class to be craeted
+ * @param nrOfObjects number of IPCRect instances to be created
+ * @return ObjectId of the first IPCRect instance
+ */
+ private <T extends IPCRect> Object createIPCRectInstances(Class<T> pcrectClass, int nrOfObjects) {
+ IPCRect rect;
+ Object oid = null;
+
+ if (nrOfObjects < 1) {
+ return null;
+ }
+
+ pm = getPM();
+ try {
+ pm.currentTransaction().begin();
+ rect = pcrectClass.getConstructor().newInstance();
+ rect.setUpperLeft(new Point(UL_X, UL_Y));
+ rect.setLowerRight(new Point(LR_X, LR_Y));
+ pm.makePersistent(rect);
+ oid = pm.getObjectId(rect);
+ for (int i = 1; i < nrOfObjects; i++) {
+ rect = pcrectClass.getConstructor().newInstance();
+ rect.setUpperLeft(new Point(UL_X + i, UL_Y + i));
+ rect.setLowerRight(new Point(LR_X + i, LR_Y + i));
+ pm.makePersistent(rect);
+ }
+ pm.currentTransaction().commit();
+ } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException |
+ IllegalArgumentException | InvocationTargetException ex) {
+ fail("Error creating IPCRect instance: " + ex.getMessage());
+ } finally {
+ if (pm.currentTransaction().isActive()) {
+ pm.currentTransaction().rollback();
+ }
+ }
+ return oid;
+ }
+
+}
diff --git a/tck/src/main/java/org/apache/jdo/tck/pc/mylib/IPCRect.java b/tck/src/main/java/org/apache/jdo/tck/pc/mylib/IPCRect.java
new file mode 100644
index 0000000..a328200
--- /dev/null
+++ b/tck/src/main/java/org/apache/jdo/tck/pc/mylib/IPCRect.java
@@ -0,0 +1,28 @@
+/*
+ * 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.jdo.tck.pc.mylib;
+
+/**
+ * Interface for common methods of implementation classes PCRectString and PCRectStringAnnotated.
+ */
+public interface IPCRect {
+ Point getUpperLeft();
+ void setUpperLeft(Point upperLeft);
+
+ Point getLowerRight();
+ void setLowerRight(Point lowerRight);
+}
diff --git a/tck/src/main/java/org/apache/jdo/tck/pc/mylib/PCRectString.java b/tck/src/main/java/org/apache/jdo/tck/pc/mylib/PCRectString.java
new file mode 100644
index 0000000..958a9e6
--- /dev/null
+++ b/tck/src/main/java/org/apache/jdo/tck/pc/mylib/PCRectString.java
@@ -0,0 +1,70 @@
+/*
+ * 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.jdo.tck.pc.mylib;
+
+import java.util.Date;
+
+/**
+ * PersistenceCapable class to test JDO AttributeConverter interface.
+ * Its fields of type Point are converted to strings in the datastore.
+ */
+public class PCRectString implements IPCRect {
+ private static long counter = new Date().getTime();
+
+ private static synchronized long newId() {
+ return counter++;
+ }
+
+ private long id = newId();
+ private Point upperLeft;
+ private Point lowerRight;
+
+ public PCRectString() {}
+
+ public Point getUpperLeft() {
+ return upperLeft;
+ }
+ public void setUpperLeft(Point upperLeft) {
+ this.upperLeft = upperLeft;
+ }
+
+ public Point getLowerRight() {
+ return lowerRight;
+ }
+ public void setLowerRight(Point lowerRight) {
+ this.lowerRight = lowerRight;
+ }
+ public long getId() {
+ return id;
+ }
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String toString() {
+ String rc = null;
+ Object obj = this;
+ try {
+ rc = obj.getClass().getName()
+ + " ul: " + getUpperLeft().name()
+ + " lr: " + getLowerRight().name();
+ } catch (NullPointerException ex) {
+ rc = "NPE getting PCRectString's values";
+ }
+ return rc;
+ }
+}
diff --git a/tck/src/main/java/org/apache/jdo/tck/pc/mylib/PCRectStringAnnotated.java b/tck/src/main/java/org/apache/jdo/tck/pc/mylib/PCRectStringAnnotated.java
new file mode 100644
index 0000000..ec177c1
--- /dev/null
+++ b/tck/src/main/java/org/apache/jdo/tck/pc/mylib/PCRectStringAnnotated.java
@@ -0,0 +1,86 @@
+/*
+ * 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.jdo.tck.pc.mylib;
+
+import org.apache.jdo.tck.util.PointToStringConverter;
+
+import javax.jdo.annotations.Column;
+import javax.jdo.annotations.Convert;
+import javax.jdo.annotations.PersistenceCapable;
+import javax.jdo.annotations.Persistent;
+import java.util.Date;
+
+/**
+ * PersistenceCapable class to test JDO AttributeConverter interface.
+ * Its fields of type Point are converted to strings in the datastore.
+ */
+@PersistenceCapable(table="PCRectStringAnnotated")
+public class PCRectStringAnnotated implements IPCRect {
+ private static long counter = new Date().getTime();
+
+ private static synchronized long newId() {
+ return counter++;
+ }
+
+ @Column(name="ID")
+ private long id = newId();
+
+ @Persistent
+ @Column(name="UPPER_LEFT")
+ @Convert(value = PointToStringConverter.class)
+ private Point upperLeft;
+
+ @Persistent
+ @Column(name="LOWER_RIGHT")
+ @Convert(value = PointToStringConverter.class)
+ private Point lowerRight;
+
+ public PCRectStringAnnotated() {}
+
+ public Point getUpperLeft() {
+ return upperLeft;
+ }
+ public void setUpperLeft(Point upperLeft) {
+ this.upperLeft = upperLeft;
+ }
+
+ public Point getLowerRight() {
+ return lowerRight;
+ }
+ public void setLowerRight(Point lowerRight) {
+ this.lowerRight = lowerRight;
+ }
+ public long getId() {
+ return id;
+ }
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String toString() {
+ String rc = null;
+ Object obj = this;
+ try {
+ rc = obj.getClass().getName()
+ + " ul: " + getUpperLeft().name()
+ + " lr: " + getLowerRight().name();
+ } catch (NullPointerException ex) {
+ rc = "NPE getting PCRectString's values";
+ }
+ return rc;
+ }
+}
diff --git a/tck/src/main/java/org/apache/jdo/tck/pc/mylib/Point.java b/tck/src/main/java/org/apache/jdo/tck/pc/mylib/Point.java
index 572fba8..a49d71f 100644
--- a/tck/src/main/java/org/apache/jdo/tck/pc/mylib/Point.java
+++ b/tck/src/main/java/org/apache/jdo/tck/pc/mylib/Point.java
@@ -40,10 +40,8 @@ public class Point {
public String toString() {
String rc = null;
- Object obj = this;
try {
- rc = obj.getClass().getName();
- //rc = Util.getClassName(this) + name();
+ rc = "Point(" + name() + ")";
} catch (NullPointerException ex) {
rc = "NPE getting Point's values";
}
@@ -61,6 +59,7 @@ public class Point {
}
public String name() {
- return " x: " + getX() + ", y: " + getY().intValue();
+ return "x: " + getX() + ", y: " + getY().intValue();
}
+
}
diff --git a/tck/src/main/java/org/apache/jdo/tck/util/PointToStringConverter.java b/tck/src/main/java/org/apache/jdo/tck/util/PointToStringConverter.java
new file mode 100644
index 0000000..eeda26f
--- /dev/null
+++ b/tck/src/main/java/org/apache/jdo/tck/util/PointToStringConverter.java
@@ -0,0 +1,100 @@
+/*
+ * 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.jdo.tck.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jdo.tck.pc.mylib.Point;
+
+import javax.jdo.AttributeConverter;
+
+/**
+ * AttributeConverter implementation mapping a Point instance to a string of the form x:y.
+ */
+public class PointToStringConverter implements AttributeConverter<Point, String> {
+
+ private static int nrOfConvertToDatastoreCalls = 0;
+ private static int nrOfConvertToAttributeCalls = 0;
+
+ // Character to separate x and y value of the Point instance.
+ private static final String SEPARATOR = ":";
+
+ private Log logger = LogFactory.getFactory().getInstance("org.apache.jdo.tck");
+
+ /**
+ * Converts the given Point attribute value to its string representation in the datastore.
+ * @param attributeValue the attribute value of type Point to be converted
+ * @return the string representation of the Point instance
+ */
+ @Override
+ public String convertToDatastore(Point attributeValue) {
+ nrOfConvertToDatastoreCalls++;
+ String datastoreValue = null;
+ if (attributeValue != null) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(attributeValue.getX());
+ builder.append(SEPARATOR);
+ builder.append(attributeValue.getY() == null ? Integer.valueOf(0) : attributeValue.getY());
+ datastoreValue = builder.toString();
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("PointToStringConverter.convertToDatastore " +
+ "attributeValue=" + attributeValue + " datastoreValue=" + datastoreValue);
+ }
+ return datastoreValue;
+ }
+
+ /**
+ * Converts the given string datastore value to its representation as a persistent attribute of type Point.
+ * @param datastoreValue the string value in the datastore
+ * @return the attribute value as Point instance
+ */
+ @Override
+ public Point convertToAttribute(String datastoreValue) {
+ nrOfConvertToAttributeCalls++;
+ Point attributeValue = null;
+ if (datastoreValue != null) {
+ String[] parts = datastoreValue.split(SEPARATOR);
+ if (parts.length == 2) {
+ Integer x = Integer.valueOf(parts[0]);
+ Integer y = Integer.valueOf(parts[1]);
+ attributeValue = new Point(x == null ? 0 : x.intValue(), y);
+ }
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("PointToStringConverter.convertToAttribute " +
+ "datastoreValue=" + datastoreValue + " attributeValue=" + attributeValue);
+ }
+ return attributeValue;
+ }
+
+ /**
+ * Method returning the current number of convertToDatastore method calls.
+ * @return number of convertToDatastore method calls
+ */
+ public static int getNrOfConvertToDatastoreCalls() {
+ return nrOfConvertToDatastoreCalls;
+ }
+
+ /**
+ * Method returning the current number of convertToAttribute method calls.
+ * @return number of convertToAttribute method calls
+ */
+ public static int getNrOfConvertToAttributeCalls() {
+ return nrOfConvertToAttributeCalls;
+ }
+}
diff --git a/tck/src/main/resources/conf/configurations.list b/tck/src/main/resources/conf/configurations.list
index ca46d57..9382a72 100644
--- a/tck/src/main/resources/conf/configurations.list
+++ b/tck/src/main/resources/conf/configurations.list
@@ -25,6 +25,7 @@ jdo.tck.cfglist = \
extents.conf \
fetchplan.conf \
fetchgroup.conf \
+ converter.conf \
lifecycle.conf \
models.conf \
models1.conf \
diff --git a/tck/src/main/resources/conf/converter.conf b/tck/src/main/resources/conf/converter.conf
new file mode 100644
index 0000000..921a371
--- /dev/null
+++ b/tck/src/main/resources/conf/converter.conf
@@ -0,0 +1,23 @@
+# 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.
+
+jdo.tck.description = Converter test, standard mapping, no testdata.
+jdo.tck.mapping.companyfactory =
+jdo.tck.testdata =
+jdo.tck.standarddata =
+jdo.tck.mapping = 0
+jdo.tck.requiredOptions =
+jdo.tck.classes = \
+org.apache.jdo.tck.api.converter.AttributeConverterTest
diff --git a/tck/src/main/resources/jdo/applicationidentity/org/apache/jdo/tck/pc/mylib/package.jdo b/tck/src/main/resources/jdo/applicationidentity/org/apache/jdo/tck/pc/mylib/package.jdo
index 0a4e695..2330581 100644
--- a/tck/src/main/resources/jdo/applicationidentity/org/apache/jdo/tck/pc/mylib/package.jdo
+++ b/tck/src/main/resources/jdo/applicationidentity/org/apache/jdo/tck/pc/mylib/package.jdo
@@ -52,6 +52,18 @@
</fetch-group>
</class>
+ <class name="PCRectString"
+ identity-type="application" objectid-class="javax.jdo.identity.LongIdentity">
+ <field name="id" primary-key="true"/>
+ <field name="upperLeft" converter="org.apache.jdo.tck.util.PointToStringConverter"/>
+ <field name="lowerRight" converter="org.apache.jdo.tck.util.PointToStringConverter"/>
+ </class>
+
+ <class name="PCRectStringAnnotated"
+ identity-type="application" objectid-class="javax.jdo.identity.LongIdentity">
+ <field name="id" primary-key="true"/>
+ </class>
+
<class name="PrimitiveTypes"
identity-type="application" objectid-class="org.apache.jdo.tck.pc.mylib.PrimitiveTypes$Oid">
<field name="id" primary-key="true"/>
diff --git a/tck/src/main/resources/jdo/datastoreidentity/org/apache/jdo/tck/pc/mylib/package.jdo b/tck/src/main/resources/jdo/datastoreidentity/org/apache/jdo/tck/pc/mylib/package.jdo
index 99e376f..f5da7db 100644
--- a/tck/src/main/resources/jdo/datastoreidentity/org/apache/jdo/tck/pc/mylib/package.jdo
+++ b/tck/src/main/resources/jdo/datastoreidentity/org/apache/jdo/tck/pc/mylib/package.jdo
@@ -43,6 +43,13 @@
</fetch-group>
</class>
+ <class name="PCRectStringAnnotated" identity-type="datastore"/>
+
+ <class name="PCRectString" identity-type="datastore">
+ <field name="upperLeft" converter="org.apache.jdo.tck.util.PointToStringConverter"/>
+ <field name="lowerRight" converter="org.apache.jdo.tck.util.PointToStringConverter"/>
+ </class>
+
<class name="PrimitiveTypes" identity-type="datastore"/>
</package>
diff --git a/tck/src/main/resources/orm/applicationidentity/org/apache/jdo/tck/pc/mylib/package-standard.orm b/tck/src/main/resources/orm/applicationidentity/org/apache/jdo/tck/pc/mylib/package-standard.orm
index 053bbc7..0a7b45c 100644
--- a/tck/src/main/resources/orm/applicationidentity/org/apache/jdo/tck/pc/mylib/package-standard.orm
+++ b/tck/src/main/resources/orm/applicationidentity/org/apache/jdo/tck/pc/mylib/package-standard.orm
@@ -49,6 +49,12 @@
</field>
</class>
+ <class name="PCRectString" table="PCRectString">
+ <field name="id" column="ID"/>
+ <field name="lowerRight" column="LOWER_RIGHT"/>
+ <field name="upperLeft" column="UPPER_LEFT"/>
+ </class>
+
<class name="PrimitiveTypes" table="PrimitiveTypes">
<field name="id" column="ID"/>
<field name="booleanNotNull" column="booleanNotNull"/>
diff --git a/tck/src/main/resources/orm/datastoreidentity/org/apache/jdo/tck/pc/mylib/package-standard.orm b/tck/src/main/resources/orm/datastoreidentity/org/apache/jdo/tck/pc/mylib/package-standard.orm
index 3ca561e..e7f1ac9 100644
--- a/tck/src/main/resources/orm/datastoreidentity/org/apache/jdo/tck/pc/mylib/package-standard.orm
+++ b/tck/src/main/resources/orm/datastoreidentity/org/apache/jdo/tck/pc/mylib/package-standard.orm
@@ -53,6 +53,17 @@
</field>
</class>
+ <class name="PCRectString" table="PCRectString">
+ <datastore-identity strategy="identity" column="DATASTORE_IDENTITY"/>
+ <field name="id" column="ID"/>
+ <field name="lowerRight" column="LOWER_RIGHT"/>
+ <field name="upperLeft" column="UPPER_LEFT"/>
+ </class>
+
+ <class name="PCRectStringAnnotated">
+ <datastore-identity strategy="identity" column="DATASTORE_IDENTITY"/>
+ </class>
+
<class name="PrimitiveTypes" table="PrimitiveTypes">
<datastore-identity strategy="identity" column="DATASTORE_IDENTITY"/>
<field name="id" column="ID"/>
diff --git a/tck/src/main/resources/sql/derby/applicationidentity/schema.sql b/tck/src/main/resources/sql/derby/applicationidentity/schema.sql
index c68b0f2..4596103 100644
--- a/tck/src/main/resources/sql/derby/applicationidentity/schema.sql
+++ b/tck/src/main/resources/sql/derby/applicationidentity/schema.sql
@@ -61,6 +61,8 @@ CREATE TABLE Item (
-------------------------
DROP TABLE PCRect;
+DROP TABLE PCRectString;
+DROP TABLE PCRectStringAnnotated;
DROP TABLE PCPoint;
DROP TABLE VersionedPCPoint;
DROP TABLE PCPoint2;
@@ -96,6 +98,20 @@ CREATE TABLE PCRect (
CONSTRAINT PCRCT_CONST PRIMARY KEY (ID)
);
+CREATE TABLE PCRectString (
+ ID BIGINT NOT NULL,
+ UPPER_LEFT VARCHAR(30),
+ LOWER_RIGHT VARCHAR(30),
+ CONSTRAINT PCRCTSTR_CONST PRIMARY KEY (ID)
+);
+
+CREATE TABLE PCRectStringAnnotated (
+ ID BIGINT NOT NULL,
+ UPPER_LEFT VARCHAR(30),
+ LOWER_RIGHT VARCHAR(30),
+ CONSTRAINT PCRCTANN_CONST PRIMARY KEY (ID)
+);
+
CREATE TABLE PrimitiveTypes (
ID BIGINT NOT NULL,
booleanNotNull CHAR(1) NOT NULL CHECK (booleanNotNull IN ('Y','N')),
diff --git a/tck/src/main/resources/sql/derby/datastoreidentity/schema.sql b/tck/src/main/resources/sql/derby/datastoreidentity/schema.sql
index dfd4902..7fc3f17 100644
--- a/tck/src/main/resources/sql/derby/datastoreidentity/schema.sql
+++ b/tck/src/main/resources/sql/derby/datastoreidentity/schema.sql
@@ -41,6 +41,8 @@ CREATE TABLE address (
-------------------------
DROP TABLE PCRect;
+DROP TABLE PCRectString;
+DROP TABLE PCRectStringAnnotated;
DROP TABLE PCPoint;
DROP TABLE VersionedPCPoint;
DROP TABLE PCPoint2;
@@ -80,6 +82,22 @@ CREATE TABLE PCRect (
CONSTRAINT PCRCT_CONST PRIMARY KEY (DATASTORE_IDENTITY)
);
+CREATE TABLE PCRectString (
+ DATASTORE_IDENTITY BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+ ID BIGINT,
+ UPPER_LEFT VARCHAR(30),
+ LOWER_RIGHT VARCHAR(30),
+ CONSTRAINT PCRCTSTR_CONST PRIMARY KEY (DATASTORE_IDENTITY)
+);
+
+CREATE TABLE PCRectStringAnnotated (
+ DATASTORE_IDENTITY BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
+ ID BIGINT,
+ UPPER_LEFT VARCHAR(30),
+ LOWER_RIGHT VARCHAR(30),
+ CONSTRAINT PCRCTANN_CONST PRIMARY KEY (DATASTORE_IDENTITY)
+);
+
CREATE TABLE PrimitiveTypes (
DATASTORE_IDENTITY BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY,
ID BIGINT,