/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.kernel.util;
import com.liferay.portal.kernel.test.rule.CodeCoverageAssertor;
import com.liferay.portal.kernel.util.ObjectGraphUtil.AnnotatedFieldMappingVisitor;
import com.liferay.portal.kernel.util.ObjectGraphUtil.Visitor;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
/**
* @author Shuyang Zhou
*/
public class ObjectGraphUtilTest {
@ClassRule
public static final CodeCoverageAssertor codeCoverageAssertor =
CodeCoverageAssertor.INSTANCE;
@Before
public void setUp() {
_recordVisitor = new RecordVisitor();
_objectValuePairs = _recordVisitor._objectValuePairs;
_recordAnnotatedFieldMappingVisitor =
new RecordAnnotatedFieldMappingVisitor();
_annotatedFieldMappingObjectValuePairs =
_recordAnnotatedFieldMappingVisitor._objectValuePairs;
}
@Test
public void testAnnotatedFieldMappingVisitorHasAnnoation() {
Assert.assertFalse(
_recordAnnotatedFieldMappingVisitor.hasAnnotation(
new Annotation[] {Annotation1.INSTANCE}));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.hasAnnotation(
new Annotation[] {Annotation2.INSTANCE}));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.hasAnnotation(
new Annotation[] {Annotation3.INSTANCE}));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.hasAnnotation(
new Annotation[] {Annotation1.INSTANCE, Annotation2.INSTANCE}));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.hasAnnotation(
new Annotation[] {Annotation2.INSTANCE, Annotation3.INSTANCE}));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.hasAnnotation(
new Annotation[] {Annotation1.INSTANCE, Annotation3.INSTANCE}));
}
@Test
public void testAnnotatedFieldMappingVisitorIsFieldTypeClass() {
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
LinkedType1.class));
Assert.assertFalse(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
LinkedType2.class));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
LinkedType3.class));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
LinkedType1[].class));
Assert.assertFalse(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
LinkedType2[].class));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
LinkedType3[].class));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
LinkedType1[][].class));
Assert.assertFalse(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
LinkedType2[][].class));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
LinkedType3[][].class));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
new LinkedType1() {}.getClass()));
Assert.assertFalse(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
new LinkedType2() {}.getClass()));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isFieldTypeClass(
new LinkedType3() {}.getClass()));
}
@Test
public void testAnnotatedFieldMappingVisitorIsLinkedClass() {
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isLinkedClass(
LinkedType1.class));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isLinkedClass(
LinkedType2.class));
Assert.assertFalse(
_recordAnnotatedFieldMappingVisitor.isLinkedClass(
LinkedType3.class));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isLinkedClass(
new LinkedType1() {}.getClass()));
Assert.assertTrue(
_recordAnnotatedFieldMappingVisitor.isLinkedClass(
new LinkedType2() {}.getClass()));
Assert.assertFalse(
_recordAnnotatedFieldMappingVisitor.isLinkedClass(
new LinkedType3() {}.getClass()));
}
@Test
public void testAnnotatedFieldMappingVisitorMapValue() {
LinkedType1 linkedType1 = new LinkedType1();
Assert.assertSame(
linkedType1,
_recordAnnotatedFieldMappingVisitor.mapValue(null, linkedType1));
Assert.assertEquals(
_annotatedFieldMappingObjectValuePairs.toString(), 1,
_annotatedFieldMappingObjectValuePairs.size());
ObjectValuePair<Field, Object> objectValuePair =
_annotatedFieldMappingObjectValuePairs.get(0);
Assert.assertNull(objectValuePair.getKey());
Assert.assertSame(linkedType1, objectValuePair.getValue());
}
@Test
public void testAnnotatedFieldMappingVisitorMapValueArray() {
LinkedType1[] linkedType1Array = {new LinkedType1(), new LinkedType1()};
LinkedType1[] mappedLinkedType1Array =
(LinkedType1[])
_recordAnnotatedFieldMappingVisitor.mapValue(
null, linkedType1Array);
Assert.assertNotSame(linkedType1Array, mappedLinkedType1Array);
Assert.assertArrayEquals(linkedType1Array, mappedLinkedType1Array);
Assert.assertEquals(
_annotatedFieldMappingObjectValuePairs.toString(), 2,
_annotatedFieldMappingObjectValuePairs.size());
ObjectValuePair<Field, Object> objectValuePair =
_annotatedFieldMappingObjectValuePairs.get(0);
Assert.assertNull(objectValuePair.getKey());
Assert.assertSame(linkedType1Array[0], objectValuePair.getValue());
objectValuePair = _annotatedFieldMappingObjectValuePairs.get(1);
Assert.assertNull(objectValuePair.getKey());
Assert.assertSame(linkedType1Array[1], objectValuePair.getValue());
}
@Test
public void testAnnotatedFieldMappingVisitorNullReference()
throws Exception {
Assert.assertNull(
_recordAnnotatedFieldMappingVisitor.visit(
ReflectionUtil.getDeclaredField(NullReference.class, "_object"),
new NullReference()));
Assert.assertTrue(_annotatedFieldMappingObjectValuePairs.isEmpty());
}
@Test
public void testAnnotatedFieldMappingVisitorStaticField() throws Exception {
Assert.assertNull(
_recordAnnotatedFieldMappingVisitor.visit(
ReflectionUtil.getDeclaredField(StaticField.class, "_INT"),
new StaticField()));
Assert.assertTrue(_annotatedFieldMappingObjectValuePairs.isEmpty());
}
@Test
public void testAnnotatedFieldMappingVisitorVisit() throws Exception {
LinkedType1 linkedType1 = new LinkedType1();
Assert.assertSame(
linkedType1._object1,
_recordAnnotatedFieldMappingVisitor.visit(
ReflectionUtil.getDeclaredField(LinkedType1.class, "_object1"),
linkedType1));
Assert.assertTrue(_annotatedFieldMappingObjectValuePairs.isEmpty());
Assert.assertSame(
linkedType1._object2,
_recordAnnotatedFieldMappingVisitor.visit(
ReflectionUtil.getDeclaredField(LinkedType1.class, "_object2"),
linkedType1));
Assert.assertTrue(_annotatedFieldMappingObjectValuePairs.isEmpty());
Field field = ReflectionUtil.getDeclaredField(
LinkedType1.class, "_linkedType3");
Assert.assertNull(
_recordAnnotatedFieldMappingVisitor.visit(field, linkedType1));
Assert.assertEquals(
_annotatedFieldMappingObjectValuePairs.toString(), 1,
_annotatedFieldMappingObjectValuePairs.size());
ObjectValuePair<Field, Object> objectValuePair =
_annotatedFieldMappingObjectValuePairs.get(0);
Assert.assertEquals(field, objectValuePair.getKey());
Assert.assertSame(linkedType1._linkedType3, objectValuePair.getValue());
}
@Test
public void testConstructor() {
new ObjectGraphUtil();
}
@Test
public void testWalkObjectGraphNullReference() throws Exception {
NullReference nullReference = new NullReference();
ObjectGraphUtil.walkObjectGraph(nullReference, _recordVisitor);
Assert.assertEquals(
_objectValuePairs.toString(), 1, _objectValuePairs.size());
ObjectValuePair<Field, Object> objectValuePair = _objectValuePairs.get(
0);
Assert.assertEquals(
ReflectionUtil.getDeclaredField(NullReference.class, "_object"),
objectValuePair.getKey());
Assert.assertSame(nullReference, objectValuePair.getValue());
}
@Test
public void testWalkObjectGraphNullReferenceWithException() {
final Exception exception = new Exception();
try {
ObjectGraphUtil.walkObjectGraph(
new NullReference(),
new Visitor() {
@Override
public Object visit(Field field, Object target)
throws Exception {
throw exception;
}
});
Assert.fail();
}
catch (Exception e) {
Assert.assertSame(exception, e);
}
}
@Test
public void testWalkObjectGraphObject() {
ObjectGraphUtil.walkObjectGraph(new Object(), _recordVisitor);
Assert.assertTrue(_objectValuePairs.isEmpty());
}
@Test
public void testWalkObjectGraphPrimitive() throws Exception {
Primitive primitive = new Primitive();
ObjectGraphUtil.walkObjectGraph(primitive, _recordVisitor);
Assert.assertEquals(
_objectValuePairs.toString(), 1, _objectValuePairs.size());
ObjectValuePair<Field, Object> objectValuePair = _objectValuePairs.get(
0);
Assert.assertEquals(
ReflectionUtil.getDeclaredField(Primitive.class, "_int"),
objectValuePair.getKey());
Assert.assertSame(primitive, objectValuePair.getValue());
}
@Test
public void testWalkObjectGraphPrimitiveArray() throws Exception {
PrimitiveArray primitiveArray = new PrimitiveArray();
ObjectGraphUtil.walkObjectGraph(primitiveArray, _recordVisitor);
Assert.assertEquals(
_objectValuePairs.toString(), 1, _objectValuePairs.size());
ObjectValuePair<Field, Object> objectValuePair = _objectValuePairs.get(
0);
Assert.assertEquals(
ReflectionUtil.getDeclaredField(PrimitiveArray.class, "_ints"),
objectValuePair.getKey());
Assert.assertSame(primitiveArray, objectValuePair.getValue());
}
@Test
public void testWalkObjectGraphSelfReference() throws Exception {
SelfReference selfReference = new SelfReference();
ObjectGraphUtil.walkObjectGraph(selfReference, _recordVisitor);
Assert.assertEquals(
_objectValuePairs.toString(), 1, _objectValuePairs.size());
ObjectValuePair<Field, Object> objectValuePair = _objectValuePairs.get(
0);
Assert.assertEquals(
ReflectionUtil.getDeclaredField(
SelfReference.class, "_selfReference"),
objectValuePair.getKey());
Assert.assertSame(selfReference, objectValuePair.getValue());
}
@Test
public void testWalkObjectGraphSelfReferenceArray() throws Exception {
SelfReferenceArray selfReferenceArray = new SelfReferenceArray();
ObjectGraphUtil.walkObjectGraph(selfReferenceArray, _recordVisitor);
Assert.assertEquals(
_objectValuePairs.toString(), 1, _objectValuePairs.size());
ObjectValuePair<Field, Object> objectValuePair = _objectValuePairs.get(
0);
Assert.assertEquals(
ReflectionUtil.getDeclaredField(
SelfReferenceArray.class, "_selfReferenceArray"),
objectValuePair.getKey());
Assert.assertSame(selfReferenceArray, objectValuePair.getValue());
}
@Test
public void testWalkObjectGraphStaticField() {
ObjectGraphUtil.walkObjectGraph(new StaticField(), _recordVisitor);
Assert.assertTrue(_objectValuePairs.isEmpty());
}
private List<ObjectValuePair<Field, Object>>
_annotatedFieldMappingObjectValuePairs;
private List<ObjectValuePair<Field, Object>> _objectValuePairs;
private RecordAnnotatedFieldMappingVisitor
_recordAnnotatedFieldMappingVisitor;
private RecordVisitor _recordVisitor;
private static class LinkedType1 {
@Annotation3
private final LinkedType3 _linkedType3 = new LinkedType3();
@Annotation1
private final Object _object1 = new Object();
@Annotation2
private final Object _object2 = new Object();
}
private static class LinkedType2 {
}
private static class LinkedType3 {
}
private static class NullReference {
@SuppressWarnings("unused")
private final Object _object = null;
}
private static class Primitive {
public Primitive() {
_int = 1;
}
@SuppressWarnings("unused")
private final int _int;
}
private static class PrimitiveArray {
@SuppressWarnings("unused")
private final int[] _ints = {1, 2, 3};
}
private static class RecordAnnotatedFieldMappingVisitor
extends AnnotatedFieldMappingVisitor {
@Override
protected Object doMap(Field field, Object value) {
_objectValuePairs.add(
new ObjectValuePair<Field, Object>(field, value));
return value;
}
private RecordAnnotatedFieldMappingVisitor() {
super(
new HashSet<Class<?>>(
Arrays.asList(LinkedType1.class, LinkedType2.class)),
new HashSet<Class<? extends Annotation>>(
Arrays.asList(Annotation2.class, Annotation3.class)),
new HashSet<Class<?>>(
Arrays.asList(LinkedType1.class, LinkedType3.class)));
}
private List<ObjectValuePair<Field, Object>> _objectValuePairs =
new ArrayList<>();
}
private static class RecordVisitor implements Visitor {
@Override
public Object visit(Field field, Object target) throws Exception {
_objectValuePairs.add(
new ObjectValuePair<Field, Object>(field, target));
return field.get(target);
}
private final List<ObjectValuePair<Field, Object>> _objectValuePairs =
new ArrayList<>();
}
private static class SelfReference {
@SuppressWarnings("unused")
private final SelfReference _selfReference = this;
}
private static class SelfReferenceArray {
@SuppressWarnings("unused")
private final SelfReferenceArray[] _selfReferenceArray = {this, null};
}
private static class StaticField {
@SuppressWarnings("unused")
private static final int _INT = 1;
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
private @interface Annotation1 {
public static final Annotation1 INSTANCE = new Annotation1() {
@Override
public Class<? extends Annotation> annotationType() {
return Annotation1.class;
}
};
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
private @interface Annotation2 {
public static final Annotation2 INSTANCE = new Annotation2() {
@Override
public Class<? extends Annotation> annotationType() {
return Annotation2.class;
}
};
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
private @interface Annotation3 {
public static final Annotation3 INSTANCE = new Annotation3() {
@Override
public Class<? extends Annotation> annotationType() {
return Annotation3.class;
}
};
}
}