blob: 2177d9fab01926d07ec36dbf972b7a3637b4b198 [file] [log] [blame]
/*
* 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.
*/
/*
* ObjectIdentityTest.java
*
*/
package javax.jdo.identity;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.security.PrivilegedAction;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Currency;
import java.util.Date;
import java.util.Locale;
import javax.jdo.JDOFatalInternalException;
import javax.jdo.JDONullIdentityException;
import javax.jdo.JDOUserException;
import javax.jdo.LegacyJava;
import javax.jdo.spi.JDOImplHelper;
import org.junit.jupiter.api.Test;
/** */
class ObjectIdentityTest extends SingleFieldIdentityTest {
/** The JDOImplHelper instance used for Date formatting. */
private static final JDOImplHelper helper = doPrivileged(JDOImplHelper::getInstance);
@SuppressWarnings("unchecked")
private static <T> T doPrivileged(PrivilegedAction<T> privilegedAction) {
try {
return (T) LegacyJava.doPrivilegedAction.invoke(null, privilegedAction);
} catch (IllegalAccessException | InvocationTargetException e) {
if (e.getCause() instanceof RuntimeException) {
throw (RuntimeException) e.getCause();
}
throw new JDOFatalInternalException(e.getMessage());
}
}
/** Creates a new instance of ObjectIdentityTest */
public ObjectIdentityTest() {}
@Test
void testConstructor() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
ObjectIdentity c2 = new ObjectIdentity(Object.class, new IdClass(1));
ObjectIdentity c3 = new ObjectIdentity(Object.class, new IdClass(2));
assertEquals(c1, c2, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, c3, "Not equal ObjectIdentity instances compare equal");
}
@Test
void testIntegerConstructor() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, Integer.valueOf(1));
ObjectIdentity c2 = new ObjectIdentity(Object.class, Integer.valueOf(1));
ObjectIdentity c3 = new ObjectIdentity(Object.class, Integer.valueOf(2));
assertEquals(c1, c2, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, c3, "Not equal ObjectIdentity instances compare equal");
}
@Test
void testLongConstructor() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, Long.valueOf(1));
ObjectIdentity c2 = new ObjectIdentity(Object.class, Long.valueOf(1));
ObjectIdentity c3 = new ObjectIdentity(Object.class, Long.valueOf(2));
assertEquals(c1, c2, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, c3, "Not equal ObjectIdentity instances compare equal");
}
@Test
void testDateConstructor() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, new Date(1));
ObjectIdentity c2 = new ObjectIdentity(Object.class, new Date(1));
ObjectIdentity c3 = new ObjectIdentity(Object.class, new Date(2));
assertEquals(c1, c2, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, c3, "Not equal ObjectIdentity instances compare equal");
}
@Test
void testLocaleConstructor() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, Locale.US);
ObjectIdentity c2 = new ObjectIdentity(Object.class, Locale.US);
ObjectIdentity c3 = new ObjectIdentity(Object.class, Locale.GERMANY);
assertEquals(c1, c2, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, c3, "Not equal ObjectIdentity instances compare equal");
}
@Test
void testCurrencyConstructor() {
if (!isClassLoadable("java.util.Currency")) return;
ObjectIdentity c1 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.US));
ObjectIdentity c2 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.US));
ObjectIdentity c3 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.GERMANY));
assertEquals(c1, c2, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, c3, "Not equal ObjectIdentity instances compare equal");
}
@Test
void testStringConstructor() {
ObjectIdentity c1 =
new ObjectIdentity(Object.class, "javax.jdo.identity.ObjectIdentityTest$IdClass:1");
ObjectIdentity c2 =
new ObjectIdentity(Object.class, "javax.jdo.identity.ObjectIdentityTest$IdClass:1");
ObjectIdentity c3 =
new ObjectIdentity(Object.class, "javax.jdo.identity.ObjectIdentityTest$IdClass:2");
assertEquals(c1, c2, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, c3, "Not equal ObjectIdentity instances compare equal");
}
@Test
void testToStringConstructor() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
ObjectIdentity c2 = new ObjectIdentity(Object.class, c1.toString());
assertEquals(c1, c2, "Equal ObjectIdentity instances compare not equal.");
}
@Test
void testDateCompareTo() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, new Date(1));
ObjectIdentity c2 = new ObjectIdentity(Object.class, new Date(1));
ObjectIdentity c3 = new ObjectIdentity(Object.class, new Date(2));
ObjectIdentity c4 = new ObjectIdentity(Class.class, new Date(1));
assertEquals(0, c1.compareTo(c2), "Equal ObjectIdentity instances compare not equal.");
assertTrue(
c1.compareTo(c3) < 0, "Not equal ObjectIdentity instances have wrong compareTo result");
assertTrue(
c3.compareTo(c1) > 0, "Not equal ObjectIdentity instances have wrong compareTo result");
assertTrue(
c1.compareTo(c4) > 0, "Not equal ObjectIdentity instances have wrong compareTo result");
}
@Test
void testBadStringConstructorNullClass() {
assertThrows(
NullPointerException.class,
() -> new ObjectIdentity(null, "1"),
"Failed to catch expected exception.");
}
@Test
void testBadStringConstructorNullParam() {
assertThrows(
JDONullIdentityException.class,
() -> new ObjectIdentity(Object.class, null),
"Failed to catch expected exception.");
}
@Test
void testBadStringConstructorTooShort() {
assertThrows(
JDOUserException.class,
() -> new ObjectIdentity(Object.class, "xx"),
"Failed to catch expected exception.");
}
@Test
void testBadStringConstructorNoDelimiter() {
assertThrows(
JDOUserException.class,
() -> new ObjectIdentity(Object.class, "xxxxxxxxx"),
"Failed to catch expected exception.");
}
@Test
void testBadStringConstructorBadClassName() {
JDOUserException ex =
assertThrows(
JDOUserException.class,
() -> new ObjectIdentity(Object.class, "xx:yy"),
"Failed to catch expected ClassNotFoundException.");
validateNestedException(ex, ClassNotFoundException.class);
}
@Test
void testBadStringConstructorNoStringConstructor() {
JDOUserException ex =
assertThrows(
JDOUserException.class,
() ->
new ObjectIdentity(
Object.class,
"javax.jdo.identity.ObjectIdentityTest$BadIdClassNoStringConstructor:yy"),
"Failed to catch expected NoSuchMethodException.");
validateNestedException(ex, NoSuchMethodException.class);
}
@Test
void testBadStringConstructorNoPublicStringConstructor() {
JDOUserException ex =
assertThrows(
JDOUserException.class,
() ->
new ObjectIdentity(
Object.class,
"javax.jdo.identity.ObjectIdentityTest$BadIdClassNoPublicStringConstructor:yy"),
"Failed to catch expected NoSuchMethodException.");
validateNestedException(ex, NoSuchMethodException.class);
}
@Test
void testBadStringConstructorIllegalArgument() {
JDOUserException ex =
assertThrows(
JDOUserException.class,
() ->
new ObjectIdentity(
Object.class, "javax.jdo.identity.ObjectIdentityTest$IdClass:yy"),
"Failed to catch expected InvocationTargetException.");
validateNestedException(ex, InvocationTargetException.class);
}
@Test
void testStringDateConstructor() {
SimpleDateFormat usDateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a", Locale.US);
helper.registerDateFormat(usDateFormat);
// construct date instance for 1.1.1970 00:00:00
Calendar cal = Calendar.getInstance(Locale.US);
cal.clear();
cal.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
Date date = cal.getTime();
ObjectIdentity c1 = new ObjectIdentity(Object.class, "java.util.Date:Jan 01, 1970 00:00:00 AM");
ObjectIdentity c2 = new ObjectIdentity(Object.class, date);
assertEquals(0, c1.compareTo(c2), "Equal ObjectIdentity instances compare not equal.");
helper.registerDateFormat(DateFormat.getDateTimeInstance());
}
@Test
void testStringDefaultDateConstructor() {
DateFormat dateFormat = DateFormat.getDateTimeInstance();
Calendar cal = Calendar.getInstance();
// nullify millisecond field since dateFormat does not take milliseconds into account
cal.clear(Calendar.MILLISECOND);
Date date = cal.getTime();
String dateAsString = dateFormat.format(date);
ObjectIdentity c1 = new ObjectIdentity(Object.class, "java.util.Date:" + dateAsString);
ObjectIdentity c2 = new ObjectIdentity(Object.class, date);
assertEquals(0, c1.compareTo(c2), "Equal ObjectIdentity instances compare not equal.");
}
@Test
void testBadStringDateConstructor() {
assertThrows(
JDOUserException.class,
() -> new ObjectIdentity(Object.class, "java.util.Date:Jop 1, 1970 00:00:00"),
"Failed to catch expected Exception.");
}
@Test
void testStringLocaleConstructorLanguage() {
if (!isClassLoadable("java.util.Currency")) return;
SingleFieldIdentity<ObjectIdentity> c1 =
new ObjectIdentity(Object.class, "java.util.Locale:en");
assertEquals(new Locale("en"), c1.getKeyAsObject());
}
@Test
void testStringLocaleConstructorCountry() {
SingleFieldIdentity<ObjectIdentity> c1 =
new ObjectIdentity(Object.class, "java.util.Locale:_US");
assertEquals(new Locale("", "US"), c1.getKeyAsObject());
}
@Test
void testStringLocaleConstructorLanguageCountry() {
SingleFieldIdentity<ObjectIdentity> c1 =
new ObjectIdentity(Object.class, "java.util.Locale:en_US");
assertEquals(new Locale("en", "US"), c1.getKeyAsObject());
}
@Test
void testStringLocaleConstructorLanguageCountryVariant() {
SingleFieldIdentity<ObjectIdentity> c1 =
new ObjectIdentity(Object.class, "java.util.Locale:en_US_MAC");
assertEquals(new Locale("en", "US", "MAC"), c1.getKeyAsObject());
}
@Test
void testStringCurrencyConstructor() {
if (!isClassLoadable("java.util.Currency")) return;
ObjectIdentity c1 = new ObjectIdentity(Object.class, "java.util.Currency:USD");
assertEquals(Currency.getInstance("USD"), c1.getKeyAsObject(), "Expected USD currency");
}
@Test
void testBadStringCurrencyConstructor() {
if (!isClassLoadable("java.util.Currency")) return;
JDOUserException ex =
assertThrows(
JDOUserException.class,
() -> new ObjectIdentity(Object.class, "java.util.Currency:NowhereInTheWorld"),
"Failed to catch expected IllegalArgumentException.");
validateNestedException(ex, IllegalArgumentException.class);
}
@Test
void testSerializedIdClass() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
ObjectIdentity c2 = new ObjectIdentity(Object.class, new IdClass(1));
ObjectIdentity c3 = new ObjectIdentity(Object.class, new IdClass(2));
Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
Object sc1 = scis[0];
Object sc2 = scis[1];
Object sc3 = scis[2];
assertEquals(c1, sc1, "Equal ObjectIdentity instances compare not equal.");
assertEquals(c2, sc2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc1, c2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc2, c1, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, c3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc3, sc1, "Not equal ObjectIdentity instances compare equal.");
}
@Test
void testSerializedBigDecimal() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, new BigDecimal("123456789.012"));
ObjectIdentity c2 = new ObjectIdentity(Object.class, new BigDecimal("123456789.012"));
ObjectIdentity c3 = new ObjectIdentity(Object.class, new BigDecimal("123456789.01"));
Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
Object sc1 = scis[0];
Object sc2 = scis[1];
Object sc3 = scis[2];
assertEquals(c1, sc1, "Equal ObjectIdentity instances compare not equal.");
assertEquals(c2, sc2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc1, c2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc2, c1, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, c3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc3, sc1, "Not equal ObjectIdentity instances compare equal.");
}
@Test
void testSerializedCurrency() {
if (!isClassLoadable("java.util.Currency")) return;
ObjectIdentity c1 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.US));
ObjectIdentity c2 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.US));
ObjectIdentity c3 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.GERMANY));
Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
Object sc1 = scis[0];
Object sc2 = scis[1];
Object sc3 = scis[2];
assertEquals(c1, sc1, "Equal ObjectIdentity instances compare not equal.");
assertEquals(c2, sc2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc1, c2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc2, c1, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, c3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc3, sc1, "Not equal ObjectIdentity instances compare equal.");
}
@Test
void testSerializedDate() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, new Date(1));
ObjectIdentity c2 = new ObjectIdentity(Object.class, "java.util.Date:1");
ObjectIdentity c3 = new ObjectIdentity(Object.class, new Date(2));
Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
Object sc1 = scis[0];
Object sc2 = scis[1];
Object sc3 = scis[2];
assertEquals(c1, sc1, "Equal ObjectIdentity instances compare not equal.");
assertEquals(c2, sc2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc1, c2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc2, c1, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, c3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc3, sc1, "Not equal ObjectIdentity instances compare equal.");
}
@Test
void testSerializedLocale() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, Locale.US);
ObjectIdentity c2 = new ObjectIdentity(Object.class, Locale.US);
ObjectIdentity c3 = new ObjectIdentity(Object.class, Locale.GERMANY);
Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
Object sc1 = scis[0];
Object sc2 = scis[1];
Object sc3 = scis[2];
assertEquals(c1, sc1, "Equal ObjectIdentity instances compare not equal.");
assertEquals(c2, sc2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc1, c2, "Equal ObjectIdentity instances compare not equal.");
assertEquals(sc2, c1, "Equal ObjectIdentity instances compare not equal.");
assertNotEquals(c1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, c3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc1, sc3, "Not equal ObjectIdentity instances compare equal.");
assertNotEquals(sc3, sc1, "Not equal ObjectIdentity instances compare equal.");
}
@Test
void testGetKeyAsObject() {
ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
assertEquals(c1.getKeyAsObject(), new IdClass(1), "keyAsObject doesn't match.");
}
private <T> void validateNestedException(JDOUserException ex, Class<T> expected) {
Throwable[] nesteds = ex.getNestedExceptions();
if (nesteds == null || nesteds.length != 1) {
fail("Nested exception is null or length 0");
}
Throwable nested = nesteds[0];
if (nested != ex.getCause()) {
fail("Nested exception is not == getCause()");
}
if (!(expected.isAssignableFrom(nested.getClass()))) {
fail("Wrong nested exception. Expected " + expected.getName() + ", got " + nested.toString());
}
return;
}
public static class IdClass implements Serializable {
private static final long serialVersionUID = 5718122068872969580L;
public final int value;
public IdClass() {
value = 0;
}
public IdClass(int value) {
this.value = value;
}
public IdClass(String str) {
this.value = Integer.parseInt(str);
}
public String toString() {
return Integer.toString(value);
}
public int hashCode() {
return value;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else {
IdClass other = (IdClass) obj;
return value == other.value;
}
}
}
public static class BadIdClassNoStringConstructor {}
public static class BadIdClassNoPublicStringConstructor {
private BadIdClassNoPublicStringConstructor(String str) {}
}
}