Search in sources :

Example 6 with UML

use of org.opengis.annotation.UML in project sis by apache.

the class ReferencingUtilities method toPropertyName.

/**
 * Returns the XML property name of the given interface.
 *
 * For {@link CoordinateSystem} base type, the returned value shall be one of
 * {@code affineCS}, {@code cartesianCS}, {@code cylindricalCS}, {@code ellipsoidalCS}, {@code linearCS},
 * {@code parametricCS}, {@code polarCS}, {@code sphericalCS}, {@code timeCS} or {@code verticalCS}.
 *
 * @param  base  the abstract base interface.
 * @param  type  the interface or classes for which to get the XML property name.
 * @return the XML property name for the given class or interface, or {@code null} if none.
 *
 * @see WKTUtilities#toType(Class, Class)
 */
public static StringBuilder toPropertyName(final Class<?> base, final Class<?> type) {
    final UML uml = type.getAnnotation(UML.class);
    if (uml != null) {
        final Specification spec = uml.specification();
        if (spec == Specification.ISO_19111) {
            final String name = uml.identifier();
            final int length = name.length();
            final StringBuilder buffer = new StringBuilder(length).append(name, name.indexOf('_') + 1, length);
            if (buffer.length() != 0) {
                buffer.setCharAt(0, Character.toLowerCase(buffer.charAt(0)));
                return buffer;
            }
        }
    }
    for (final Class<?> c : type.getInterfaces()) {
        if (base.isAssignableFrom(c)) {
            final StringBuilder name = toPropertyName(base, c);
            if (name != null) {
                return name;
            }
        }
    }
    return null;
}
Also used : UML(org.opengis.annotation.UML) Specification(org.opengis.annotation.Specification)

Example 7 with UML

use of org.opengis.annotation.UML in project sis by apache.

the class MetadataSource method getTableName.

/**
 * Returns the table name for the specified class. This is usually the ISO 19115 name,
 * but we fallback on the simple class name if the ISO name is not available.
 * The package prefix is omitted (e.g. {@code "CI_"} in {@code "CI_Citation"}
 * since newer ISO standards tend to drop it.
 */
static String getTableName(final Class<?> type) {
    final UML annotation = type.getAnnotation(UML.class);
    if (annotation == null) {
        return type.getSimpleName();
    }
    final String name = annotation.identifier();
    int s = name.lastIndexOf('.') + 1;
    /*
         * Drop package prefix if present (e.g. "CI_" in "CI_Citation").
         */
    if (name.length() > s + 3 && name.charAt(s + 2) == '_' && Character.isUpperCase(name.charAt(1))) {
        s += 3;
    }
    return name.substring(s);
}
Also used : UML(org.opengis.annotation.UML)

Example 8 with UML

use of org.opengis.annotation.UML in project sis by apache.

the class AnnotationConsistencyCheck method testMethodAnnotations.

/**
 * Tests the annotations on every methods of SIS classes.
 * More specifically this method tests that:
 *
 * <ul>
 *   <li>The name declared in {@link XmlElement} matches the UML identifier.</li>
 *   <li>The {@code XmlElement.required()} boolean is consistent with the UML {@linkplain Obligation obligation}.</li>
 *   <li>The namespace declared in {@code XmlElement} is not redundant with the one declared in the package.</li>
 * </ul>
 */
@Test
@DependsOnMethod("testImplementationAnnotations")
public void testMethodAnnotations() {
    for (final Class<?> type : types) {
        if (CodeList.class.isAssignableFrom(type)) {
            // Skip code lists, since they are not the purpose of this test.
            continue;
        }
        testingMethod = null;
        testingClass = type.getCanonicalName();
        final Class<?> impl = getImplementation(type);
        if (impl == null) {
            /*
                 * Implementation existence are tested by 'testImplementationAnnotations()'.
                 * It is not the purpose of this test to verify again their existence.
                 */
            continue;
        }
        testingClass = impl.getCanonicalName();
        for (final Method method : type.getDeclaredMethods()) {
            if (!isPublic(method) || isIgnored(method)) {
                continue;
            }
            testingMethod = method.getName();
            final UML uml = method.getAnnotation(UML.class);
            XmlElement element;
            try {
                element = impl.getMethod(testingMethod).getAnnotation(XmlElement.class);
            } catch (NoSuchMethodException e) {
                fail(e.toString());
                continue;
            }
            if (element == null) {
                if (uml == null) {
                    continue;
                }
                /*
                     * If the method does not have a @XmlElement annotation, search for a private method having the
                     * @XmlElement annotation with expected name. This situation happens when metadata object needs
                     * to perform some extra step at XML marshalling time only (not when using directly the API),
                     * for example verifying whether we are marshalling ISO 19139:2007 or ISO 19115-3:2016.
                     */
                boolean wasPublic = false;
                final String identifier = firstIdentifier(uml);
                for (final Method pm : impl.getDeclaredMethods()) {
                    final XmlElement e = pm.getAnnotation(XmlElement.class);
                    if (e != null && identifier.equals(e.name())) {
                        final boolean isPublic = isPublic(pm);
                        if (element != null) {
                            // Give precedence to private methods.
                            if (isPublic & !wasPublic)
                                continue;
                            if (isPublic == wasPublic) {
                                fail("Duplicated @XmlElement for \"" + identifier + "\".");
                            }
                        }
                        wasPublic = isPublic;
                        element = e;
                    }
                }
                /*
                     * In a few case the annotation is not on a getter method, but directly on the field.
                     * The main case is the "pass" field in DefaultConformanceResult.
                     */
                if (element == null)
                    try {
                        element = impl.getDeclaredField(identifier).getAnnotation(XmlElement.class);
                        assertNotNull("Missing @XmlElement annotation.", element);
                    } catch (NoSuchFieldException e) {
                        fail("Missing @XmlElement annotation.");
                        // As a metter of principle (should never reach this point).
                        continue;
                    }
            }
            /*
                 * The UML annotation is mandatory in the default implementation of the
                 * 'testInterfaceAnnotations()' method, but we don't require the UML to
                 * be non-null here since this is not the job of this test method. This
                 * is because subclasses may choose to override the above test method.
                 */
            if (uml != null) {
                assertEquals("Wrong @XmlElement.name().", getExpectedXmlElementName(type, uml), element.name());
            // More tests on development branch (removed on trunk because test depends on GeoAPI 3.1)
            }
            /*
                 * Check that the namespace is the expected one (according subclass)
                 * and is not redundant with the package @XmlSchema annotation.
                 */
            assertExpectedNamespace(element.namespace(), impl, uml);
        }
    }
}
Also used : UML(org.opengis.annotation.UML) XmlElement(javax.xml.bind.annotation.XmlElement) Method(java.lang.reflect.Method) DependsOnMethod(org.apache.sis.test.DependsOnMethod) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 9 with UML

use of org.opengis.annotation.UML in project sis by apache.

the class AnnotationConsistencyCheck method testInterfaceAnnotations.

/**
 * Tests the annotations on every GeoAPI interfaces and code lists in the {@link #types} array.
 * More specifically this method tests that:
 *
 * <ul>
 *   <li>All elements in {@link #types} except code lists are interfaces.</li>
 *   <li>All elements in {@code types} have a {@link UML} annotation.</li>
 *   <li>All methods except deprecated methods and methods overriding JDK methods
 *       have a {@link UML} annotation.</li>
 * </ul>
 */
@Test
public void testInterfaceAnnotations() {
    for (final Class<?> type : types) {
        testingMethod = null;
        testingClass = type.getCanonicalName();
        UML uml = type.getAnnotation(UML.class);
        assertNotNull("Missing @UML annotation.", uml);
        if (!CodeList.class.isAssignableFrom(type)) {
            for (final Method method : type.getDeclaredMethods()) {
                if (isPublic(method)) {
                    testingMethod = method.getName();
                    if (!isIgnored(method)) {
                        uml = method.getAnnotation(UML.class);
                        if (!method.isAnnotationPresent(Deprecated.class)) {
                            assertNotNull("Missing @UML annotation.", uml);
                        }
                    }
                }
            }
        }
    }
}
Also used : CodeList(org.opengis.util.CodeList) UML(org.opengis.annotation.UML) Method(java.lang.reflect.Method) DependsOnMethod(org.apache.sis.test.DependsOnMethod) Test(org.junit.Test)

Example 10 with UML

use of org.opengis.annotation.UML in project sis by apache.

the class PropertyComparator method compare.

/**
 * Compares the given methods for order.
 */
@Override
public int compare(final Method m1, final Method m2) {
    final boolean deprecated = isDeprecated(implementation, m1);
    if (deprecated != isDeprecated(implementation, m2)) {
        return deprecated ? +1 : -1;
    }
    // indexOf(…) are sorted in descending order.
    int c = indexOf(m2) - indexOf(m1);
    if (c == 0) {
        final UML a1 = m1.getAnnotation(UML.class);
        final UML a2 = m2.getAnnotation(UML.class);
        if (a1 != null) {
            // Sort annotated elements first.
            if (a2 == null)
                return +1;
            // Mandatory elements must be first.
            c = order(a1) - order(a2);
            if (c == 0) {
                // Fallback on alphabetical order.
                c = a1.identifier().compareToIgnoreCase(a2.identifier());
            }
            return c;
        } else if (a2 != null) {
            // Sort annotated elements first.
            return -1;
        }
        // Fallback on alphabetical order.
        c = m1.getName().compareToIgnoreCase(m2.getName());
    }
    return c;
}
Also used : UML(org.opengis.annotation.UML)

Aggregations

UML (org.opengis.annotation.UML)10 Method (java.lang.reflect.Method)4 DependsOnMethod (org.apache.sis.test.DependsOnMethod)4 Test (org.junit.Test)4 XmlElement (javax.xml.bind.annotation.XmlElement)3 CodeList (org.opengis.util.CodeList)2 Field (java.lang.reflect.Field)1 HashMap (java.util.HashMap)1 XmlRootElement (javax.xml.bind.annotation.XmlRootElement)1 XmlType (javax.xml.bind.annotation.XmlType)1 XmlJavaTypeAdapter (javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter)1 PropertyComparator (org.apache.sis.metadata.PropertyComparator)1 Specification (org.opengis.annotation.Specification)1