if (factoryClass != XmlType.DEFAULT.class)
factoryClassInfo = (ClassInfo) typeInfo.getTypeInfoFactory().getTypeInfo(factoryClass);
factoryMethod = xmlType.factoryMethod();
propertyOrder = xmlType.propOrder();
}
JBossXmlType jbossXmlType = typeInfo.getUnderlyingAnnotation(JBossXmlType.class);
if (jbossXmlType != null)
{
beanAdapterBuilderClass = jbossXmlType.beanAdapterBuilder();
}
// Determine the property access order
XmlAccessorOrder accessorOrder = typeInfo.getUnderlyingAnnotation(XmlAccessorOrder.class);
if (accessorOrder == null)
{
PackageInfo pkg = typeInfo.getPackage();
if (pkg != null)
accessorOrder = pkg.getUnderlyingAnnotation(XmlAccessorOrder.class);
}
if (accessorOrder != null)
accessOrder = accessorOrder.value();
// Create the binding
TypeBinding typeBinding = null;
if (root)
{
QName qName = generateXmlName(typeInfo, XmlNsForm.QUALIFIED, overrideNamespace, overrideName);
typeBinding = new TypeBinding(qName);
}
else
{
typeBinding = new TypeBinding();
}
// Push into the cache early to avoid recursion
typeCache.put(typeInfo, typeBinding);
JBossXmlAdaptedType adaptedType = typeInfo.getUnderlyingAnnotation(JBossXmlAdaptedType.class);
if(adaptedType != null)
{
if(adaptedType.type() != JBossXmlConstants.DEFAULT.class)
throw new JBossXBRuntimeException("@JBossXmlAdaptedType on a type must not specify type element: " + typeInfo.getName());
adaptType(typeBinding, adaptedType);
}
// Determine any factory method
MethodInfo factory = null;
if (factoryMethod != null && factoryMethod.length() > 0)
factory = Config.findMethodInfo(factoryClassInfo, factoryMethod, null, true, true);
// Create the handler
BeanInfo beanInfo = JBossXBBuilder.configuration.getBeanInfo(typeInfo);
BeanAdapterFactory beanAdapterFactory = createAdapterFactory(beanAdapterBuilderClass, beanInfo, factory);
BeanHandler handler = new BeanHandler(beanInfo.getName(), beanAdapterFactory);
typeBinding.setHandler(handler);
if (trace)
log.trace("Created BeanHandler for type=" + beanInfo.getName() + " factory=" + factory);
// Look through the properties
JBossXmlNoElements jbossXmlNoElements = typeInfo.getUnderlyingAnnotation(JBossXmlNoElements.class);
boolean noElements = jbossXmlNoElements != null;
PropertyInfo valueProperty = null;
PropertyInfo wildcardProperty = null;
boolean allBinding = propertyOrder.length == 0;
boolean determinePropertyOrder = allBinding || (propertyOrder.length == 1 && propertyOrder[0].length() == 0);
ArrayList<String> propertyNames = new ArrayList<String>();
Set<PropertyInfo> properties = beanInfo.getProperties();
if (properties != null && properties.isEmpty() == false)
{
boolean seenXmlAnyElement = false;
PropertyInfo seenXmlAnyAttribute = null;
for (PropertyInfo property : properties)
{
push(typeInfo, property.getName());
if (trace)
log.trace("Checking property " + property.getName() + " for " + beanInfo.getName() + " type=" + property.getType().getName());
// Is this the value property?
XmlValue xmlValue = property.getUnderlyingAnnotation(XmlValue.class);
if (xmlValue != null)
{
if (trace)
log.trace("Seen @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
if (valueProperty != null)
throw new RuntimeException("@XmlValue seen on two properties: " + property.getName() + " and " + valueProperty.getName());
valueProperty = property;
}
// Is this the wildcard property?
boolean ignoreXmlAnyElement = false;
XmlAnyElement xmlAnyElement = property.getUnderlyingAnnotation(XmlAnyElement.class);
if (xmlAnyElement != null)
{
if (trace)
log.trace("Seen @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
if (wildcardProperty != null && seenXmlAnyElement)
throw new RuntimeException("@XmlAnyElement seen on two properties: " + property.getName() + " and " + wildcardProperty.getName());
wildcardProperty = property;
seenXmlAnyElement = true;
// should we ignore it
if(property.getUnderlyingAnnotation(XmlElements.class) == null &&
property.getUnderlyingAnnotation(XmlElementRefs.class) == null)
ignoreXmlAnyElement = true;
}
// Is this an attribute
XmlAttribute xmlAttribute = property.getUnderlyingAnnotation(XmlAttribute.class);
if (xmlAttribute != null)
{
JBossXmlAttribute jbossXmlAttribute = property.getUnderlyingAnnotation(JBossXmlAttribute.class);
// Determine the name
QName qName = generateXmlName(property.getName(), attributeForm, xmlAttribute.namespace(), xmlAttribute.name());
// Resolve the type
TypeInfo attributeTypeInfo = property.getType();
if (jbossXmlAttribute != null && jbossXmlAttribute.type() != Object.class)
attributeTypeInfo = attributeTypeInfo.getTypeInfoFactory().getTypeInfo(jbossXmlAttribute.type());
TypeBinding attributeType = resolveTypeBinding(attributeTypeInfo);
// Create the attribute handler
AttributeHandler attributeHandler = new PropertyHandler(property, attributeTypeInfo);
// Create the attributre and bind it to the type
AttributeBinding attribute = new AttributeBinding(schemaBinding, qName, attributeType, attributeHandler);
attribute.setRequired(xmlAttribute.required());
typeBinding.addAttribute(attribute);
JBossXmlPreserveWhitespace preserveSpace = property.getUnderlyingAnnotation(JBossXmlPreserveWhitespace.class);
if(preserveSpace != null)
attribute.setNormalizeSpace(preserveSpace.preserve() ? false : true);
if (trace)
log.trace("Bound attribute " + qName + " type=" + beanInfo.getName() + " property=" + property.getName() + " propertyType=" + attributeTypeInfo + ", normalizeSpace=" + attribute.isNormalizeSpace());
}
// Is this any attribute
XmlAnyAttribute xmlAnyAttribute = property.getUnderlyingAnnotation(XmlAnyAttribute.class);
if (xmlAnyAttribute != null)
{
if (seenXmlAnyAttribute != null)
throw new RuntimeException("@XmlAnyAttribute seen on two properties: " + property.getName() + " and " + seenXmlAnyAttribute.getName());
seenXmlAnyAttribute = property;
AnyAttributePropertyHandler anyHandler = new AnyAttributePropertyHandler(property, property.getType());
AnyAttributeBinding anyAttribute = new AnyAttributeBinding(schemaBinding, anyHandler);
typeBinding.setAnyAttribute(anyAttribute);
JBossXmlPreserveWhitespace preserveSpace = property.getUnderlyingAnnotation(JBossXmlPreserveWhitespace.class);
if(preserveSpace != null)
anyAttribute.setNormalizeSpace(preserveSpace.preserve() ? false : true);
if (trace)
log.trace("Bound any attribute type=" + beanInfo.getName() + " property=" + property.getName() + ", normalizeSpace=" + anyAttribute.isNormalizeSpace());
}
// Are we determining the property order?
if (determinePropertyOrder)
{
// Value property
if (xmlValue != null)
{
if (trace)
log.trace("Ignore not element @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
pop();
continue;
}
// Wildcard property
if (ignoreXmlAnyElement)
{
if (trace)
log.trace("Ignore not element @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
pop();
continue;
}
// Ignore xml attribute
if (xmlAttribute != null)
{
if (trace)
log.trace("Ignore not element @XmlAttribute for type=" + beanInfo.getName() + " property=" + property.getName());
pop();
continue;
}
// Ignore xml tranient
XmlTransient xmlTransient = property.getUnderlyingAnnotation(XmlTransient.class);
if (xmlTransient != null)
{
if (trace)
log.trace("Ignore not element @XmlTransient for type=" + beanInfo.getName() + " property=" + property.getName());
pop();
continue;
}
// Ignore the class property
String name = property.getName();
if ("class".equals(name))
{
pop();
continue;
}
if (noElements)
{
pop();
continue;
}
if (trace)
log.trace("Element for type=" + beanInfo.getName() + " property=" + property.getName());
propertyNames.add(property.getName());
}
pop();
}
// Apply any access order
if (determinePropertyOrder)
{
if (accessOrder == XmlAccessOrder.ALPHABETICAL)
Collections.sort(propertyNames);
propertyOrder = propertyNames.toArray(new String[propertyNames.size()]);
}
}
// No value property, see if we have a default one
//if (valueProperty == null)
//{
// try
// {
// valueProperty = beanInfo.getProperty("value");
// }
// catch (Exception ignored)
// {
// Nope.
// }
//}
// Bind the value
if (valueProperty != null)
{
CharactersHandler charactersHandler = new ValueHandler(valueProperty);
typeBinding.setSimpleType(charactersHandler);
JBossXmlValue jbossXmlValue = typeInfo.getUnderlyingAnnotation(JBossXmlValue.class);
if(jbossXmlValue != null)
{
if(trace)
log.trace("Type " + typeInfo.getName() + " is annotated with @JBossXmlValue.ignoreEmptyString=" + jbossXmlValue.ignoreEmptyString());
typeBinding.setIgnoreEmptyString(jbossXmlValue.ignoreEmptyString());
}
}
else if (trace)
log.trace("No value for type=" + beanInfo.getName());
if (trace)
log.trace("PropertyOrder " + Arrays.asList(propertyOrder) + " for type=" + beanInfo.getName());
// Determine the model
// TODO simple types/content when no properties other than @XmlValue and @XmlAttribute
typeBinding.setSimple(false);
ModelGroupBinding model = null;
boolean propOrderMissing = propertyNames.size() > 1 && determinePropertyOrder && accessOrder == XmlAccessOrder.UNDEFINED;
if(jbossXmlType != null && !JBossXmlConstants.DEFAULT.equals(jbossXmlType.modelGroup()))
model = createModelGroup(jbossXmlType.modelGroup(), typeInfo, propOrderMissing, propertyOrder);
else if (allBinding)
model = new AllBinding(schemaBinding);
else
{
if(propOrderMissing)