blob: 90397af80cbf2edca1153c32963b0e3830d61f48 [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
*
* 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.sis.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.GenericDeclaration;
import static org.apache.sis.util.Classes.*;
// Test dependencies
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import org.apache.sis.test.TestCase;
/*
* Following imports are not used for actual code.
* The are used only as various Class<?> arguments
* given to the methods to test.
*/
import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.HashSet;
import java.util.TreeSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.NavigableSet;
import java.util.RandomAccess;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.InvalidObjectException;
import java.io.NotSerializableException;
import java.io.Serializable;
import java.awt.geom.Point2D;
import javax.print.attribute.standard.PrinterStateReason;
import javax.print.attribute.standard.PrinterStateReasons;
import org.opengis.util.InternationalString;
import org.opengis.metadata.extent.Extent;
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.ReferenceSystem;
import org.opengis.referencing.cs.EllipsoidalCS;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.crs.GeodeticCRS;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.operation.Transformation;
import org.opengis.referencing.operation.CoordinateOperation;
/**
* Tests the {@link Classes} static methods.
*
* @author Martin Desruisseaux (Geomatys)
*/
public final class ClassesTest extends TestCase {
/**
* Creates a new test case.
*/
public ClassesTest() {
}
/**
* Tests {@link Classes#changeArrayDimension(Class, int)}.
*/
@Test
public void testChangeArrayDimension() {
assertEquals(float .class, changeArrayDimension(float .class, 0));
assertEquals(Float .class, changeArrayDimension(Float .class, 0));
assertEquals(float[] .class, changeArrayDimension(float .class, 1));
assertEquals(Float[] .class, changeArrayDimension(Float .class, 1));
assertEquals(float[][].class, changeArrayDimension(float .class, 2));
assertEquals(Float[][].class, changeArrayDimension(Float .class, 2));
assertEquals(float[][].class, changeArrayDimension(float[] .class, 1));
assertEquals(Float[][].class, changeArrayDimension(Float[] .class, 1));
assertEquals(float[] .class, changeArrayDimension(float[][].class, -1));
assertEquals(Float[] .class, changeArrayDimension(Float[][].class, -1));
assertEquals(float .class, changeArrayDimension(float[][].class, -2));
assertEquals(Float .class, changeArrayDimension(Float[][].class, -2));
assertNull ( changeArrayDimension(float[][].class, -3));
assertNull ( changeArrayDimension(Float[][].class, -3));
assertNull ( changeArrayDimension(Void.TYPE, -1));
assertEquals(Void.TYPE, changeArrayDimension(Void.TYPE, 1));
}
/**
* Tests {@link Classes#getAllInterfaces(Class)}.
*/
@Test
@SuppressWarnings("rawtypes")
public void testGetAllInterfaces() {
assertArrayEquals(new Class[] {
GeographicCRS.class,
EllipsoidalCS.class, // Shall be before parent types listed below.
GeodeticCRS.class,
SingleCRS.class,
CoordinateReferenceSystem.class,
ReferenceSystem.class,
IdentifiedObject.class,
CoordinateSystem.class
}, getAllInterfaces(MixedImpl.class));
}
/**
* A dummy class which implements two interfaces having a common parent.
* The intent is to verify that explicitly declared interfaces are listed
* before parent interfaces in {@link #testGetAllInterfaces()}.
*/
private abstract static class MixedImpl implements GeographicCRS, EllipsoidalCS {
}
/**
* Tests {@link Classes#getLeafInterfaces(Class, Class)}.
*/
@Test
public void testGetLeafInterfaces() {
assertArrayEquals(new Class<?>[] {NavigableSet.class},
getLeafInterfaces(TreeSet.class, Collection.class));
assertArrayEquals(new Class<?>[] {GeographicCRS.class},
getLeafInterfaces(T1.class, IdentifiedObject.class));
assertArrayEquals(new Class<?>[] {GeographicCRS.class, CoordinateOperation.class},
getLeafInterfaces(T2.class, IdentifiedObject.class));
assertArrayEquals(new Class<?>[] {Transformation.class, GeographicCRS.class},
getLeafInterfaces(T3.class, IdentifiedObject.class));
}
/**
* Dummy class for {@link #testGetLeafInterfaces()}.
*/
@SuppressWarnings("deprecation")
private abstract static class T1 implements GeographicCRS {
@Override public InternationalString getScope() {return null;}
@Override public Extent getDomainOfValidity() {return null;}
}
@SuppressWarnings("deprecation")
private abstract static class T2 extends T1 implements SingleCRS, CoordinateOperation {}
private abstract static class T3 extends T2 implements Transformation {}
/**
* Tests {@link Classes#getStandardType(Class)}.
*/
@Test
public void testGetStandardType() {
assertEquals(GeographicCRS.class, Classes.getStandardType(T1.class));
assertEquals(SingleCRS.class, Classes.getStandardType(T2.class));
assertEquals(Transformation.class, Classes.getStandardType(T3.class));
assertEquals(String.class, Classes.getStandardType(String.class));
assertEquals(CharSequence.class, Classes.getStandardType(CharSequence.class));
}
/**
* Tests {@link Classes#findCommonClass(Iterable)}
* and {@link Classes#findSpecializedClass(Iterable)}.
*/
@Test
public void testFindCommonParent() {
final Set<Object> types = new HashSet<>();
assertTrue(types.add(new NotSerializableException()));
assertEquals(NotSerializableException.class, findCommonClass (types));
assertEquals(NotSerializableException.class, findSpecializedClass(types));
assertTrue(types.add(new InvalidObjectException(null)));
assertEquals(ObjectStreamException.class, findCommonClass (types));
assertEquals(ObjectStreamException.class, findSpecializedClass(types));
assertTrue(types.add(new FileNotFoundException()));
assertEquals(IOException.class, findCommonClass (types));
assertEquals(IOException.class, findSpecializedClass(types));
assertTrue(types.add(new IOException()));
assertEquals(IOException.class, findCommonClass (types));
assertEquals(IOException.class, findSpecializedClass(types));
assertTrue(types.add(new Exception()));
assertEquals( Exception.class, findCommonClass (types));
assertEquals(IOException.class, findSpecializedClass(types));
}
/**
* Tests {@link Classes#findCommonInterfaces(Class, Class)}.
*/
@Test
public void testFindCommonInterfaces() {
final Set<Class<?>> interfaces = findCommonInterfaces(ArrayList.class, HashSet.class);
assertFalse(interfaces.contains(Set .class));
assertFalse(interfaces.contains(List .class));
assertTrue (interfaces.contains(Collection .class));
assertFalse(interfaces.contains(Iterable .class));
assertFalse(interfaces.contains(RandomAccess.class));
assertTrue (interfaces.contains(Serializable.class));
assertTrue (interfaces.contains(Cloneable .class));
}
/**
* Tests {@link Classes#implementSameInterfaces(Class, Class, Class)}.
*/
@Test
public void testImplementSameInterfaces() {
assertTrue (implementSameInterfaces(StringBuilder.class, String.class, CharSequence.class));
assertTrue (implementSameInterfaces(StringBuilder.class, String.class, Serializable.class));
assertFalse(implementSameInterfaces( File.class, String.class, CharSequence.class));
assertTrue (implementSameInterfaces( File.class, String.class, Serializable.class));
// Tests more convolved cases
assertTrue (implementSameInterfaces(T1.class, T3.class, CoordinateReferenceSystem.class));
assertTrue (implementSameInterfaces(T3.class, T1.class, CoordinateReferenceSystem.class));
assertFalse(implementSameInterfaces(T2.class, T3.class, CoordinateOperation.class));
assertFalse(implementSameInterfaces(T3.class, T2.class, CoordinateOperation.class));
assertFalse(implementSameInterfaces(T3.class, T1.class, CoordinateOperation.class));
}
/**
* Tests the {@link Classes#boundOfParameterizedProperty(Field)} method.
*
* @throws NoSuchFieldException if there is an error in a field name.
*/
@Test
public void testBoundOfParameterizedField() throws NoSuchFieldException {
final Class<Parameterized> c = Parameterized.class;
assertNull( boundOfParameterizedProperty(c.getField("attrib1")));
assertEquals(Long .class, boundOfParameterizedProperty(c.getField("attrib2")));
assertEquals(String.class, boundOfParameterizedProperty(c.getField("attrib3")));
}
/**
* Tests the {@link Classes#boundOfParameterizedProperty(Method)} method.
*
* @throws NoSuchMethodException if there is an error in a method name.
*/
@Test
public void testBoundOfParameterizedProperty() throws NoSuchMethodException {
final Class<?>[] getter = null;
final Class<?>[] setter = new Class<?>[] {Set.class};
final Class<Parameterized> c = Parameterized.class;
assertNull( boundOfParameterizedProperty(c.getMethod("getter0", getter)));
assertNull( boundOfParameterizedProperty(c.getMethod("setter0", setter)));
assertEquals(Integer .class, boundOfParameterizedProperty(c.getMethod("getter1", getter)));
assertEquals(Byte .class, boundOfParameterizedProperty(c.getMethod("getter2", getter)));
assertEquals(Object .class, boundOfParameterizedProperty(c.getMethod("getter3", getter)));
assertEquals(short[] .class, boundOfParameterizedProperty(c.getMethod("getter4", getter)));
assertEquals(Comparable .class, boundOfParameterizedProperty(c.getMethod("getter5", getter)));
assertEquals(Comparable[].class, boundOfParameterizedProperty(c.getMethod("getter6", getter)));
assertEquals(String .class, boundOfParameterizedProperty(c.getMethod("setter1", setter)));
assertEquals(Short .class, boundOfParameterizedProperty(c.getMethod("setter2", setter)));
assertEquals(Object .class, boundOfParameterizedProperty(c.getMethod("setter3", setter)));
assertEquals(PrinterStateReason.class, boundOfParameterizedProperty(c.getMethod("getter7", getter)));
}
/**
* Dummy class for {@link #testBoundOfParameterizedProperty()} usage only.
*/
@SuppressWarnings("rawtypes")
private static final class Parameterized {
public Long attrib1;
public Set<? extends Long> attrib2;
public Map<String,Integer> attrib3;
public Set getter0() {return null;} // Intentionnaly unparameterized.
public Set< Integer> getter1() {return null;}
public Set<? extends Byte> getter2() {return null;}
public Set<? super Float> getter3() {return null;}
public Set< short[]> getter4() {return null;}
public Set<Comparable<?>> getter5() {return null;}
public Set<Comparable<?>[]> getter6() {return null;}
public PrinterStateReasons getter7() {return null;}
public void setter0(Set dummy) {} // Intentionnaly unparameterized.
public void setter1(Set< String> dummy) {}
public void setter2(Set<? extends Short> dummy) {}
public void setter3(Set<? super Double> dummy) {}
}
/**
* Tests the {@link Classes#boundOfParameterizedDeclaration(GenericDeclaration)} method.
*/
@Test
public void testBoundOfParameterizedDeclaration() {
assertNull ( boundOfParameterizedDeclaration(Long.class));
assertEquals(Object.class, boundOfParameterizedDeclaration(List.class));
assertEquals(Object.class, boundOfParameterizedDeclaration(Map.class));
assertEquals(PrinterStateReason.class, boundOfParameterizedDeclaration(PrinterStateReasons.class));
}
/**
* Tests the {@link Classes#getShortName(Class)}, in particular the example values given in the javadoc.
*/
@Test
public void testGetShortName() {
assertEquals("java.lang.String", String.class.getName());
assertEquals("String", String.class.getSimpleName());
assertEquals("java.lang.String", String.class.getCanonicalName());
assertEquals("String", getShortName(String.class));
assertEquals("[D", double[].class.getName());
assertEquals("double[]", double[].class.getSimpleName());
assertEquals("double[]", double[].class.getCanonicalName());
assertEquals("double[]", getShortName(double[].class));
assertEquals("java.awt.geom.Point2D$Double", Point2D.Double.class.getName());
assertEquals("Double", Point2D.Double.class.getSimpleName());
assertEquals("java.awt.geom.Point2D.Double", Point2D.Double.class.getCanonicalName());
assertEquals("Point2D.Double", getShortName(Point2D.Double.class));
final Class<?> anonymous = new Comparable<Object>() {
@Override public int compareTo(final Object o) {
return 0; // Not the purpose of this test.
}
}.getClass();
assertTrue(anonymous.getName().startsWith("org.apache.sis.util.ClassesTest$"));
assertEquals("", anonymous.getSimpleName());
assertEquals(null, anonymous.getCanonicalName());
assertEquals("Object", getShortName(anonymous));
}
}