Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JDO-709] Enable Element.TYPE for @Convert - TCK test #61

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/src/main/java/javax/jdo/annotations/Convert.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
* @since 3.2
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
public @interface Convert {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
import org.apache.jdo.tck.pc.converter.IPCRect;
import org.apache.jdo.tck.pc.converter.PCRect;
import org.apache.jdo.tck.pc.converter.PCRectAnnotated;
import org.apache.jdo.tck.pc.converter.PCRectPointTypeAnnotated;
import org.apache.jdo.tck.pc.mylib.ConvertiblePoint;
import org.apache.jdo.tck.pc.mylib.Point;
import org.apache.jdo.tck.util.BatchTestRunner;
import org.apache.jdo.tck.util.PointToStringConverter;
import org.apache.jdo.tck.util.PointConversionCounter;

/**
* <B>Title:</B>PointAttributeConverterTest <br>
Expand Down Expand Up @@ -59,6 +61,7 @@ public static void main(String[] args) {
protected void localSetUp() {
addTearDownClass(PCRect.class);
addTearDownClass(PCRectAnnotated.class);
addTearDownClass(PCRectPointTypeAnnotated.class);
}

/** Test method creating and storing a PCRectString instance. */
Expand All @@ -78,7 +81,7 @@ public void testModifyPCRectStringInstance() {

/** Test method running a PCRectString query with a query parameter of type Point. */
public void testPCRectStringQueryWithPointParam() {
runQueryWithPointParameter(PCRect.class);
runQueryWithPointParameter(PCRect.class, false);
}

/** Test method running a PCRectString query with a query parameter of type String. */
Expand All @@ -103,32 +106,57 @@ public void testModifyPCRectStringAnnotatedInstance() {

/** Test method running a PCRectStringAnnotated query with a query parameter of type String. */
public void testPCRectStringAnnotatedQueryWithPointParam() {
runQueryWithPointParameter(PCRectAnnotated.class);
runQueryWithPointParameter(PCRectAnnotated.class, false);
}

/** Test method running a PCRectStringAnnotated query with a query parameter of type Point. */
public void testPCRectStringAnnotatedQueryWithStringParam() throws Exception {
runQueryWithStringParameter(PCRectAnnotated.class);
}

/** Test method creating and storing a PCRectStringAnnotated instance. */
public void testStorePCRectPointTypeAnnotatedInstance() {
runStoreIPCRectInstance(PCRectPointTypeAnnotated.class);
}

/** Test method reading a PCRectStringAnnotated instance from the datastore. */
public void testReadPCRectPointTypeAnnotatedInstance() {
runReadIPCRectInstance(PCRectPointTypeAnnotated.class);
}

/** Test method modifying a PCRectStringAnnotated instance and storing in the datastore. */
public void testModifyPCRectPointTypeAnnotatedInstance() {
runModifyIPCRectInstance(PCRectPointTypeAnnotated.class);
}

/** Test method running a PCRectStringAnnotated query with a query parameter of type String. */
public void testPCRectPointTypeAnnotatedQueryWithPointParam() {
runQueryWithPointParameter(PCRectPointTypeAnnotated.class, true);
}

/** Test method running a PCRectStringAnnotated query with a query parameter of type Point. */
public void testPCRectPointTypeAnnotatedQueryWithStringParam() throws Exception {
runQueryWithStringParameter(PCRectPointTypeAnnotated.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();
int nrOfDbCalls = PointConversionCounter.getNrOfConvertToDatastoreCalls();
int nrOfAttrCalls = PointConversionCounter.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);
assertEquals(2, PointConversionCounter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should not be called
assertEquals(0, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
assertEquals(0, PointConversionCounter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
}

/**
Expand All @@ -149,8 +177,8 @@ private <T extends IPCRect> void runReadIPCRectInstance(Class<T> pcrectClass) {
pm.close();
pm = null;

nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
nrOfDbCalls = PointConversionCounter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointConversionCounter.getNrOfConvertToAttributeCalls();
pm = getPM();
pm.currentTransaction().begin();
// Read the IPCRect instance from the datastore, this should call convertToAttribute
Expand All @@ -160,9 +188,9 @@ private <T extends IPCRect> void runReadIPCRectInstance(Class<T> pcrectClass) {
pm.currentTransaction().commit();

// convertToDatastore should not be called
assertEquals(0, PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
assertEquals(0, PointConversionCounter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should be called twice
assertEquals(2, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
assertEquals(2, PointConversionCounter.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());
Expand All @@ -189,8 +217,8 @@ private <T extends IPCRect> void runModifyIPCRectInstance(Class<T> pcrectClass)
pm.close();
pm = null;

nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
nrOfDbCalls = PointConversionCounter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointConversionCounter.getNrOfConvertToAttributeCalls();
pm = getPM();
tx = pm.currentTransaction();
tx.begin();
Expand All @@ -206,9 +234,9 @@ private <T extends IPCRect> void runModifyIPCRectInstance(Class<T> pcrectClass)
tx.commit();

// convertToDatastore should be called twice
assertEquals(2, PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
assertEquals(2, PointConversionCounter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should be called twice
assertEquals(2, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
assertEquals(2, PointConversionCounter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
}

/**
Expand All @@ -217,29 +245,34 @@ private <T extends IPCRect> void runModifyIPCRectInstance(Class<T> pcrectClass)
*
* @throws Exception
*/
private <T extends IPCRect> void runQueryWithPointParameter(Class<T> pcrectClass) {
private <T extends IPCRect> void runQueryWithPointParameter(
Class<T> pcrectClass, boolean useConvertiblePoint) {
int nrOfDbCalls;
int nrOfAttrCalls;

nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
nrOfDbCalls = PointConversionCounter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointConversionCounter.getNrOfConvertToAttributeCalls();
createIPCRectInstances(pcrectClass, 5);
// convertToDatastore should be called twice per instance = 10 times
assertEquals(10, PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
assertEquals(10, PointConversionCounter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should not be called
assertEquals(0, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
assertEquals(0, PointConversionCounter.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();
nrOfDbCalls = PointConversionCounter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointConversionCounter.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));
if (useConvertiblePoint) {
q.setParameters(new ConvertiblePoint(UL_X + 1, UL_Y + 1));
} else {
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();
Expand All @@ -260,9 +293,9 @@ private <T extends IPCRect> void runQueryWithPointParameter(Class<T> pcrectClass
}

// convertToDatastore should be called to handle the query parameter
assertTrue(PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls >= 1);
assertTrue(PointConversionCounter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls >= 1);
// convertToAttribute should be called at least twice
assertTrue(PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls >= 2);
assertTrue(PointConversionCounter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls >= 2);
}

/**
Expand All @@ -276,21 +309,21 @@ private <T extends IPCRect> void runQueryWithStringParameter(Class<T> pcrectClas
int nrOfDbCalls;
int nrOfAttrCalls;

nrOfDbCalls = PointToStringConverter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointToStringConverter.getNrOfConvertToAttributeCalls();
nrOfDbCalls = PointConversionCounter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointConversionCounter.getNrOfConvertToAttributeCalls();
createIPCRectInstances(pcrectClass, 5);
// convertToDatastore should be called twice per instance = 10 times
assertEquals(10, PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
assertEquals(10, PointConversionCounter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls);
// convertToAttribute should not be called
assertEquals(0, PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls);
assertEquals(0, PointConversionCounter.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();
nrOfDbCalls = PointConversionCounter.getNrOfConvertToDatastoreCalls();
nrOfAttrCalls = PointConversionCounter.getNrOfConvertToAttributeCalls();
pm = getPM();
pm.currentTransaction().begin();
try (Query<T> q = pm.newQuery(pcrectClass, "this.upperLeft == str")) {
Expand All @@ -314,9 +347,9 @@ private <T extends IPCRect> void runQueryWithStringParameter(Class<T> pcrectClas
}

// convertToDatastore should not be called
assertTrue(PointToStringConverter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls == 0);
assertTrue(PointConversionCounter.getNrOfConvertToDatastoreCalls() - nrOfDbCalls == 0);
// convertToAttribute should be called at least twice
assertTrue(PointToStringConverter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls >= 2);
assertTrue(PointConversionCounter.getNrOfConvertToAttributeCalls() - nrOfAttrCalls >= 2);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* 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
*
* https://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.converter;

import java.util.Date;
import javax.jdo.annotations.Column;
import javax.jdo.annotations.PersistenceCapable;
import org.apache.jdo.tck.pc.mylib.ConvertiblePoint;
import org.apache.jdo.tck.pc.mylib.Point;

/**
* PersistenceCapable class to test JDO AttributeConverter interface. Its fields of type Point are
* converted to strings in the datastore. The conversion is declared directly on the type
* ConvertiblePoint.
*/
@PersistenceCapable(table = "PCRectConv")
public class PCRectPointTypeAnnotated implements IPCRect {
private static long counter = new Date().getTime();

private static synchronized long newId() {
return counter++;
}

@Column(name = "ID")
private long id = newId();

@Column(name = "UPPER_LEFT")
private ConvertiblePoint upperLeft;

@Column(name = "LOWER_RIGHT")
private ConvertiblePoint lowerRight;

public PCRectPointTypeAnnotated() {}

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public Point getUpperLeft() {
return new Point(upperLeft.getX(), upperLeft.getY());
}

public void setUpperLeft(Point upperLeft) {
this.upperLeft = new ConvertiblePoint(upperLeft.getX(), upperLeft.getY());
}

public Point getLowerRight() {
return new Point(lowerRight.getX(), lowerRight.getY());
}

public void setLowerRight(Point lowerRight) {
this.lowerRight = new ConvertiblePoint(lowerRight.getX(), lowerRight.getY());
}

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 PCRectPointTypeAnnotated's values";
}
return rc;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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
*
* https://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 javax.jdo.annotations.Convert;
import org.apache.jdo.tck.util.ConvertiblePointToStringConverter;

/** A simple point class with two fields. The whole class/type is declared convertible. */
@Convert(value = ConvertiblePointToStringConverter.class)
public class ConvertiblePoint {
public int x;
public Integer y;

public ConvertiblePoint() {}

public ConvertiblePoint(int x, int y) {
this.x = x;
this.y = Integer.valueOf(y);
}

public ConvertiblePoint(int x, Integer y) {
this.x = x;
this.y = y;
}

public String toString() {
String rc = null;
try {
rc = "ConvertiblePoint(" + name() + ")";
} catch (NullPointerException ex) {
rc = "NPE getting ConvertiblePoint's values";
}
return rc;
}

public int getX() {
System.out.println("Hello from ConvertiblePoint.getX");
return x;
}

public Integer getY() {
System.out.println("Hello from ConvertiblePoint.getY");
return y;
}

public String name() {
return "x: " + getX() + ", y: " + getY().intValue();
}
}
Loading