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;
}
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);
}
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);
}
}
}
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);
}
}
}
}
}
}
}
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;
}
Aggregations