[jboss-svn-commits] JBoss Common SVN: r2510 - jbossxb-builder/trunk/src/main/java/org/jboss/xb/builder.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Aug 24 18:01:02 EDT 2007
Author: alex.loubyansky at jboss.com
Date: 2007-08-24 18:01:01 -0400 (Fri, 24 Aug 2007)
New Revision: 2510
Modified:
jbossxb-builder/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java
Log:
support for @XmlJavaTypeAdapter, fixes for @XmlElementWrapper (accidently reformatted some stuff)
Modified: jbossxb-builder/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java
===================================================================
--- jbossxb-builder/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java 2007-08-24 15:24:27 UTC (rev 2509)
+++ jbossxb-builder/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java 2007-08-24 22:01:01 UTC (rev 2510)
@@ -1,24 +1,24 @@
/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
package org.jboss.xb.builder;
import java.lang.reflect.Method;
@@ -50,6 +50,8 @@
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.namespace.QName;
import org.jboss.beans.info.spi.BeanInfo;
@@ -63,6 +65,7 @@
import org.jboss.reflect.spi.MethodInfo;
import org.jboss.reflect.spi.PackageInfo;
import org.jboss.reflect.spi.TypeInfo;
+import org.jboss.reflect.spi.TypeInfoFactory;
import org.jboss.xb.annotations.JBossXmlAdaptedType;
import org.jboss.xb.annotations.JBossXmlAdaptedTypes;
import org.jboss.xb.annotations.JBossXmlAttribute;
@@ -84,6 +87,7 @@
import org.jboss.xb.binding.sunday.unmarshalling.AttributeHandler;
import org.jboss.xb.binding.sunday.unmarshalling.CharactersHandler;
import org.jboss.xb.binding.sunday.unmarshalling.ChoiceBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.DefaultElementHandler;
import org.jboss.xb.binding.sunday.unmarshalling.DefaultElementInterceptor;
import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
@@ -126,16 +130,16 @@
{
/** The log */
private static final Logger log = Logger.getLogger(JBossXBBuilder.class);
-
+
/** Whether trace is enabled */
private boolean trace = log.isTraceEnabled();
-
+
/** The schema binding */
private SchemaBinding schemaBinding;
-
+
/** The root type */
private ClassInfo root;
-
+
/** The namespace */
private String defaultNamespace;
@@ -144,16 +148,16 @@
/** The element form */
private XmlNsForm elementForm = XmlNsForm.UNSET;
-
+
/** A cache of types */
private Map<TypeInfo, TypeBinding> typeCache = new HashMap<TypeInfo, TypeBinding>();
/** A root elements we have processed */
private Map<TypeInfo, ElementBinding> rootCache = new HashMap<TypeInfo, ElementBinding>();
-
+
/** The current location */
private Stack<Location> locations = new Stack<Location>();
-
+
/**
* Create a new JBossXBNoSchemaBuilder.
*
@@ -167,7 +171,7 @@
this.root = root;
}
-
+
/**
* Build the schema
*
@@ -190,9 +194,9 @@
JBossXBBuilder.initSchema(schemaBinding, root);
if (trace)
log.trace("Building schema for " + root.getName() + " schemaBinding=" + schemaBinding);
-
+
// Remember the default namespace
- if(defaultNamespace == null)
+ if (defaultNamespace == null)
{
defaultNamespace = (String) schemaBinding.getNamespaces().iterator().next();
}
@@ -203,7 +207,7 @@
attributeForm = jbossXmlSchema.attributeFormDefault();
elementForm = jbossXmlSchema.elementFormDefault();
}
-
+
// Look for an annotation
PackageInfo packageInfo = root.getPackage();
if (packageInfo != null)
@@ -213,10 +217,10 @@
{
if (attributeForm == XmlNsForm.UNSET)
attributeForm = jbossXmlSchema.attributeFormDefault();
- if (elementForm == XmlNsForm.UNSET);
+ if (elementForm == XmlNsForm.UNSET)
elementForm = jbossXmlSchema.elementFormDefault();
}
-
+
XmlSchema xmlSchema = packageInfo.getUnderlyingAnnotation(XmlSchema.class);
if (xmlSchema != null)
{
@@ -226,13 +230,13 @@
defaultNamespace = namespace;
addNamespace(defaultNamespace, true);
}
-
+
if (attributeForm == XmlNsForm.UNSET)
attributeForm = xmlSchema.attributeFormDefault();
- if (elementForm == XmlNsForm.UNSET);
+ if (elementForm == XmlNsForm.UNSET)
elementForm = xmlSchema.elementFormDefault();
}
-
+
// Check for adapted types
JBossXmlAdaptedTypes adaptedTypes = packageInfo.getUnderlyingAnnotation(JBossXmlAdaptedTypes.class);
if (adaptedTypes != null)
@@ -245,7 +249,7 @@
generateAdaptedType(adaptedType);
}
}
-
+
/**
* Create the root elements
*/
@@ -267,7 +271,7 @@
return;
// Put a skeleton marker in the cache so we know not to redo it
rootCache.put(typeInfo, null);
-
+
// We force the element to be a root element
push(typeInfo);
try
@@ -293,11 +297,11 @@
{
// Resolve the type
TypeBinding typeBinding = resolveTypeBinding(typeInfo);
-
+
// Create the element
return createElementBinding(typeInfo, typeBinding, name, root);
}
-
+
/**
* Create an element binding
*
@@ -322,7 +326,7 @@
overrideName = xmlRootElement.name();
}
}
-
+
// Create the binding
XmlNsForm form = elementForm;
if (root)
@@ -330,7 +334,7 @@
QName qName = generateXmlName(name, form, overrideNamespace, overrideName);
return createElementBinding(typeInfo, typeBinding, qName, root);
}
-
+
/**
* Create an element binding
*
@@ -353,7 +357,6 @@
root = true;
}
-
ElementBinding elementBinding = new ElementBinding(schemaBinding, qName, typeBinding);
if (trace)
log.trace("created element " + qName + " element=" + elementBinding + " rootElement=" + root);
@@ -367,7 +370,7 @@
particleBinding.setMaxOccurs(1);
rootCache.put(typeInfo, elementBinding);
}
-
+
return elementBinding;
}
@@ -381,20 +384,20 @@
if (typeInfo.isPrimitive() == false && typeInfo.isEnum() && typeInfo.isAnnotation() && Object.class.getName().equals(typeInfo.getName()) == false)
{
ClassInfo classInfo = (ClassInfo) typeInfo;
-
+
// Create the type
resolveTypeBinding(typeInfo);
-
+
// Check wether we need to add it as a root element
if (rootCache.containsKey(typeInfo) == false)
{
XmlRootElement xmlRootElement = classInfo.getUnderlyingAnnotation(XmlRootElement.class);
- if (xmlRootElement != null)
+ if (xmlRootElement != null)
createRootElementBinding(typeInfo);
}
}
}
-
+
/**
* Resolve a type binding
*
@@ -409,19 +412,19 @@
// Look for a cached value
TypeBinding result = typeCache.get(typeInfo);
-
+
// No cached value
if (result == null)
{
// Generate it
result = generateTypeBinding(typeInfo);
-
+
// Cache it
typeCache.put(typeInfo, result);
}
if (trace)
log.trace("resolved type " + typeInfo.getName() + " binding=" + result);
-
+
// Return the result
return result;
}
@@ -441,20 +444,20 @@
if (typeInfo.isAnnotation())
return generateAnnotation((ClassInfo) typeInfo);
-
+
if (typeInfo.isArray())
return generateArray((ArrayInfo) typeInfo);
-
+
if (typeInfo.isCollection())
return generateCollection((ClassInfo) typeInfo);
-
+
if (typeInfo.isMap())
return generateMap((ClassInfo) typeInfo);
-
+
TypeBinding typeBinding = isSimpleType(typeInfo);
if (typeBinding != null)
return typeBinding;
-
+
return generateBean((ClassInfo) typeInfo);
}
finally
@@ -471,7 +474,7 @@
for (int i = 0; i < typeArgs.length; ++i)
process(typeArgs[i]);
}
-
+
// Process the super class
ClassInfo superClass = classInfo.getGenericSuperclass();
if (superClass != null)
@@ -479,7 +482,7 @@
}
}
}
-
+
/**
* Generate an enum type binding
*
@@ -506,10 +509,10 @@
if (xmlEnum != null)
xmlEnumValue = xmlEnum.value();
TypeInfo enumType = typeInfo.getTypeInfoFactory().getTypeInfo(xmlEnumValue);
-
+
// Resolve the enum type as the parent (must be simple)
TypeBinding parent = getSimpleType(enumType);
-
+
// Create the enum type
QName qName = null;
TypeBinding typeBinding = null;
@@ -522,21 +525,21 @@
{
typeBinding = new TypeBinding(null, parent);
}
-
+
typeBinding.setValueAdapter(new EnumValueAdapter(qName, typeInfo, enumType));
if (trace)
log.trace("Created enum=" + typeInfo.getName() + " type=" + typeBinding + " rootType=" + root);
-
+
// Bind it as a global type
if (root)
schemaBinding.addType(typeBinding);
else
typeBinding.setSchemaBinding(schemaBinding);
-
+
return typeBinding;
}
-
+
/**
* Generate an adapted type
*
@@ -552,10 +555,10 @@
Class<? extends ValueAdapter> adapter = adaptedType.valueAdapter();
try
{
-
+
TypeInfo typeInfo = JBossXBBuilder.configuration.getTypeInfo(type);
BeanInfo adapterInfo = JBossXBBuilder.configuration.getBeanInfo(adapter);
-
+
ValueAdapter valueAdapter = (ValueAdapter) adapterInfo.newInstance();
QName qName = generateXmlName(typeInfo, XmlNsForm.QUALIFIED, overrideNamespace, overrideName);
@@ -578,7 +581,7 @@
throw new RuntimeException("Unable to adapt type " + type.getName() + " with " + adapter.getName(), t);
}
}
-
+
/**
* Generate an annotation type binding
*
@@ -590,7 +593,7 @@
// TODO generateAnnotation
throw new UnsupportedOperationException("generateAnnotation");
}
-
+
/**
* Generate an array type binding
*
@@ -601,7 +604,7 @@
{
return resolveTypeBinding(typeInfo.getComponentType());
}
-
+
/**
* Generate a collection type binding
*
@@ -622,7 +625,7 @@
return generateBean(typeInfo);
}
}
-
+
/**
* Generate a map type binding
*
@@ -634,7 +637,7 @@
// TODO generateMap
return generateBean(typeInfo);
}
-
+
/**
* Check whether this is a simple type
*
@@ -652,7 +655,7 @@
result.setHandler(BuilderSimpleParticleHandler.SIMPLE_INSTANCE);
return result;
}
-
+
/**
* Get the simple type
*
@@ -667,7 +670,7 @@
throw new IllegalStateException(typeInfo.getName() + " does not map to a simple type.");
return result;
}
-
+
/**
* Generate a bean type binding
*
@@ -678,7 +681,7 @@
{
return generateBean(typeInfo, false);
}
-
+
/**
* Generate a bean type binding
*
@@ -690,7 +693,7 @@
{
return generateType(typeInfo, root);
}
-
+
/**
* Generate a bean type binding
*
@@ -716,7 +719,7 @@
overrideName = xmlType.name();
if (overrideName.length() == 0)
root = false;
-
+
Class<?> factoryClass = xmlType.factoryClass();
if (factoryClass != XmlType.DEFAULT.class)
factoryClassInfo = (ClassInfo) typeInfo.getTypeInfoFactory().getTypeInfo(factoryClass);
@@ -738,7 +741,7 @@
}
if (accessorOrder != null)
accessOrder = accessorOrder.value();
-
+
// Create the binding
TypeBinding typeBinding = null;
if (root)
@@ -758,7 +761,7 @@
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 = null;
@@ -770,7 +773,7 @@
}
catch (Throwable t)
{
- throw new RuntimeException("Error creating BeanAdapterFactory for " + beanAdapterBuilderClass.getName(), t);
+ throw new RuntimeException("Error creating BeanAdapterFactory for " + beanAdapterBuilderClass.getName(), t);
}
BeanHandler handler = new BeanHandler(beanInfo.getName(), beanAdapterFactory);
typeBinding.setHandler(handler);
@@ -791,10 +794,10 @@
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)
@@ -805,7 +808,7 @@
throw new RuntimeException("@XmlValue seen on two properties: " + property.getName() + " and " + valueProperty.getName());
valueProperty = property;
}
-
+
// Is this the wildcard property?
XmlAnyElement xmlAnyElement = property.getUnderlyingAnnotation(XmlAnyElement.class);
if (xmlAnyElement != null)
@@ -836,7 +839,7 @@
attribute.setRequired(xmlAttribute.required());
typeBinding.addAttribute(attribute);
if (trace)
- log.trace("Bound attribute " + qName + " type=" + beanInfo.getName() + " property=" + property.getName() +" propertyType=" + attributeTypeInfo);
+ log.trace("Bound attribute " + qName + " type=" + beanInfo.getName() + " property=" + property.getName() + " propertyType=" + attributeTypeInfo);
}
// Are we determining the property order?
@@ -882,18 +885,18 @@
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
@@ -902,7 +905,7 @@
if (accessOrder == XmlAccessOrder.ALPHABETICAL)
Collections.sort(propertyNames);
propertyOrder = propertyNames.toArray(new String[propertyNames.size()]);
- }
+ }
}
// No value property, see if we have a default one
@@ -917,7 +920,7 @@
// Nope.
// }
//}
-
+
// Bind the value
if (valueProperty != null)
{
@@ -926,10 +929,10 @@
}
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);
@@ -952,7 +955,7 @@
typeParticle.setMaxOccurs(1);
typeBinding.setParticle(typeParticle);
- if(typeInfo.isCollection())
+ if (typeInfo.isCollection())
{
TypeInfo memberBaseType = findComponentType(typeInfo);
// if the type is a parameterized collection then
@@ -967,7 +970,7 @@
.getUnderlyingAnnotation(JBossXmlModelGroup.class);
if (xmlModelGroup != null && xmlModelGroup.particles().length > 0)
{
- if(trace)
+ if (trace)
log.trace("Item base type for " + typeInfo.getName() + " is " + memberBaseType.getName() + " and bound to repeatable choice");
// it's choice by default based on the idea that the
@@ -976,19 +979,19 @@
choiceGroup.setHandler(BuilderParticleHandler.INSTANCE);
ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
model.addParticle(choiceParticle);
-
- for(JBossXmlModelGroup.Particle member : xmlModelGroup.particles())
+
+ for (JBossXmlModelGroup.Particle member : xmlModelGroup.particles())
{
- XmlElement element = member.element();
+ XmlElement element = member.element();
QName memberQName = generateXmlName(element.name(), XmlNsForm.QUALIFIED, element.namespace(), null);
TypeInfo memberTypeInfo = typeInfo.getTypeInfoFactory().getTypeInfo(member.type());
boolean isCol = false;
- if(memberTypeInfo.isCollection())
+ if (memberTypeInfo.isCollection())
{
// TODO here we should properly identify the type of the item (based on a testcase)
//memberTypeInfo = pti.getActualTypeArguments()[0];
- memberTypeInfo = findComponentType((ClassInfo)memberTypeInfo);
+ memberTypeInfo = findComponentType((ClassInfo) memberTypeInfo);
isCol = true;
}
@@ -997,27 +1000,27 @@
memberElement.setNillable(true);
ParticleBinding memberParticle = new ParticleBinding(memberElement, 0, 1, isCol);
choiceGroup.addParticle(memberParticle);
-
+
typeBinding.pushInterceptor(memberQName, ChildCollectionInterceptor.SINGLETON);
}
-
- if(trace)
+
+ if (trace)
log.trace("choices for " + typeBinding.getQName() + ": " + choiceGroup.getParticles());
}
}
}
-
+
// Determine the wildcard handler
AbstractPropertyHandler wildcardHandler = null;
if (wildcardProperty != null)
{
TypeInfo wildcardType = wildcardProperty.getType();
if (wildcardType.isCollection())
- wildcardHandler = new CollectionPropertyWildcardHandler(wildcardProperty, wildcardType);
+ wildcardHandler = new CollectionPropertyWildcardHandler(wildcardProperty, wildcardType);
else
wildcardHandler = new PropertyWildcardHandler(wildcardProperty, wildcardType);
}
-
+
// Look through the properties
for (String name : propertyOrder)
{
@@ -1025,16 +1028,16 @@
push(typeInfo, name);
// Get the property
- PropertyInfo property = beanInfo.getProperty(name);
+ PropertyInfo property = beanInfo.getProperty(name);
TypeInfo propertyType = property.getType();
if (trace)
log.trace("Processing type=" + beanInfo.getName() + " property=" + property.getName());
-
+
// This is illegal
XmlTransient xmlTransient = property.getUnderlyingAnnotation(XmlTransient.class);
if (xmlTransient != null)
throw new RuntimeException("Property " + name + " in property order " + Arrays.asList(propertyOrder) + " is marked @XmlTransient");
-
+
// The current model
ModelGroupBinding localModel = model;
@@ -1058,7 +1061,7 @@
// TODO XmlElement on this property?..
XmlElement propXmlElement = property.getUnderlyingAnnotation(XmlElement.class);
- if(propXmlElement != null)
+ if (propXmlElement != null)
{
propClassInfo = (ClassInfo) propClassInfo.getTypeInfoFactory().getTypeInfo(propXmlElement.type());
}
@@ -1066,11 +1069,11 @@
JBossXmlModelGroup xmlModelGroup = propClassInfo.getUnderlyingAnnotation(JBossXmlModelGroup.class);
if (xmlModelGroup != null && xmlModelGroup.particles().length == 0)
{
- if(trace)
+ if (trace)
log.trace("Property " + property.getName() + " is bound to " + xmlModelGroup.kind());
ModelGroupBinding propertyGroup = new SequenceBinding(schemaBinding);
- if(!JBossXmlConstants.DEFAULT.equals(xmlModelGroup.name()))
+ if (!JBossXmlConstants.DEFAULT.equals(xmlModelGroup.name()))
{
// TODO what if it doesn't have a name? should an artificial one be created?
propertyGroup.setQName(new QName(name));
@@ -1092,7 +1095,7 @@
propertyHandler = new PropertyHandler(property, propClassInfo);
}
beanAdapterFactory.addProperty(propertyGroup.getQName(), propertyHandler);
-
+
// handler for the model group members
BeanInfo propBeanInfo = JBossXBBuilder.configuration.getBeanInfo(propClassInfo);
BeanAdapterFactory propBeanAdapterFactory = null;
@@ -1104,27 +1107,27 @@
}
catch (Throwable t)
{
- throw new RuntimeException("Error creating BeanAdapterFactory for " + beanAdapterBuilderClass.getName(), t);
+ throw new RuntimeException("Error creating BeanAdapterFactory for " + beanAdapterBuilderClass.getName(), t);
}
BeanHandler propHandler = new BeanHandler(propBeanInfo.getName(), propBeanAdapterFactory);
propertyGroup.setHandler(propHandler);
-
+
String[] memberOrder = xmlModelGroup.propOrder();
- if(memberOrder.length == 0 || memberOrder[0].length() == 0)
+ if (memberOrder.length == 0 || memberOrder[0].length() == 0)
{
List<String> propNames = new ArrayList<String>();
- for(PropertyInfo prop : propBeanInfo.getProperties())
+ for (PropertyInfo prop : propBeanInfo.getProperties())
{
propNames.add(prop.getName());
}
memberOrder = propNames.toArray(new String[propNames.size()]);
}
- if(trace)
+ if (trace)
log.trace("Property order for " + xmlModelGroup.kind() + " property " + property.getName() + ": " + Arrays.asList(memberOrder));
-
+
// bind model group members
- for(String memberPropName : memberOrder)
+ for (String memberPropName : memberOrder)
{
if ("class".equals(memberPropName))
{
@@ -1136,41 +1139,41 @@
String memberNamespace = null;
JBossXmlNsPrefix nsPrefix = memberProp.getUnderlyingAnnotation(JBossXmlNsPrefix.class);
- if(nsPrefix != null)
+ if (nsPrefix != null)
{
memberNamespace = schemaBinding.getNamespace(nsPrefix.prefix());
- if(memberNamespace == null && nsPrefix.schemaTargetIfNotMapped())
+ if (memberNamespace == null && nsPrefix.schemaTargetIfNotMapped())
{
- throw new IllegalStateException("Prefix '" + nsPrefix.prefix() + "' is not mapped to any namespace!");
+ throw new IllegalStateException("Prefix '" + nsPrefix.prefix() + "' is not mapped to any namespace!");
}
}
-
+
String memberName = null;
XmlElement memberXmlElement = memberProp.getUnderlyingAnnotation(XmlElement.class);
- if(memberXmlElement != null)
+ if (memberXmlElement != null)
{
- if(!XmlElement.DEFAULT.class.equals(memberXmlElement.type()))
+ if (!XmlElement.DEFAULT.class.equals(memberXmlElement.type()))
{
memberTypeInfo = memberTypeInfo.getTypeInfoFactory().getTypeInfo(memberXmlElement.type());
}
-
- if(memberNamespace == null)
+
+ if (memberNamespace == null)
memberNamespace = memberXmlElement.namespace();
memberName = memberXmlElement.name();
}
- if(memberNamespace == null)
+ if (memberNamespace == null)
{
memberNamespace = defaultNamespace;
}
boolean isCol = false;
AbstractPropertyHandler memberPropertyHandler = null;
- if(memberTypeInfo.isCollection())
+ if (memberTypeInfo.isCollection())
{
memberPropertyHandler = new CollectionPropertyHandler(memberProp, memberTypeInfo);
isCol = true;
- memberTypeInfo = findComponentType((ClassInfo)memberTypeInfo);
+ memberTypeInfo = findComponentType((ClassInfo) memberTypeInfo);
}
else
{
@@ -1180,13 +1183,22 @@
QName memberQName = generateXmlName(memberProp.getName(), elementForm, memberNamespace, memberName);
propBeanAdapterFactory.addProperty(memberQName, memberPropertyHandler);
+ XBValueAdapter valueAdapter = null;
+ XmlJavaTypeAdapter xmlTypeAdapter = memberProp.getUnderlyingAnnotation(XmlJavaTypeAdapter.class);
+ if (xmlTypeAdapter != null)
+ {
+ valueAdapter = new XBValueAdapter(xmlTypeAdapter.value(), memberTypeInfo.getTypeInfoFactory());
+ memberTypeInfo = valueAdapter.getAdaptedType();
+ }
+
TypeBinding memberTypeBinding = resolveTypeBinding(memberTypeInfo);
ElementBinding memberElement = createElementBinding(memberTypeInfo, memberTypeBinding, memberQName, false);
memberElement.setNillable(true);
+ memberElement.setValueAdapter(valueAdapter);
ParticleBinding memberParticle = new ParticleBinding(memberElement, 0, 1, isCol);
propertyGroup.addParticle(memberParticle);
-
- if(trace)
+
+ if (trace)
log.trace("added " + memberParticle + " to " + xmlModelGroup.kind() + ", property " + property.getName());
}
@@ -1210,14 +1222,14 @@
if (xmlElements != null)
elements = xmlElements.value();
}
-
+
// A single element not annotated
if (elements == null || elements.length == 0)
elements = new XmlElement[1];
// for now support just one JBossXmlNsPrefix
JBossXmlNsPrefix xmlNsPrefix = property.getUnderlyingAnnotation(JBossXmlNsPrefix.class);
-
+
// Setup a choice
if (elements.length > 1)
{
@@ -1231,21 +1243,21 @@
if (trace)
log.trace("XmlElements seen adding choice for type=" + beanInfo.getName() + " property=" + property.getName());
}
-
+
for (int i = 0; i < elements.length; ++i)
{
XmlElement element = elements[i];
if (trace)
log.trace("Processing " + element + " for type=" + beanInfo.getName() + " property=" + property.getName());
-
+
// Determine the parameters
overrideNamespace = null;
overrideName = null;
boolean nillable = false;
boolean required = false;
-
+
TypeInfo localPropertyType = propertyType;
-
+
if (element != null)
{
overrideNamespace = element.namespace();
@@ -1256,13 +1268,13 @@
if (elementType != XmlElement.DEFAULT.class)
localPropertyType = propertyType.getTypeInfoFactory().getTypeInfo(elementType);
}
-
- if(xmlNsPrefix != null)
+
+ if (xmlNsPrefix != null)
{
overrideNamespace = schemaBinding.getNamespace(xmlNsPrefix.prefix());
- if(overrideNamespace == null)
+ if (overrideNamespace == null)
{
- if(xmlNsPrefix.schemaTargetIfNotMapped())
+ if (xmlNsPrefix.schemaTargetIfNotMapped())
{
overrideNamespace = defaultNamespace;
}
@@ -1272,7 +1284,7 @@
}
}
}
-
+
// Determine the name
QName qName = generateXmlName(property.getName(), elementForm, overrideNamespace, overrideName);
@@ -1291,7 +1303,7 @@
elementTypeBinding.setSchemaBinding(schemaBinding);
elementTypeBinding.setHandler(BuilderParticleHandler.INSTANCE);
ElementBinding elementBinding = createElementBinding(localPropertyType, elementTypeBinding, qName, false);
-
+
// Bind it to the model
ParticleBinding particle = new ParticleBinding(elementBinding, 1, 1, false);
if (required == false)
@@ -1312,7 +1324,7 @@
textHandler = new ValueHandler(property);
elementTypeBinding.setCharactersHandler(textHandler);
}
-
+
// Setup the child model
ChoiceBinding childModel = new ChoiceBinding(schemaBinding);
childModel.setHandler(BuilderParticleHandler.INSTANCE);
@@ -1329,7 +1341,7 @@
TypeBinding childTypeBinding = resolveTypeBinding(childType);
ElementBinding childBinding = createElementBinding(childType, childTypeBinding, childName, false);
childBinding.setNillable(nillable);
-
+
// Bind it to the model
particle = new ParticleBinding(childBinding, child.minOccurs(), child.maxOccurs(), child.unbounded());
particle.setMinOccurs(0);
@@ -1354,7 +1366,7 @@
}
else
groupWildcardHandler = new ChildWildcardHandler(property);
-
+
WildcardBinding wildcard = new WildcardBinding(schemaBinding);
if (groupWildcard.lax())
wildcard.setProcessContents((short) 3); // Lax
@@ -1365,7 +1377,7 @@
particleBinding.setMinOccurs(0);
particleBinding.setMaxOccurs(1);
childModel.addParticle(particleBinding);
-
+
elementTypeBinding.getWildcard().setWildcardHandler(groupWildcardHandler);
}
}
@@ -1388,7 +1400,7 @@
isCol = true;
propertyHandler = new CollectionPropertyHandler(property, propertyType);
ClassInfo typeArg = (ClassInfo) findComponentType(property);
-
+
//if (((ClassInfo) typeArg).getUnderlyingAnnotation(XmlType.class) != null)
if (typeArg != null && typeArg.getUnderlyingAnnotation(JBossXmlModelGroup.class) == null)
{// it may be a model group in which case we don't want to change the type
@@ -1403,12 +1415,12 @@
}
// TODO this shouldn't be here (because localPropertyType should specify an item?)
// this is to support the Descriptions.class -> DescriptionsImpl.class
- else if (localPropertyType.isCollection() && ((ClassInfo)localPropertyType).getUnderlyingAnnotation(XmlType.class) == null)
+ else if (localPropertyType.isCollection() && ((ClassInfo) localPropertyType).getUnderlyingAnnotation(XmlType.class) == null)
{
propertyHandler = new CollectionPropertyHandler(property, localPropertyType);
isCol = true;
- localPropertyType = findComponentType((ClassInfo)localPropertyType);
-
+ localPropertyType = findComponentType((ClassInfo) localPropertyType);
+
// TypeInfo gs = ((ClassInfo) localPropertyType).getGenericSuperclass();
// if (gs instanceof ParameterizedClassInfo)
// {
@@ -1433,24 +1445,37 @@
ParticleBinding particle;
- if(propertyType.isCollection() && property.getUnderlyingAnnotation(XmlElementWrapper.class) != null)
+ if (propertyType.isCollection() && property.getUnderlyingAnnotation(XmlElementWrapper.class) != null)
{
- XmlElementWrapper wrapper = property.getUnderlyingAnnotation(XmlElementWrapper.class);
- String wrapperOverrideNamespace = wrapper.namespace();
- String wrapperOverrideName = wrapper.name();
- boolean wrapperNillable = wrapper.nillable();
+ // support for @XmlElementWrapper
+ // the wrapping element is ignored in this case
+ XmlElementWrapper xmlWrapper = property.getUnderlyingAnnotation(XmlElementWrapper.class);
+ String wrapperNamespace = xmlWrapper.namespace();
+ String wrapperName = xmlWrapper.name();
+ boolean wrapperNillable = xmlWrapper.nillable();
QName childQName = qName;
- qName = generateXmlName(property.getName(), elementForm, wrapperOverrideNamespace, wrapperOverrideName);
+ qName = generateXmlName(property.getName(), elementForm, wrapperNamespace, wrapperName);
- boolean typeIsNew = !typeCache.containsKey(localPropertyType);
- TypeBinding elementTypeBinding = resolveTypeBinding(localPropertyType);
+ boolean typeIsNew = !typeCache.containsKey(propertyType);
- ElementBinding elementBinding = createElementBinding(localPropertyType, elementTypeBinding, qName, false);
- elementBinding.setNillable(wrapperNillable);
- particle = new ParticleBinding(elementBinding, 1, 1, false);
+ TypeBinding wrapperType = new TypeBinding();
+ SequenceBinding seq = new SequenceBinding(schemaBinding);
+ seq.setHandler(BuilderParticleHandler.INSTANCE);
+ particle = new ParticleBinding(seq);
+ wrapperType.setParticle(particle);
+ wrapperType.setHandler(new DefaultElementHandler());
- if(typeIsNew)
+ ElementBinding wrapperElement = createElementBinding(propertyType, wrapperType, qName, false);
+ wrapperElement.setNillable(wrapperNillable);
+ particle = new ParticleBinding(wrapperElement, 1, 1, false);
+ targetGroup.addParticle(particle);
+
+ if(trace)
+ log.trace("Added property " + qName + " for type=" + beanInfo.getName() + " property="
+ + property.getName() + " as a wrapper element");
+
+ if (typeIsNew)
{
// component stuff
ClassInfo typeArg = (ClassInfo) findComponentType(property);
@@ -1466,34 +1491,46 @@
// Bind it to the model
ParticleBinding childParticle = new ParticleBinding(childElement, 0, 1, true);
- elementBinding.getType().addParticle(childParticle);
+ wrapperElement.getType().addParticle(childParticle);
- DefaultElementInterceptor interceptor = ChildCollectionInterceptor.SINGLETON;
- elementBinding.getType().pushInterceptor(childQName, interceptor);
+ beanAdapterFactory.addProperty(childQName, propertyHandler);
+ if (trace)
+ log.trace("Added property " + childQName + " for type=" + beanInfo.getName() + " property="
+ + property.getName() + " handler=" + propertyHandler + " wrapper=" + qName);
}
}
else
{
+ XBValueAdapter valueAdapter = null;
+ XmlJavaTypeAdapter xmlTypeAdapter = property.getUnderlyingAnnotation(XmlJavaTypeAdapter.class);
+ if (xmlTypeAdapter != null)
+ {
+ valueAdapter = new XBValueAdapter(xmlTypeAdapter.value(), propertyType.getTypeInfoFactory());
+ localPropertyType = valueAdapter.getAdaptedType();
+ }
+
TypeBinding elementTypeBinding = resolveTypeBinding(localPropertyType);
ElementBinding elementBinding = createElementBinding(localPropertyType, elementTypeBinding, qName, false);
elementBinding.setNillable(nillable);
-
+ elementBinding.setValueAdapter(valueAdapter);
+
// Bind it to the model
particle = new ParticleBinding(elementBinding, 1, 1, isCol);
if (required == false)
particle.setMinOccurs(0);
- }
- targetGroup.addParticle(particle);
+ targetGroup.addParticle(particle);
- beanAdapterFactory.addProperty(qName, propertyHandler);
- if (trace)
- log.trace("Added property " + qName + " for type=" + beanInfo.getName() + " property=" + property.getName() + " handler=" + propertyHandler);
+ beanAdapterFactory.addProperty(qName, propertyHandler);
+ if (trace)
+ log.trace("Added property " + qName + " for type=" + beanInfo.getName() + " property="
+ + property.getName() + " handler=" + propertyHandler);
+ }
}
}
pop();
}
-
+
// Bind the children
JBossXmlChild[] children = null;
JBossXmlChildren jbossXmlChildren = typeInfo.getUnderlyingAnnotation(JBossXmlChildren.class);
@@ -1505,7 +1542,7 @@
if (jbossXmlChild != null)
children = new JBossXmlChild[] { jbossXmlChild };
}
-
+
if (children != null && children.length > 0)
{
for (JBossXmlChild child : children)
@@ -1515,7 +1552,7 @@
TypeBinding elementTypeBinding = resolveTypeBinding(childType);
ElementBinding elementBinding = createElementBinding(childType, elementTypeBinding, qName, false);
-
+
// Bind it to the model
ParticleBinding particle = new ParticleBinding(elementBinding, child.minOccurs(), child.maxOccurs(), child.unbounded());
model.addParticle(particle);
@@ -1537,7 +1574,7 @@
ModelGroupBinding localModel = model;
TypeInfo wildcardType = wildcardProperty.getType();
TypeInfo type = wildcardType;
-
+
// Setup any new model and determine the wildcard type
if (wildcardType.isArray())
{
@@ -1553,7 +1590,7 @@
if (trace)
log.trace("Wildcard " + wildcardProperty.getName() + " is a collection of type " + type.getName());
}
-
+
XmlAnyElement xmlAnyElement = wildcardProperty.getUnderlyingAnnotation(XmlAnyElement.class);
WildcardBinding wildcard = new WildcardBinding(schemaBinding);
if (xmlAnyElement.lax())
@@ -1567,7 +1604,7 @@
wildcard.setUnresolvedElementHandler(DOMHandler.INSTANCE);
wildcard.setUnresolvedCharactersHandler(DOMHandler.INSTANCE);
}
-
+
// Bind the particle to the model
ParticleBinding particleBinding = new ParticleBinding(wildcard);
particleBinding.setMinOccurs(0);
@@ -1576,13 +1613,13 @@
typeBinding.getWildcard().setWildcardHandler((ParticleHandler) wildcardHandler);
beanAdapterFactory.setWildcardHandler(wildcardHandler);
}
-
+
JBossXmlChildWildcard childWildcard = typeInfo.getUnderlyingAnnotation(JBossXmlChildWildcard.class);
if (childWildcard != null)
{
if (wildcardProperty != null)
throw new RuntimeException("Cannot have both @JBossXmlChildWildcard and @XmlAnyElement");
-
+
ParticleHandler childWildcardHandler = null;
if (typeInfo.isCollection())
{
@@ -1607,10 +1644,10 @@
particleBinding.setMinOccurs(0);
particleBinding.setMaxOccurs(1);
model.addParticle(particleBinding);
-
+
typeBinding.getWildcard().setWildcardHandler(childWildcardHandler);
}
-
+
if (trace)
log.trace("Created type=" + typeInfo.getName() + " typeBinding=" + typeBinding + " rootType=" + root);
@@ -1619,7 +1656,7 @@
schemaBinding.addType(typeBinding);
else
typeBinding.setSchemaBinding(schemaBinding);
-
+
return typeBinding;
}
@@ -1743,22 +1780,22 @@
}
throw new RuntimeException(message.toString(), t);
}
-
+
/** A location */
private class Location
{
/** The type info */
TypeInfo typeInfo;
-
+
/** The join point */
String joinpoint;
-
+
Location(TypeInfo typeInfo, String joinpoint)
{
this.typeInfo = typeInfo;
this.joinpoint = joinpoint;
}
-
+
public void append(StringBuilder builder)
{
builder.append("at ");
@@ -1767,7 +1804,7 @@
builder.append('.').append(joinpoint);
}
}
-
+
// the following is available in the latest org.jboss.reflect package
// but doesn't build at the moment...
private TypeInfo findComponentType(PropertyInfo prop)
@@ -1779,15 +1816,15 @@
{
return findActualType(classInfo, classInfo.getType(), java.util.Collection.class, 0);
}
-
+
private TypeInfo findActualType(PropertyInfo property, Class reference, int parameter)
{
MethodInfo getter = property.getGetter();
- if(getter == null)
+ if (getter == null)
{
throw new IllegalStateException("Expected a getter for " + property.getName() + " in " + property.getBeanInfo().getName());
}
-
+
Method m;
try
{
@@ -1798,7 +1835,7 @@
throw new IllegalStateException("Expected a getter for " + property.getName() + " in " + property.getBeanInfo().getName());
}
- return findActualType((ClassInfo)property.getType(), m.getGenericReturnType(), reference, parameter);
+ return findActualType((ClassInfo) property.getType(), m.getGenericReturnType(), reference, parameter);
}
protected TypeInfo findActualType(ClassInfo classInfo, Type genericType, Class reference, int parameter)
@@ -1809,10 +1846,10 @@
TypeVariable typeVariable = (TypeVariable) result;
result = typeVariable.getBounds()[0];
}
-
+
return classInfo.getTypeInfoFactory().getTypeInfo(result);
}
-
+
protected static Type locateActualType(Class reference, int parameter, Class clazz, Type type)
{
if (reference.equals(clazz))
@@ -1828,10 +1865,10 @@
return parameterized.getActualTypeArguments()[parameter];
}
}
-
+
Type[] interfaces = clazz.getGenericInterfaces();
for (Type intf : interfaces)
- {
+ {
Class interfaceClass;
if (intf instanceof Class)
{
@@ -1883,4 +1920,44 @@
// Not generic
return Object.class;
}
+
+ private static class XBValueAdapter implements ValueAdapter
+ {
+ private final XmlAdapter xmlAdapter;
+
+ private final TypeInfo adaptedType;
+
+ public XBValueAdapter(Class<? extends XmlAdapter> adapterImplClass, TypeInfoFactory factory)
+ {
+ try
+ {
+ this.xmlAdapter = adapterImplClass.newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("Failed to create an instance of " + adapterImplClass.getName(), e);
+ }
+
+ ClassInfo adapterImplInfo = (ClassInfo) factory.getTypeInfo(adapterImplClass);
+ ClassInfo xmlAdapterInfo = adapterImplInfo.getGenericSuperclass();
+ adaptedType = xmlAdapterInfo.getActualTypeArguments()[0];
+ }
+
+ public TypeInfo getAdaptedType()
+ {
+ return adaptedType;
+ }
+
+ public Object cast(Object o, Class c)
+ {
+ try
+ {
+ return xmlAdapter.unmarshal(o);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("Failed to adapt value " + o + " to type " + c, e);
+ }
+ }
+ }
}
More information about the jboss-svn-commits
mailing list