use of org.jaffa.persistence.IPersistent in project jaffa-framework by jaffa-projects.
the class DatabasePoller method poll.
/**
* Polls the database for a row represented by the input domain object. This
* will reload the row in a new UOW with paranoid locking, and then invoke
* the process() method on the reloaded domain object.
* @param domain The domain object.
*/
protected void poll(final IPersistent domain) {
UserContextWrapper ucw = null;
UOW uow = null;
try {
// Setup the user context based on the person who created the row in
// the database.
ucw = UserContextWrapperFactory.instance(findCreatedBy(domain));
// Reload the input domain object in a new UOW with paranoid locking
// NOTE: Another thread may have modified some flags on the
// underlying record; in which case a
// primary-key-based query will still reload the object. But we want
// to avoid re-processing that object.
// Hence re-apply the original filters
uow = new UOW();
final Criteria criteria = PersistentHelper.generateKeyCriteria(domain);
customizeCriteria(criteria);
criteria.setLocking(Criteria.LOCKING_PARANOID);
final Iterator<IPersistent> i = uow.query(criteria).iterator();
if (i.hasNext()) {
process(i.next());
uow.commit();
} else {
LOGGER.error(this.getClass().getSimpleName() + ": Unable to reload domain object. It may already have been processed by another thread. " + domain);
}
} catch (Exception e) {
if (ExceptionHelper.extractException(e, LockedApplicationException.class) != null) {
LOGGER.error(this.getClass().getSimpleName() + ": Error in reloading domain object. It may be locked by another thread. " + domain, e);
} else
LOGGER.error(this.getClass().getSimpleName() + ": Error in polling domain object " + domain, e);
} finally {
try {
if (uow != null)
uow.rollback();
} catch (Exception e) {
LOGGER.error(this.getClass().getSimpleName() + ": Error in closing UOW", e);
}
if (ucw != null)
ucw.unsetContext();
}
}
use of org.jaffa.persistence.IPersistent in project jaffa-framework by jaffa-projects.
the class DataTransformer method findRelatedObjects.
/**
* Retrieves the related object, as specified by the relatedObjectClass, from the input domain object.
* It'll utilize the findXyzCriteria() method, if available, to build the query, as well as to fire the handler.
* Else it'll utilize the getXyzArray() method, which may cache a huge number of objects.
*
* @param domain The domain object against which the query is to be invoked.
* @param relatedObjectClass The Class of the related object.
* @param relatedObjectGetter The getter for obtaining the array of related objects.
* @param handler The handler, if passed, will be invoked prior to retrieving the related object.
* @param originalCriteria The original Criteria used for the query. This is passed to the handler.
* @param path This is the source path of this graph, used when processing a more complex tree, where this is the path to get to this root object being processed.
* @return an array of related objects.
* @throws IllegalAccessException if the relatedObjectGetter is not accessible.
* @throws InvocationTargetException if any error occurs during invocation of the relatedObjectGetter.
*/
private static Object[] findRelatedObjects(Object domain, Class relatedObjectClass, Method relatedObjectGetter, ITransformationHandler handler, GraphCriteria originalCriteria, String path) throws IllegalAccessException, InvocationTargetException {
// The Getter typically caches the related objects. Hence try to locate the corresponding findXyzCriteria() method
try {
Matcher m = RELATED_OBJECT_GETTER.matcher(relatedObjectGetter.getName());
if (m.matches()) {
Method criteriaMethod = domain.getClass().getMethod("find" + m.group(1) + "Criteria");
if (Criteria.class.isAssignableFrom(criteriaMethod.getReturnType())) {
Criteria criteria = (Criteria) criteriaMethod.invoke(domain);
// Invoke the handler
if (handler != null) {
if (log.isDebugEnabled()) {
log.debug("Invoking the preQuery on the handler");
}
for (ITransformationHandler transformationHandler : handler.getTransformationHandlers()) {
Criteria handlerCriteria = transformationHandler.preQuery(path, criteria, originalCriteria, relatedObjectClass);
if (handlerCriteria != null) {
criteria = handlerCriteria;
}
}
}
if (criteria == null) {
// The handler will return a null if this query is not to be performed
return null;
} else {
UOW uow = domain instanceof IPersistent ? ((IPersistent) domain).getUOW() : null;
boolean localUow = uow == null;
try {
if (localUow)
uow = new UOW();
Collection col = uow.query(criteria);
// Iterate through the Collection to retrieve all the objects
for (Object o : col) {
}
return col.toArray();
} finally {
if (localUow && uow != null)
uow.rollback();
}
}
} else {
if (log.isDebugEnabled())
log.debug("Method '" + criteriaMethod.getName() + "' does not does not return a Criteria. Will invoke the method '" + relatedObjectGetter.getName() + "' directly to obtain the related object");
}
} else {
if (log.isDebugEnabled())
log.debug("Method '" + relatedObjectGetter.getName() + "' does not match the pattern '" + RELATED_OBJECT_GETTER + "'. Will invoke the method directly to obtain the related object");
}
} catch (Exception e) {
// do nothing
if (log.isDebugEnabled())
log.debug("Exception thrown during creation of the criteria for the related object or while retrieving it. Will invoke the method '" + relatedObjectGetter.getName() + "' directly to obtain the related object", e);
}
// There must have been an error in invoking the findXyzCriteria() method. Simply invoke the Getter
return (Object[]) relatedObjectGetter.invoke(domain);
}
use of org.jaffa.persistence.IPersistent in project jaffa-framework by jaffa-projects.
the class TransformerUtils method deleteChildBean.
/**
* Take a source object and try and mold it back it its domain object.
* This is the same as updateParent, except from the way it retrieved the
* record, and the way it creates a new record.
*/
static void deleteChildBean(String path, GraphDataObject source, UOW uow, ITransformationHandler handler, IPersistent parentDomain, GraphMapping parentMapping, String parentField) throws ApplicationExceptions, FrameworkException {
if (log.isDebugEnabled())
log.debug("Delete Child Bean " + path);
String relationshipName = parentMapping.getDomainFieldName(parentField);
if (relationshipName.endsWith("Array"))
relationshipName = relationshipName.substring(0, relationshipName.length() - 5);
if (relationshipName.endsWith("Object"))
relationshipName = relationshipName.substring(0, relationshipName.length() - 6);
try {
IPersistent domainObject = null;
GraphMapping mapping = MappingFactory.getInstance(source);
Map keys = new LinkedHashMap();
Class doClass = mapping.getDomainClass();
boolean gotKeys = false;
// if (mapping.getKeyFields() == null || mapping.getKeyFields().size() == 0) {
if (path == null || path.charAt(path.length() - 1) != ']') {
if (log.isDebugEnabled())
log.debug("Find 'one-to-one' object - " + path);
// Just use the getXxxObject method to get the related domain object,
// if there is one...
domainObject = (IPersistent) getProperty(parentMapping.getDomainFieldDescriptor(parentField), parentDomain);
if (domainObject == null) {
if (log.isDebugEnabled())
log.debug("Not Found - " + path);
}
} else {
// Get the key fields used in the domain object. Use the findXxxxxCriteria() method,
// then add the extra fields to the criteria object, to get the unique record.
gotKeys = fillInKeys(path, source, mapping, keys);
// read DO based on key
if (gotKeys) {
// get the method to get the PK criteria (i.e. public Criteria findVendorSiteCriteria(); )
Method findCriteria = null;
String methodName = "find" + StringHelper.getUpper1(relationshipName) + "Criteria";
try {
findCriteria = parentDomain.getClass().getMethod(methodName, new Class[] {});
} catch (NoSuchMethodException e) {
log.error("Find method '" + methodName + "' not found!");
}
if (findCriteria == null)
throw new TransformException(TransformException.METHOD_NOT_FOUND, path, methodName);
// Find Criteria For Related Object
Criteria criteria = (Criteria) findCriteria.invoke(parentDomain, new Object[] {});
// Add extra key info...
for (Iterator it = keys.keySet().iterator(); it.hasNext(); ) {
String keyField = (String) it.next();
Object value = keys.get(keyField);
keyField = StringHelper.getUpper1(mapping.getDomainFieldName(keyField));
criteria.addCriteria(keyField, value);
if (log.isDebugEnabled())
log.debug(path + "- Add to criteria:" + keyField + '=' + value);
}
// See if we get an object :-)
Iterator itr = uow.query(criteria).iterator();
if (itr.hasNext())
domainObject = (IPersistent) itr.next();
if (itr.hasNext()) {
// Error, multiple objects found
throw new ApplicationExceptions(new ApplicationExceptionWithContext(path, new MultipleDomainObjectsFoundException(findDomainLabel(criteria.getTable()))));
}
}
}
// Error if DO not found
if (domainObject == null)
throw new ApplicationExceptions(new ApplicationExceptionWithContext(path, new DomainObjectNotFoundException(findDomainLabel(doClass))));
// Process the delete, either on this DO, or a related DO if there is one
deleteBeanData(path, source, uow, handler, mapping, domainObject);
} catch (IllegalAccessException e) {
TransformException me = new TransformException(TransformException.ACCESS_ERROR, path, e.getMessage());
log.error(me.getLocalizedMessage(), e);
throw me;
} catch (InvocationTargetException e) {
ApplicationExceptions appExps = ExceptionHelper.extractApplicationExceptions(e);
if (appExps != null)
throw appExps;
FrameworkException fe = ExceptionHelper.extractFrameworkException(e);
if (fe != null)
throw fe;
TransformException me = new TransformException(TransformException.INVOCATION_ERROR, path, e);
log.error(me.getLocalizedMessage(), me.getCause());
throw me;
} catch (InstantiationException e) {
TransformException me = new TransformException(TransformException.INSTANTICATION_ERROR, path, e.getMessage());
log.error(me.getLocalizedMessage(), e);
throw me;
}
}
use of org.jaffa.persistence.IPersistent in project jaffa-framework by jaffa-projects.
the class TransformerUtils method updateChildBean.
/**
* Take a source object and try and mold it back it its domain object.
* This is the same as updateParent, except from the way it retrieved the
* record, and the way it creates a new record.
*/
static void updateChildBean(String path, GraphDataObject source, UOW uow, ITransformationHandler handler, IPersistent parentDomain, GraphMapping parentMapping, String parentField, DataTransformer.Mode mode, GraphDataObject newGraph) throws ApplicationExceptions, FrameworkException {
if (log.isDebugEnabled())
log.debug("Update Child Bean " + path);
String relationshipName = parentMapping.getDomainFieldName(parentField);
if (relationshipName.endsWith("Array"))
relationshipName = relationshipName.substring(0, relationshipName.length() - 5);
if (relationshipName.endsWith("Object"))
relationshipName = relationshipName.substring(0, relationshipName.length() - 6);
try {
IPersistent domainObject = null;
GraphMapping mapping = MappingFactory.getInstance(source);
Map keys = new LinkedHashMap();
Class doClass = mapping.getDomainClass();
boolean gotKeys = false;
// if (mapping.getKeyFields() == null || mapping.getKeyFields().size() == 0) {
if (path == null || path.charAt(path.length() - 1) != ']') {
if (log.isDebugEnabled())
log.debug("Find 'one-to-one' object - " + path);
// Just use the getXxxObject method to get the related domain object,
// if there is one...
domainObject = (IPersistent) getProperty(parentMapping.getDomainFieldDescriptor(parentField), parentDomain);
if (domainObject == null) {
if (log.isDebugEnabled())
log.debug("Not Found - " + path);
}
} else if (mode == DataTransformer.Mode.CLONE) {
// In CLONE mode, get the keys from the new graph, and force the creation of the domain object
if (newGraph != null)
fillInKeys(path, newGraph, mapping, keys);
} else {
// Get the key fields used in the domain object. Use the findXxxxxCriteria() method,
// then add the extra fields to the criteria object, to get the unique record.
gotKeys = fillInKeys(path, source, mapping, keys);
// read DO based on key
if (gotKeys) {
// get the method to get the PK criteria (i.e. public Criteria findVendorSiteCriteria(); )
Method findCriteria = null;
String methodName = "find" + StringHelper.getUpper1(relationshipName) + "Criteria";
try {
findCriteria = parentDomain.getClass().getMethod(methodName, new Class[] {});
} catch (NoSuchMethodException e) {
log.error("Find method '" + methodName + "' not found!");
}
if (findCriteria == null)
throw new TransformException(TransformException.METHOD_NOT_FOUND, path, methodName);
// Find Criteria For Related Object
Criteria criteria = (Criteria) findCriteria.invoke(parentDomain, new Object[] {});
// Add extra key info...
for (Iterator it = keys.keySet().iterator(); it.hasNext(); ) {
String keyField = (String) it.next();
Object value = keys.get(keyField);
keyField = StringHelper.getUpper1(mapping.getDomainFieldName(keyField));
criteria.addCriteria(keyField, value);
if (log.isDebugEnabled())
log.debug(path + "- Add to criteria:" + keyField + '=' + value);
}
// See if we get an object :-)
Iterator itr = uow.query(criteria).iterator();
if (itr.hasNext())
domainObject = (IPersistent) itr.next();
if (itr.hasNext()) {
// Error, multiple objects found
throw new ApplicationExceptions(new ApplicationExceptionWithContext(path, new MultipleDomainObjectsFoundException(findDomainLabel(criteria.getTable()))));
}
} else {
if (log.isDebugEnabled())
log.debug("Object " + path + " has either missing or null key values - Assume Create is needed");
}
}
// Create object if not found
if (domainObject == null) {
// In MASS_UPDATE mode, error if DO not found
if (mode == DataTransformer.Mode.MASS_UPDATE)
throw new ApplicationExceptions(new ApplicationExceptionWithContext(path, new DomainObjectNotFoundException(TransformerUtils.findDomainLabel(doClass))));
// NEW OBJECT, create and reflect keys
if (log.isDebugEnabled())
log.debug("DO '" + mapping.getDomainClassShortName() + "' not found with key, create a new one...");
// find method on parent used to create object
Method newObject = null;
String methodName = "new" + StringHelper.getUpper1(relationshipName) + "Object";
try {
newObject = parentDomain.getClass().getMethod(methodName, new Class[] {});
} catch (NoSuchMethodException e) {
log.error("Method '" + methodName + "()' not found!");
}
if (newObject == null)
throw new TransformException(TransformException.METHOD_NOT_FOUND, path, methodName);
// Call method to create object
domainObject = (IPersistent) newObject.invoke(parentDomain, new Object[] {});
// Set the key fields
for (Iterator it = keys.keySet().iterator(); it.hasNext(); ) {
String keyField = (String) it.next();
if (mapping.isReadOnly(keyField))
continue;
Object value = keys.get(keyField);
updateProperty(mapping.getDomainFieldDescriptor(keyField), value, domainObject);
}
} else {
if (log.isDebugEnabled())
log.debug("Found DO '" + mapping.getDomainClassShortName() + "' with key,");
}
// Now update all domain fields
updateBeanData(path, source, uow, handler, mapping, domainObject, mode, newGraph);
} catch (IllegalAccessException e) {
TransformException me = new TransformException(TransformException.ACCESS_ERROR, path, e.getMessage());
log.error(me.getLocalizedMessage(), e);
throw me;
} catch (InvocationTargetException e) {
ApplicationExceptions appExps = ExceptionHelper.extractApplicationExceptions(e);
if (appExps != null)
throw appExps;
FrameworkException fe = ExceptionHelper.extractFrameworkException(e);
if (fe != null)
throw fe;
TransformException me = new TransformException(TransformException.INVOCATION_ERROR, path, e);
log.error(me.getLocalizedMessage(), me.getCause());
throw me;
} catch (InstantiationException e) {
TransformException me = new TransformException(TransformException.INSTANTICATION_ERROR, path, e.getMessage());
log.error(me.getLocalizedMessage(), e);
throw me;
}
}
Aggregations