String message = "Internal context or class descriptor resolver within are not valid";
LOG.warn(message);
throw new IllegalStateException(message);
}
// Create the class descriptor.
XMLClassDescriptorAdapter xmlClassDesc = new XMLClassDescriptorAdapter();
// Introspection and package level stuff needs to be disabled !!
getInternalContext().getXMLClassDescriptorResolver().setUseIntrospection(false);
getInternalContext().getXMLClassDescriptorResolver().setLoadPackageMappings(false);
try {
if (classMapping.getAutoComplete()) {
if ((classMapping.getMapTo() == null)
&& ((classMapping.getClassChoice() == null)
|| (classMapping.getClassChoice().getFieldMappingCount() == 0))
&& (classMapping.getIdentityCount() == 0)) {
// If we make it here we simply try to load a compiled mapping
try {
ClassDescriptor clsDesc =
getInternalContext()
.getXMLClassDescriptorResolver().resolve(classMapping.getName());
if (clsDesc != null) { return clsDesc; }
} catch (ResolverException e) {
if (LOG.isDebugEnabled()) {
String message =
new StringBuffer().append("Ignoring exception: ").append(e)
.append(" at resolving: ").append(classMapping.getName()).toString();
LOG.debug(message);
}
}
}
}
// Obtain the Java class.
Class javaClass = resolveType(classMapping.getName());
if (classMapping.getVerifyConstructable()) {
if (!Types.isConstructable(javaClass, true)) {
throw new MappingException(
"mapping.classNotConstructable", javaClass.getName());
}
}
xmlClassDesc.setJavaClass(javaClass);
// Obtain XML name.
String xmlName;
MapTo mapTo = classMapping.getMapTo();
if ((mapTo != null) && (mapTo.getXml() != null)) {
xmlName = mapTo.getXml();
} else {
String clsName = getInternalContext().getJavaNaming().getClassName(javaClass);
xmlName = getInternalContext().getXMLNaming().toXMLName(clsName);
}
xmlClassDesc.setXMLName(xmlName);
// If this class extends another class, we need to obtain the extended
// class and make sure this class indeed extends it.
ClassDescriptor extDesc = getExtended(classMapping, javaClass);
xmlClassDesc.setExtends((XMLClassDescriptor) extDesc);
// Create all field descriptors.
FieldDescriptorImpl[] allFields = createFieldDescriptors(classMapping, javaClass);
// Make sure there are no two fields with the same name.
checkFieldNameDuplicates(allFields, javaClass);
// Identify identity and normal fields. Note that order must be preserved.
List fieldList = new ArrayList(allFields.length);
List idList = new ArrayList();
if (extDesc == null) {
// Sort fields into 2 lists based on identity definition of field.
for (int i = 0; i < allFields.length; i++) {
if (!allFields[i].isIdentity()) {
fieldList.add(allFields[i]);
} else {
idList.add(allFields[i]);
}
}
if (idList.size() == 0) {
// Found no identities based on identity definition of field.
// Try to find identities based on identity definition on class.
String[] idNames = classMapping.getIdentity();
FieldDescriptor identity;
for (int i = 0; i < idNames.length; i++) {
identity = findIdentityByName(fieldList, idNames[i], javaClass);
if (identity != null) {
idList.add(identity);
} else {
throw new MappingException("mapping.identityMissing",
idNames[i], javaClass.getName());
}
}
}
} else {
// Add all fields of extending class to field list.
for (int i = 0; i < allFields.length; i++) { fieldList.add(allFields[i]); }
// Add identity of extended class to identity list.
if (extDesc.getIdentity() != null) { idList.add(extDesc.getIdentity()); }
// Search redefined identities in extending class.
FieldDescriptor identity;
for (int i = 0; i < idList.size(); i++) {
String idname = ((FieldDescriptor) idList.get(i)).getFieldName();
identity = findIdentityByName(fieldList, idname, javaClass);
if (identity != null) { idList.set(i, identity); }
}
}
FieldDescriptor xmlId = null;
if (idList.size() != 0) { xmlId = (FieldDescriptor) idList.get(0); }
if (xmlId != null) { xmlClassDesc.setIdentity((XMLFieldDescriptorImpl) xmlId); }
for (int i = 0; i < fieldList.size(); i++) {
FieldDescriptor fieldDesc = (FieldDescriptor) fieldList.get(i);
if (fieldDesc != null) {
xmlClassDesc.addFieldDescriptor((XMLFieldDescriptorImpl) fieldDesc);
}
}
if (classMapping.getAutoComplete()) {
XMLClassDescriptor referenceDesc = null;
Class type = xmlClassDesc.getJavaClass();
//-- check compiled descriptors
if ((getInternalContext() == null)
|| (getInternalContext().getXMLClassDescriptorResolver() == null)) {
String message = "Internal context or class descriptor resolver within are not valid";
LOG.warn(message);
throw new IllegalStateException(message);
}
try {
referenceDesc = (XMLClassDescriptor) getInternalContext().getXMLClassDescriptorResolver().resolve(type);
} catch (ResolverException rx) {
throw new MappingException(rx);
}
if (referenceDesc == null) {
Introspector introspector = getInternalContext().getIntrospector();
try {
referenceDesc = introspector.generateClassDescriptor(type);
if (classMapping.getExtends() != null) {
//-- clear parent from introspected descriptor since
//-- a mapping was provided in the mapping file
((XMLClassDescriptorImpl) referenceDesc).setExtends(null);
}
} catch (MarshalException mx) {
String error = "unable to introspect class '" +
type.getName() + "' for auto-complete: ";
throw new MappingException(error + mx.getMessage());
}
}
//-- check for identity
String identity = "";
if (classMapping.getIdentityCount() > 0) {
identity = classMapping.getIdentity(0);
}
FieldDescriptor[] xmlFields2 = xmlClassDesc.getFields();
// Attributes
XMLFieldDescriptor[] introFields = referenceDesc.getAttributeDescriptors();
for (int i = 0; i < introFields.length; ++i) {
if (!isMatchFieldName(xmlFields2, introFields[i].getFieldName())) {
// If there is no field with this name, we can add it
if (introFields[i].getFieldName().equals(identity)) {
xmlClassDesc.setIdentity(introFields[i]);
}
else {
xmlClassDesc.addFieldDescriptor(introFields[i]);
}
}
}
// Elements
introFields = referenceDesc.getElementDescriptors();
for (int i = 0; i < introFields.length; ++i) {
if (!isMatchFieldName(xmlFields2, introFields[i].getFieldName())) {
// If there is no field with this name, we can add it
if (introFields[i].getFieldName().equals(identity)) {
xmlClassDesc.setIdentity(introFields[i]);
}
else {
xmlClassDesc.addFieldDescriptor(introFields[i]);
}
}
}
// Content
XMLFieldDescriptor field = referenceDesc.getContentDescriptor();
if (field != null) {
if (!isMatchFieldName(xmlFields2, field.getFieldName())) {
// If there is no field with this name, we can add
xmlClassDesc.addFieldDescriptor(field);
}
}
}
// Copy ns-uri + ns-prefix + element-definition
if (mapTo != null) {
xmlClassDesc.setNameSpacePrefix(mapTo.getNsPrefix());
xmlClassDesc.setNameSpaceURI(mapTo.getNsUri());
xmlClassDesc.setElementDefinition(mapTo.getElementDefinition());
}
}
finally {
getInternalContext().getXMLClassDescriptorResolver().setUseIntrospection(true);
getInternalContext().getXMLClassDescriptorResolver().setLoadPackageMappings(true);