if (isAtEndElement(xmlReader, entityName)) {
break;
}
final LocalElement childElement = getElement(xmlReader);
final Property p = entity.getProperty(childElement.getName());
log.debug(">>> Importing property " + p.getName());
// TODO: make this option controlled
final boolean isNotImportableProperty = p.isTransient(bob)
|| (p.isAuditInfo() && !isOptionImportAuditInfo()) || p.isInactive();
if (isNotImportableProperty) {
log.debug("Property " + p + " is inactive, transient or auditinfo, ignoring it");
skipElement(xmlReader);
continue;
}
// ignore the id properties as they are already set, or should
// not be set
if (p.isId()) {
skipElement(xmlReader);
continue;
}
if (p.isOneToMany()) {
throw new EntityXMLException("This XML converter can not handle one-to-many properties");
}
final Object currentValue = bob.get(p.getName());
// do the primitive values
if (p.isPrimitive()) {
// NOTE: I noticed a difference between running from Eclipse and from the commandline
// after some searching, there is a jar file wstx-asl-3.0.2.jar used in
// src-db/database/lib
// which provides the woodstox XMLStreamReader. From the commandline the xerces
// XMLStreamReader
// is used. They differ in the handling of the getText method in handling entities. For
// example the following text: <text>Tom&Jerry</text> now assume that the pointer is
// at the content of the text tag, and you do getText, then woodstox will return Tom&Jerry
// while xerces will return Tom, this because the & is an entity which is a separate
// event.
// below we use the getElementText which works correctly in both cases apparently
// element value, note that getElementText means that it is not required anymore
// to go to element end, that is done by the xmlReader
final String elementText = xmlReader.getElementText();
Object newValue = XMLTypeConverter.getInstance().fromXML(p.getPrimitiveType(),
elementText);
// correct the value
newValue = replaceValue(bob, p, newValue);
log.debug("Primitive property with value " + newValue);
// only update if changed
if ((currentValue != null && newValue == null)
|| (currentValue == null && newValue != null)
|| (currentValue != null && newValue != null && !currentValue.equals(newValue))) {
log.debug("Value changed setting it");
if (!preventRealUpdate) {
bob.set(p.getName(), newValue);
updated = true;
}
}
} else {
Check.isTrue(!p.isOneToMany(), "One to many property not allowed here");
// never update the org or client through xml!
final boolean clientUpdate = bob instanceof ClientEnabled
&& p.getName().equals(Organization.PROPERTY_CLIENT);
final boolean orgUpdate = bob instanceof OrganizationEnabled
&& p.getName().equals(Client.PROPERTY_ORGANIZATION);
if (!isOptionClientImport() && currentValue != null && (clientUpdate || orgUpdate)) {
skipElement(xmlReader);
continue;
}
// determine the referenced entity
Object newValue;
// handle null value
if (childElement.getAttributes().get(XMLConstants.ID_ATTRIBUTE) == null) {
newValue = null;
} else {
// get the info and resolve the reference
final String refId = childElement.getAttributes().get(XMLConstants.ID_ATTRIBUTE);
final String refEntityName = p.getTargetEntity().getName();
newValue = resolve(refEntityName, refId, true);
}
newValue = replaceValue(bob, p, newValue);
final boolean hasChanged = (currentValue == null && newValue != null)
|| (currentValue != null && newValue != null && !currentValue.equals(newValue));
if (hasChanged) {
log.debug("Setting value " + newValue);
if (!preventRealUpdate) {
bob.set(p.getName(), newValue);
updated = true;
}
}
checkEndElement(xmlReader, childElement.getName());
}