use of org.jaffa.flexfields.IFlexFields in project jaffa-framework by jaffa-projects.
the class TransformerUtils method updateBeanData.
static void updateBeanData(String path, GraphDataObject source, UOW uow, ITransformationHandler handler, GraphMapping mapping, IPersistent domainObject, DataTransformer.Mode mode, GraphDataObject newGraph) throws InstantiationException, IllegalAccessException, InvocationTargetException, ApplicationExceptions, FrameworkException {
try {
// No need to invoke it during CLONING/MASS_UPDATE as well, since the source object should be unmodified
if (mode != DataTransformer.Mode.VALIDATE_ONLY && mode != DataTransformer.Mode.CLONE && mode != DataTransformer.Mode.MASS_UPDATE)
source.validate();
List<ITransformationHandler> handlers = null;
if (handler != null) {
handlers = handler.getTransformationHandlers();
}
// Ensure the domain object has not been modified
domainObjectChangedTest(path, source, mapping, domainObject);
// Stamp the UOW on the domain object to avoid creation of separate UOWs during foreign-key validations
if (domainObject.getUOW() == null)
domainObject.setUOW(uow);
// Reflect ProcessEventGraphs from newGraph to source - This will handle Pending/Warning Events during a clone/mass update
if (newGraph != null && newGraph.getProcessEventGraphs() != null)
source.setProcessEventGraphs(newGraph.getProcessEventGraphs());
// Fire 'startBean' handler
if (mode != DataTransformer.Mode.VALIDATE_ONLY && handlers != null) {
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.startBean(path, source, domainObject);
}
}
// Reflect all normal fields
for (Iterator it = mapping.getFields().iterator(); it.hasNext(); ) {
String field = (String) it.next();
// ignore read-only fields
if (mapping.isReadOnly(field))
continue;
// values from the newGraph take precedence in CLONE/MASS_UPDATE mode
if (mode == DataTransformer.Mode.CLONE) {
// ignore dirty-read fields, and no-cloning fields unless a value is passed in the newGraph
if (field.equals(mapping.getDirtyReadDataFieldName()) || (mapping.isNoCloning(field) && (newGraph == null || !newGraph.hasChanged(field))))
continue;
Object value = getProperty(mapping.getDataFieldDescriptor(field), newGraph != null && newGraph.hasChanged(field) ? newGraph : source);
updateProperty(mapping.getDomainFieldDescriptor(field), value, domainObject);
} else if (mode == DataTransformer.Mode.MASS_UPDATE) {
if (newGraph != null && newGraph.hasChanged(field)) {
Object value = getProperty(mapping.getDataFieldDescriptor(field), newGraph);
updateProperty(mapping.getDomainFieldDescriptor(field), value, domainObject);
}
} else {
Object value = getProperty(mapping.getDataFieldDescriptor(field), source);
if ((!domainObject.isDatabaseOccurence() && value != null) || source.hasChanged(field))
updateProperty(mapping.getDomainFieldDescriptor(field), value, domainObject);
}
}
// Update flex fields
if (source instanceof IFlexFields && domainObject instanceof IFlexFields) {
if (log.isDebugEnabled())
log.debug("Updating flex fields for " + path);
FlexBean sFlexBean = ((IFlexFields) source).getFlexBean();
FlexBean tFlexBean = ((IFlexFields) domainObject).getFlexBean();
if (sFlexBean != null && tFlexBean != null) {
for (DynaProperty flexProperty : tFlexBean.getDynaClass().getDynaProperties()) {
String name = flexProperty.getName();
// values from the newGraph take precedence in CLONE/MASS_UPDATE mode
if (mode == DataTransformer.Mode.CLONE) {
FlexBean nFlexBean = newGraph != null && newGraph instanceof IFlexFields ? ((IFlexFields) newGraph).getFlexBean() : null;
Object value = nFlexBean != null && nFlexBean.hasChanged(name) ? nFlexBean.get(name) : sFlexBean.get(name);
if (value != null)
tFlexBean.set(name, value);
} else if (mode == DataTransformer.Mode.MASS_UPDATE) {
FlexBean nFlexBean = newGraph != null && newGraph instanceof IFlexFields ? ((IFlexFields) newGraph).getFlexBean() : null;
if (nFlexBean != null && nFlexBean.hasChanged(name)) {
Object value = nFlexBean.get(name);
tFlexBean.set(name, value);
}
} else {
if (sFlexBean.hasChanged(name)) {
Object value = sFlexBean.get(name);
if (log.isDebugEnabled())
log.debug("Update flex field '" + name + '=' + value + "' on object '" + domainObject.getClass().getName() + '\'');
tFlexBean.set(name, value);
} else {
if (log.isDebugEnabled())
log.debug("Flex field '" + name + " has not changed on object " + source.getClass().getName());
}
}
}
}
}
// Reflect any foreign keys
for (Iterator it = mapping.getForeignFields().iterator(); it.hasNext(); ) {
String field = (String) it.next();
// ignore read-only fields
if (mapping.isReadOnly(field))
continue;
// It is possible that the foreign object may get resused, and only its fields may have been changed.
// Hence also invoke the hasChanged() method on the foreign object itself
Object value = null;
boolean hasChanged = false;
if (mode == DataTransformer.Mode.CLONE) {
// ignore dirty-read fields, and no-cloning fields unless a value is passed in the newGraph
if (field.equals(mapping.getDirtyReadDataFieldName()) || (mapping.isNoCloning(field) && (newGraph == null || !newGraph.hasChanged(field))))
continue;
value = getProperty(mapping.getDataFieldDescriptor(field), newGraph != null && newGraph.hasChanged(field) ? newGraph : source);
hasChanged = value != null;
} else if (mode == DataTransformer.Mode.MASS_UPDATE) {
if (newGraph != null && newGraph.hasChanged(field)) {
value = getProperty(mapping.getDataFieldDescriptor(field), newGraph);
hasChanged = true;
}
} else {
value = getProperty(mapping.getDataFieldDescriptor(field), source);
hasChanged = (!domainObject.isDatabaseOccurence() && value != null) || source.hasChanged(field);
}
if (!hasChanged && value != null && value instanceof GraphDataObject)
hasChanged = ((GraphDataObject) value).hasChanged();
if (hasChanged) {
// need to map foreign keys back
List targetKeys = mapping.getForeignKeys(field);
GraphMapping fMapping = MappingFactory.getInstance(mapping.getDataFieldDescriptor(field).getPropertyType());
Set sourceKeys = fMapping.getKeyFields();
int i = 0;
for (Iterator i2 = sourceKeys.iterator(); i2.hasNext(); i++) {
String sourceFld = (String) i2.next();
String targetFld = (String) targetKeys.get(i);
if (log.isDebugEnabled())
log.debug("Copy Foreign Key Field from " + sourceFld + " to " + targetFld);
if (value == null) {
// ForeignGraph is null. Null out the foreign-key
updateProperty(mapping.getRealDomainFieldDescriptor(targetFld), null, domainObject);
} else {
// Obtain the key-field from the ForeignGraph
Object value2 = getProperty(fMapping.getDataFieldDescriptor(sourceFld), value);
// The check is not required while cloning
if (mode == DataTransformer.Mode.CLONE || !(value instanceof GraphDataObject) || ((GraphDataObject) value).hasChanged(sourceFld))
updateProperty(mapping.getRealDomainFieldDescriptor(targetFld), value2, domainObject);
}
}
// Invoke the getter on the domain. An exception will be raised if the foreign-key is invalid
if (log.isDebugEnabled())
log.debug("Performing validation on the domain object for the foreign object " + mapping.getDomainFieldName(field));
PropertyDescriptor pd = mapping.getDomainFieldDescriptor(field);
if (pd != null && pd.getReadMethod() != null) {
Method m = pd.getReadMethod();
if (!m.isAccessible())
m.setAccessible(true);
m.invoke(domainObject, (Object[]) null);
}
}
}
// Store Record
if (mode == DataTransformer.Mode.VALIDATE_ONLY) {
if (log.isDebugEnabled())
log.debug("Domain object will not be persisted during prevalidation. Invoking the prevalidateBean handler");
if (handlers != null) {
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.prevalidateBean(path, source, domainObject);
}
}
} else if (domainObject.isDatabaseOccurence()) {
if (log.isDebugEnabled())
log.debug("UOW.Update Domain Object");
// Fire 'startBeanUpdate' handler
if (handlers != null) {
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.startBeanUpdate(path, source, domainObject);
}
}
if (domainObject.isModified()) {
uow.update(domainObject);
if (handlers != null) {
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.setChangeDone(true);
}
}
}
// Fire 'endBeanUpdate' handler
if (handlers != null) {
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.endBeanUpdate(path, source, domainObject);
}
}
} else {
if (handlers != null && mode == DataTransformer.Mode.CLONE) {
if (log.isDebugEnabled()) {
log.debug("Invoke startBeanClone");
}
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.startBeanClone(path, source, domainObject, newGraph);
}
} else if (handlers != null && mode == DataTransformer.Mode.MASS_UPDATE) {
if (log.isDebugEnabled()) {
log.debug("Invoke startBeanMassUpdate");
}
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.startBeanMassUpdate(path, source, domainObject, newGraph);
}
}
if (log.isDebugEnabled())
log.debug("UOW.Add Domain Object");
// Fire 'startBeanAdd' handler
if (handlers != null) {
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.startBeanAdd(path, source, domainObject);
}
}
uow.add(domainObject);
if (handlers != null) {
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.setChangeDone(true);
}
}
// Fire 'endBeanAdd' handler
if (handlers != null) {
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.endBeanAdd(path, source, domainObject);
}
}
if (handlers != null && mode == DataTransformer.Mode.CLONE) {
if (log.isDebugEnabled()) {
log.debug("Invoke endBeanClone");
}
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.endBeanClone(path, source, domainObject, newGraph);
}
} else if (handlers != null && mode == DataTransformer.Mode.MASS_UPDATE) {
if (log.isDebugEnabled()) {
log.debug("Invoke endBeanMassUpdate");
}
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.endBeanMassUpdate(path, source, domainObject, newGraph);
}
}
}
// Reflect any related objects
for (Iterator it = mapping.getRelatedFields().iterator(); it.hasNext(); ) {
String field = (String) it.next();
if (mapping.isReadOnly(field))
continue;
Object value = null;
if (mode == DataTransformer.Mode.CLONE) {
// ignore no-cloning fields unless a value is passed in the newGraph
if (mapping.isNoCloning(field) && (newGraph == null || !newGraph.hasChanged(field)))
continue;
value = getProperty(mapping.getDataFieldDescriptor(field), newGraph != null && newGraph.hasChanged(field) ? newGraph : source);
} else if (mode == DataTransformer.Mode.MASS_UPDATE) {
if (newGraph != null && newGraph.hasChanged(field))
value = getProperty(mapping.getDataFieldDescriptor(field), newGraph);
} else
value = getProperty(mapping.getDataFieldDescriptor(field), source);
if (value != null) {
if (value.getClass().isArray()) {
// The related field is an array of objects (one-to-many)
Object[] values = (Object[]) value;
for (int i = 0; i < values.length; i++) {
// Assumes its a DAO....what else could it be?
GraphDataObject dao = (GraphDataObject) values[i];
if (dao != null) {
if (dao.getDeleteObject() != null && dao.getDeleteObject()) {
if (mode == DataTransformer.Mode.VALIDATE_ONLY) {
if (log.isDebugEnabled())
log.debug("The 'deleteObject' property is true. No prevalidations will be performed for the childBean.");
} else {
if (log.isDebugEnabled())
log.debug("The 'deleteObject' property is true. Invoking deleteChildBean()");
deleteChildBean(path + '.' + field + '[' + i + ']', dao, uow, handler, domainObject, mapping, field);
}
} else {
Object newValue = newGraph != null ? getProperty(mapping.getDataFieldDescriptor(field), newGraph) : null;
GraphDataObject newDao = newValue != null && ((GraphDataObject[]) newValue).length > i ? ((GraphDataObject[]) newValue)[i] : null;
updateChildBean(path + '.' + field + '[' + i + ']', dao, uow, handler, domainObject, mapping, field, mode, newDao);
}
}
}
} else {
// Or a single Object (one-to-one)
// Assumes its a DAO....what else could it be?
GraphDataObject dao = (GraphDataObject) value;
if (dao.getDeleteObject() != null && dao.getDeleteObject()) {
if (mode == DataTransformer.Mode.VALIDATE_ONLY) {
if (log.isDebugEnabled())
log.debug("The 'deleteObject' property is true. No prevalidations will be performed for the childBean.");
} else {
if (log.isDebugEnabled())
log.debug("The 'deleteObject' property is true. Invoking deleteChildBean()");
deleteChildBean(path + '.' + field, dao, uow, handler, domainObject, mapping, field);
}
} else {
GraphDataObject newDao = newGraph != null ? (GraphDataObject) getProperty(mapping.getDataFieldDescriptor(field), newGraph) : null;
updateChildBean(path + '.' + field, dao, uow, handler, domainObject, mapping, field, mode, newDao);
}
}
}
}
// Fire 'endBean' handler
if (mode != DataTransformer.Mode.VALIDATE_ONLY && handlers != null) {
for (ITransformationHandler transformationHandler : handlers) {
transformationHandler.endBean(path, source, domainObject);
}
}
} catch (SkipTransformException e) {
if (log.isDebugEnabled()) {
log.debug("Processing of " + path + " will be skipped", e);
}
} catch (ApplicationException e) {
throw new ApplicationExceptions(e);
}
}
Aggregations