//-- Handle Collections
isCollection = (isCollection || isCollection(type));
TypeInfo typeInfo = null;
CollectionHandler colHandler = null;
//-- If the type is a collection and there is no add method,
//-- then we obtain a CollectionHandler
if (isCollection && (methodSet.add == null)) {
try {
colHandler = CollectionHandlers.getHandler(type);
}
catch(MappingException mx) {
//-- No collection handler available,
//-- proceed anyway...
}
//-- Find component type
if (type.isArray()) {
//-- Byte arrays are handled as a special case
//-- so don't use CollectionHandler
if (type.getComponentType() == Byte.TYPE) {
colHandler = null;
}
else type = type.getComponentType();
}
}
typeInfo = new TypeInfo(type, null, null, false, null, colHandler);
//-- Create FieldHandler first, before the XMLFieldDescriptor
//-- in case we need to use a custom handler
FieldHandler handler = null;
boolean customHandler = false;
try {
handler = new FieldHandlerImpl(methodSet.fieldName,
null,
null,
methodSet.get,
methodSet.set,
typeInfo);
//-- clean up
if (methodSet.add != null)
((FieldHandlerImpl)handler).setAddMethod(methodSet.add);
if (methodSet.create != null)
((FieldHandlerImpl)handler).setCreateMethod(methodSet.create);
//-- handle Hashtable/Map
if (isCollection && _saveMapKeys && isMapCollection(type)) {
((FieldHandlerImpl)handler).setConvertFrom(new IdentityConvertor());
}
//-- look for GeneralizedFieldHandler
FieldHandlerFactory factory = getHandlerFactory(type);
if (factory != null) {
GeneralizedFieldHandler gfh = factory.createFieldHandler(type);
if (gfh != null) {
gfh.setFieldHandler(handler);
handler = gfh;
customHandler = true;
//-- swap type with the type specified by the
//-- custom field handler
if (gfh.getFieldType() != null) {
type = gfh.getFieldType();
}
}
}
}
catch (MappingException mx) {
throw new MarshalException(mx);
}
XMLFieldDescriptorImpl fieldDesc
= createFieldDescriptor(type, methodSet.fieldName, xmlName);
if (isCollection) {
fieldDesc.setMultivalued(true);
fieldDesc.setNodeType(NodeType.Element);
}
//-- check for instances of java.util.Date
if (java.util.Date.class.isAssignableFrom(type)) {
//handler = new DateFieldHandler(handler);
if (!customHandler) {
dateDescriptors.add(fieldDesc);
}
}
fieldDesc.setHandler(handler);
//-- enable use parent namespace if explicit one doesn't exist
fieldDesc.setUseParentsNamespace(true);
//-- Wrap collections?
if (isCollection && _wrapCollectionsInContainer) {
String fieldName = COLLECTION_WRAPPER_PREFIX + methodSet.fieldName;
//-- If we have a field 'c' that is a collection and
//-- we want to wrap that field in an element <e>, we
//-- need to create a field descriptor for
//-- an object that represents the element <e> and
//-- acts as a go-between from the parent of 'c'
//-- denoted as P(c) and 'c' itself
//
// object model: P(c) -> c
// xml : <p><e><c></e><p>
//-- Make new class descriptor for the field that
//-- will represent the container element <e>
Class cType = ContainerElement.class;
XMLClassDescriptorImpl containerClassDesc = new XMLClassDescriptorImpl(cType);
//-- add the field descriptor to our new class descriptor
containerClassDesc.addFieldDescriptor(fieldDesc);
//-- nullify xmlName so that auto-naming will be enabled,
//-- we can't do this in the constructor because
//-- XMLFieldDescriptorImpl will create a default one.
fieldDesc.setXMLName(null);
fieldDesc.setMatches("*");
//-- wrap the field handler in a special container field
//-- handler that will actually do the delegation work
FieldHandler cHandler = new ContainerFieldHandler(handler);
fieldDesc.setHandler(cHandler);
fieldDesc = createFieldDescriptor(cType, fieldName, xmlName);
fieldDesc.setClassDescriptor(containerClassDesc);
fieldDesc.setHandler(cHandler);
//-- enable use parent namespace if explicit one doesn't exist
fieldDesc.setUseParentsNamespace(true);
}
//-- add FieldDescriptor to ClassDescriptor
classDesc.addFieldDescriptor(fieldDesc);
} //-- end of method loop
//-- If we didn't find any methods we can try
//-- direct field access
if (methodCount == 0) {
Field[] fields = c.getFields();
Hashtable descriptors = new Hashtable();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Class owner = field.getDeclaringClass();
//-- ignore fields from super-class, that will be
//-- introspected separately, if necessary
if (owner != c) {
//-- if declaring class is anything but
//-- an interface, than just continue,
//-- the field comes from a super class
//-- (e.g. java.lang.Object)
if (!owner.isInterface()) continue;
//-- owner is an interface, is it an
//-- interface this class implements
//-- or a parent class?
if (interfaces.length > 0) {
boolean found = false;
for (int count = 0; count < interfaces.length; count++) {
if (interfaces[count] == owner) {
found = true;
break;
}
}
if (!found) continue;
}
}
//-- make sure field is not transient or static final
int modifiers = field.getModifiers();
if (Modifier.isTransient(modifiers)) continue;
if (Modifier.isFinal(modifiers) &&
Modifier.isStatic(modifiers))
continue;
Class type = field.getType();
if (!isDescriptable(type)) continue;
//-- Built-in support for JDK 1.1 Collections
//-- we need to a pluggable interface for
//-- JDK 1.2+
boolean isCollection = isCollection(type);
TypeInfo typeInfo = null;
CollectionHandler colHandler = null;
//-- If the type is a collection and there is no add method,
//-- then we obtain a CollectionHandler
if (isCollection) {