use of javax.xml.bind.annotation.XmlRootElement in project sis by apache.
the class RenameListGenerator method add.
/**
* Gets the namespaces, types and properties for the given class.
* Properties defined in super-classes will be copied as if they were declared in-line.
* Those information are memorized for future listing with {@link #print(Appendable)}.
*
* @throws SchemaException if two properties have the same name in the same class and namespace.
*/
private void add(Class<?> classe) throws SchemaException {
XmlRootElement root = classe.getDeclaredAnnotation(XmlRootElement.class);
if (root != null) {
/*
* Add the following entry:
*
* http://a.namespace
* PX_AClass
* …
*
* Then list all properties below "PX_AClass". Note that the namespace may change because properties
* may be declared in different namespaces, but the class name stay the same. If the same properties
* are inherited by many classes, they will be repeated in each subclass.
*/
final String topLevelTypeName = root.name();
String classNS = namespace(classe, root.namespace());
for (; ; classNS = namespace(classe, root.namespace())) {
for (final Method method : classe.getDeclaredMethods()) {
if (!method.isBridge()) {
final XmlElement xe = method.getDeclaredAnnotation(XmlElement.class);
if (xe != null) {
String namespace = xe.namespace();
if (namespace.equals(DEFAULT)) {
namespace = classNS;
}
add(namespace, topLevelTypeName, xe.name());
}
}
}
classe = classe.getSuperclass();
root = classe.getDeclaredAnnotation(XmlRootElement.class);
if (root == null)
break;
}
} else {
/*
* In Apache SIS implementation, classes without JAXB annotation except on a single method are
* code lists or enumerations. Those classes have exactly one method annotated with @XmlElement,
* and that method actually gives a type, not a property (because of the way OGC/ISO wrap every
* properties in a type).
*/
XmlElement singleton = null;
for (final Method method : classe.getDeclaredMethods()) {
final XmlElement xe = method.getDeclaredAnnotation(XmlElement.class);
if (xe != null) {
if (singleton != null)
return;
singleton = xe;
}
}
}
}
use of javax.xml.bind.annotation.XmlRootElement in project sis by apache.
the class AnnotationConsistencyCheck method testImplementationAnnotations.
/**
* Tests the annotations on every SIS implementations of the interfaces enumerated
* in the {@link #types} array. More specifically this method tests that:
*
* <ul>
* <li>All implementation classes have {@link XmlRootElement} and {@link XmlType} annotations.</li>
* <li>The name declared in the {@code XmlType} annotations matches the
* {@link #getExpectedXmlTypeName expected value}.</li>
* <li>The name declared in the {@code XmlRootElement} annotations matches the identifier declared
* in the {@link UML} annotation of the GeoAPI interfaces, with {@code "Abstract"} prefix added
* if needed.</li>
* <li>The namespace declared in the {@code XmlRootElement} annotations is not redundant with
* the {@link XmlSchema} annotation in the package.</li>
* </ul>
*
* This method does not check the method annotations, since it is {@link #testMethodAnnotations()} job.
*/
@Test
@DependsOnMethod("testInterfaceAnnotations")
public void testImplementationAnnotations() {
for (final Class<?> type : types) {
if (CodeList.class.isAssignableFrom(type)) {
// Skip code lists, since they are not the purpose of this test.
continue;
}
testingClass = type.getCanonicalName();
/*
* Get the implementation class, which is mandatory (otherwise the
* subclass shall not include the interface in the 'types' array).
*/
final Class<?> impl = getImplementation(type);
assertNotNull("No implementation found.", impl);
assertNotSame("No implementation found.", type, impl);
testingClass = impl.getCanonicalName();
/*
* Compare the XmlRootElement with the UML annotation, if any. 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
* 'testInterfaceAnnotations()' method.
*/
final XmlRootElement root = impl.getAnnotation(XmlRootElement.class);
assertNotNull("Missing @XmlRootElement annotation.", root);
final UML uml = type.getAnnotation(UML.class);
// 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(root.namespace(), impl, uml);
/*
* Compare the XmlType annotation with the expected value.
*/
final XmlType xmlType = impl.getAnnotation(XmlType.class);
assertNotNull("Missing @XmlType annotation.", xmlType);
// More tests on development branch (removed on trunk because test depends on GeoAPI 3.1)
}
}
use of javax.xml.bind.annotation.XmlRootElement in project sis by apache.
the class PackageVerifier method verify.
/**
* Verifies {@code @XmlType} and {@code @XmlRootElement} on the class. This method verifies naming convention
* (type name should be same as root element name with {@value SchemaCompliance#TYPE_SUFFIX} suffix appended),
* ensures that the name exists in the schema, and checks the namespace.
*
* @param type the class on which to verify annotations.
*/
final void verify(final Class<?> type) throws IOException, ParserConfigurationException, SAXException, SchemaException {
/*
* Reinitialize fields to be updated for each class.
*/
classNS = null;
currentClass = type;
isDeprecatedClass = false;
properties = Collections.emptyMap();
final XmlType xmlType = type.getDeclaredAnnotation(XmlType.class);
final XmlRootElement xmlRoot = type.getDeclaredAnnotation(XmlRootElement.class);
XmlElement codeList = null;
/*
* Get the type name and namespace from the @XmlType or @XmlRootElement annotations.
* If both of them are present, verify that they are consistent (same namespace and
* same name with "_Type" suffix in @XmlType). If the type name is not declared, we
* assume that it is the same than the class name (this is what Apache SIS 0.8 does
* in its org.apache.sis.internal.jaxb.code package for CodeList adapters).
*/
// ISO class name (not the same than Java class name).
final String isoName;
if (xmlRoot != null) {
classNS = xmlRoot.namespace();
isoName = xmlRoot.name();
if (xmlType != null) {
if (!classNS.equals(xmlType.namespace())) {
throw new SchemaException(errorInClassMember(null).append("Mismatched namespace in @XmlType and @XmlRootElement."));
}
SchemaCompliance.verifyNamingConvention(type.getName(), isoName, xmlType.name(), SchemaCompliance.TYPE_SUFFIX);
}
} else if (xmlType != null) {
classNS = xmlType.namespace();
final String name = xmlType.name();
isoName = SchemaCompliance.trim(name, SchemaCompliance.TYPE_SUFFIX);
} else {
/*
* If there is neither @XmlRootElement or @XmlType annotation, it may be a code list as implemented
* in the org.apache.sis.internal.jaxb.code package. Those adapters have a single @XmlElement which
* is to be interpreted as if it was the actual type.
*/
for (final Method method : type.getDeclaredMethods()) {
final XmlElement e = method.getDeclaredAnnotation(XmlElement.class);
if (e != null) {
if (codeList != null)
return;
codeList = e;
}
}
if (codeList == null)
return;
classNS = codeList.namespace();
isoName = codeList.name();
}
/*
* Verify that the namespace declared on the class is not redundant with the namespace
* declared in the package. Actually redundant namespaces are not wrong, but we try to
* reduce code size.
*/
if (classNS.equals(AnnotationConsistencyCheck.DEFAULT)) {
classNS = packageNS;
} else if (classNS.equals(packageNS)) {
throw new SchemaException(errorInClassMember(null).append("Redundant namespace declaration: ").append(classNS));
}
/*
* Verify that the namespace has a prefix associated to it in the package-info file.
*/
if (namespaceIsUsed.put(classNS, Boolean.TRUE) == null) {
throw new SchemaException(errorInClassMember(null).append("No prefix in package-info for ").append(classNS));
}
/*
* Properties in the legacy GMD or GMI namespaces may be deprecated, depending if a replacement
* is already available or not. However properties in other namespaces should not be deprecated.
* Some validations of deprecated properties are skipped because we didn't loaded their schema.
*/
isDeprecatedClass = (LEGACY_NAMESPACES.get(classNS) == ALL);
if (!isDeprecatedClass) {
if (type.isAnnotationPresent(Deprecated.class)) {
throw new SchemaException(errorInClassMember(null).append("Unexpected @Deprecated annotation."));
}
/*
* Verify that class name exists, then verify its namespace (associated to the null key by convention).
*/
properties = schemas.typeDefinition(isoName);
if (properties == null) {
throw new SchemaException(errorInClassMember(null).append("Unknown name declared in @XmlRootElement: ").append(isoName));
}
final String expectedNS = properties.get(null).namespace;
if (!classNS.equals(expectedNS)) {
throw new SchemaException(errorInClassMember(null).append(isoName).append(" shall be associated to namespace ").append(expectedNS));
}
// If the class was a code list, we are done.
if (codeList != null)
return;
}
/*
* At this point the classNS, className, isDeprecatedClass and properties field have been set.
* We can now loop over the XML elements, which may be on fields or on methods (public or private).
*/
for (final Field field : type.getDeclaredFields()) {
Class<?> valueType = field.getType();
final boolean isCollection = Collection.class.isAssignableFrom(valueType);
if (isCollection) {
valueType = Classes.boundOfParameterizedProperty(field);
}
verify(field, field.getName(), valueType, isCollection);
}
for (final Method method : type.getDeclaredMethods()) {
Class<?> valueType = method.getReturnType();
final boolean isCollection = Collection.class.isAssignableFrom(valueType);
if (isCollection) {
valueType = Classes.boundOfParameterizedProperty(method);
}
verify(method, method.getName(), valueType, isCollection);
}
}
use of javax.xml.bind.annotation.XmlRootElement in project candlepin by candlepin.
the class CandlepinSwaggerModelConverter method resolve.
public Model resolve(Type rawType, ModelConverterContext context, Iterator<ModelConverter> next) {
if (this.shouldIgnoreClass(rawType)) {
return null;
}
/**
* See java doc of NestedComplexType. This unwrapping makes sure that a
* real type of field used throughout the method. At the same time flag
* 'isNested' helps to indicate later in the method that this type may
* be introspected as Hateoas enabled field
*/
boolean isNested = false;
if (rawType instanceof NestedComplexType) {
isNested = true;
NestedComplexType nested = (NestedComplexType) rawType;
rawType = nested.getOriginalType();
}
JavaType type = pMapper.constructType(rawType);
if (type.isEnumType() || PrimitiveType.fromType(type) != null) {
// We don't build models for primitive types
return null;
}
final BeanDescription beanDesc = pMapper.getSerializationConfig().introspect(type);
// Couple of possibilities for defining
String name = isNested ? "Nested" : "";
name += pTypeName(type, beanDesc);
if ("Object".equals(name)) {
return new ModelImpl();
}
final ModelImpl model = new ModelImpl().type(ModelImpl.OBJECT).name(name).description(pDescription(beanDesc.getClassInfo()));
if (!type.isContainerType()) {
// define the model here to support self/cyclic referencing of
// models
context.defineModel(name, model, type, null);
}
if (type.isContainerType()) {
// We treat collections as primitive types, just need to add models
// for values (if any)
context.resolve(type.getContentType());
return null;
}
// if XmlRootElement annotation, construct an Xml object and attach it
// to the model
XmlRootElement rootAnnotation = beanDesc.getClassAnnotations().get(XmlRootElement.class);
if (rootAnnotation != null && !"".equals(rootAnnotation.name()) && !"##default".equals(rootAnnotation.name())) {
log.debug(rootAnnotation.toString());
Xml xml = new Xml().name(rootAnnotation.name());
if (rootAnnotation.namespace() != null && !"".equals(rootAnnotation.namespace()) && !"##default".equals(rootAnnotation.namespace())) {
xml.namespace(rootAnnotation.namespace());
}
model.xml(xml);
}
// see if @JsonIgnoreProperties exist
Set<String> propertiesToIgnore = new HashSet<>();
JsonIgnoreProperties ignoreProperties = beanDesc.getClassAnnotations().get(JsonIgnoreProperties.class);
if (ignoreProperties != null) {
propertiesToIgnore.addAll(Arrays.asList(ignoreProperties.value()));
}
final ApiModel apiModel = beanDesc.getClassAnnotations().get(ApiModel.class);
String disc = (apiModel == null) ? "" : apiModel.discriminator();
if (apiModel != null && StringUtils.isNotEmpty(apiModel.reference())) {
model.setReference(apiModel.reference());
}
if (disc.isEmpty()) {
// longer method would involve
// AnnotationIntrospector.findTypeResolver(...) but:
JsonTypeInfo typeInfo = beanDesc.getClassAnnotations().get(JsonTypeInfo.class);
if (typeInfo != null) {
disc = typeInfo.property();
}
}
if (!disc.isEmpty()) {
model.setDiscriminator(disc);
}
List<Property> props = new ArrayList<>();
for (BeanPropertyDefinition propDef : beanDesc.findProperties()) {
parseProperty(context, isNested, beanDesc, propertiesToIgnore, props, propDef);
}
Collections.sort(props, getPropertyComparator());
Map<String, Property> modelProps = new LinkedHashMap<>();
for (Property prop : props) {
modelProps.put(prop.getName(), prop);
}
model.setProperties(modelProps);
/**
* This must be done after model.setProperties so that the model's set
* of properties is available to filter from any subtypes
*/
if (!resolveSubtypes(model, beanDesc, context)) {
model.setDiscriminator(null);
}
return model;
}
use of javax.xml.bind.annotation.XmlRootElement in project jbpm by kiegroup.
the class JaxbTaskSerializationTest method taskCmdUniqueRootElementTest.
@Test
public void taskCmdUniqueRootElementTest() throws Exception {
Set<String> uniqueRootElemSet = new HashSet<String>();
for (Class<?> jaxbClass : reflections.getTypesAnnotatedWith(XmlRootElement.class)) {
XmlRootElement xmlRootElemAnno = jaxbClass.getAnnotation(XmlRootElement.class);
assertTrue(xmlRootElemAnno.name() + " is not a unique @XmlRootElement value!", uniqueRootElemSet.add(xmlRootElemAnno.name()));
}
}
Aggregations