protected FieldDescriptor createFieldDesc( Class javaClass, FieldMapping fieldMap )
throws MappingException
{
FieldDescriptor fieldDesc;
CollectionType colType = fieldMap.getCollection();
String xmlName = null;
NodeType nodeType = null;
String match = null;
XMLFieldDescriptorImpl xmlDesc;
boolean isReference = false;
boolean isXMLTransient = false;
//-- handle special case for HashMap/Hashtable
if ((fieldMap.getType() == null) && (colType != null)) {
if ((colType == CollectionType.HASHTABLE) ||
(colType == CollectionType.MAP))
{
fieldMap.setType(MapItem.class.getName());
}
}
// Create an XML field descriptor
fieldDesc = super.createFieldDesc( javaClass, fieldMap );
BindXml xml = fieldMap.getBindXml();
boolean deriveNameByClass = false;
if (xml != null) {
//-- xml name
xmlName = xml.getName();
//-- node type
if ( xml.getNode() != null )
nodeType = NodeType.getNodeType( xml.getNode().toString() );
//-- matches
match = xml.getMatches();
//-- reference
isReference = xml.getReference();
//-- XML transient
isXMLTransient = xml.getTransient();
//-- autonaming
BindXmlAutoNamingType autoName = xml.getAutoNaming();
if (autoName != null) {
deriveNameByClass = (autoName == BindXmlAutoNamingType.DERIVEBYCLASS);
}
}
//-- transient
//-- XXXX -> if it's transient we probably shouldn't do all
//-- XXXX -> the unecessary work
isXMLTransient = isXMLTransient || fieldDesc.isTransient();
//--
//-- handle QName for xmlName
String namespace = null;
if ((xmlName != null) && (xmlName.length() > 0)){
if (xmlName.charAt(0) == '{') {
int idx = xmlName.indexOf('}');
if (idx < 0) {
throw new MappingException("Invalid QName: " + xmlName);
}
namespace = xmlName.substring(1, idx);
xmlName = xmlName.substring(idx+1);
}
else if (xmlName.startsWith(XML_PREFIX)) {
namespace = Namespaces.XML_NAMESPACE;
xmlName = xmlName.substring(4);
}
}
if (nodeType == null) {
if (isPrimitive(javaClass))
nodeType = _primitiveNodeType;
else
nodeType = NodeType.Element;
}
//-- Create XML name if necessary. Note if name is to be derived
//-- by class..we just make sure we set the name to null...
//-- the Marshaller does this during runtime. This allows
//-- Collections to be handled properly.
if ((!deriveNameByClass) && ((xmlName == null) && (match == null)))
{
xmlName = _naming.toXMLName( fieldDesc.getFieldName() );
match = xmlName + ' ' + fieldDesc.getFieldName();
}
xmlDesc = new XMLFieldDescriptorImpl( fieldDesc, xmlName, nodeType, _primitiveNodeType );
//-- transient?
xmlDesc.setTransient(isXMLTransient);
//--set a default fieldValidator
xmlDesc.setValidator(new FieldValidator());
//-- enable use parent namespace if explicit one doesn't exist
xmlDesc.setUseParentsNamespace(true);
//-- If deriveNameByClass we need to reset the name to
//-- null because XMLFieldDescriptorImpl tries to be smart
//-- and automatically creates the name.
if (deriveNameByClass) {
xmlDesc.setXMLName(null);
}
//-- namespace
if (namespace != null) {
xmlDesc.setNameSpaceURI(namespace);
}
//-- matches
if (match != null) {
xmlDesc.setMatches(match);
//-- special fix for xml-name since XMLFieldDescriptorImpl
//-- will create a default name based off the field name
if (xmlName == null) xmlDesc.setXMLName(null);
}
//-- reference
xmlDesc.setReference(isReference);
xmlDesc.setContainer(fieldMap.getContainer());
if (xml != null) {
//-- has class descriptor for type specified
if (xml.getClassMapping() != null) {
ClassDescriptor cd = createDescriptor(xml.getClassMapping());
xmlDesc.setClassDescriptor((XMLClassDescriptor)cd);
}
//-- has location path?
if (xml.getLocation() != null) {
xmlDesc.setLocationPath(xml.getLocation());
}
//is the value type needs specific handling
//such as QName or NCName support?
String xmlType = xml.getType();
xmlDesc.setSchemaType(xmlType);
xmlDesc.setQNamePrefix(xml.getQNamePrefix());
TypeValidator validator = null;
if (NCNAME.equals(xmlType)) {
validator = new NameValidator(NameValidator.NCNAME);
xmlDesc.setValidator(new FieldValidator(validator));
}
//-- special properties?
Property[] props = xml.getProperty();
if ((props != null) && (props.length > 0)) {
for (int pIdx = 0; pIdx < props.length; pIdx++) {
Property prop = props[pIdx];
xmlDesc.setProperty(prop.getName(), prop.getValue());
}
}
}
//-- Get collection type
if (colType == null) {
//-- just in case user forgot to use collection="..."
//-- in the mapping file
Class type = fieldDesc.getFieldType();
if (CollectionHandlers.hasHandler(type)) {
String typeName = CollectionHandlers.getCollectionName(type);
colType = CollectionType.valueOf(typeName);
}
}