use of org.jaffa.persistence.IPersistent in project jaffa-framework by jaffa-projects.
the class JdbcBridge method executeQuery.
/**
* Executes the query based on the Criteria object.
* @param criteria The input Criteria.
* @param dataSource The DataSource against which the query is to be executed.
* @throws IOException if any error occurs while extracting the String from the criteria.
* @throws SQLException if any database error occurs.
* @throws PostLoadFailedException if any error is thrown in the PostLoad trigger of the persistent object.
* @throws DataSourceCursorRuntimeException if any error occurs while molding the row into the Persistent object.
* @return a Collection of Persistent objects as a result of the query.
*/
public static Collection executeQuery(Criteria criteria, DataSource dataSource) throws IOException, SQLException, PostLoadFailedException, DataSourceCursorRuntimeException {
ClassMetaData classMetaData = criteria.getTable() != null ? ConfigurationService.getInstance().getMetaData(criteria.getTable()) : null;
// The optimization will also be used, if the criteria contains a count(*) for performing an existence-check based on the primary-key
if (usePreparedStatement(dataSource) && hasPKCriteriaOnly(criteria, classMetaData)) {
if (criteria.getFunctionEntries() == null || criteria.getFunctionEntries().size() == 0) {
// Check the cache before executing the query
IPersistent object = dataSource.lookupObjectCache(criteria);
if (object != null) {
if (log.isDebugEnabled())
log.debug("Found the cached object: " + object);
Collection output = new LinkedList();
output.add(object);
return output;
}
if (log.isDebugEnabled())
log.debug("Optimized to use the PreparedStatement for querying by primary-key");
return executeFindByPKWithPreparedStatement(criteria, dataSource, classMetaData);
} else if (criteria.getFunctionEntries().size() == 1) {
Criteria.FunctionEntry fe = (Criteria.FunctionEntry) criteria.getFunctionEntries().iterator().next();
if (fe.getName() == null && fe.getFunction() == Criteria.FUNCTION_COUNT) {
// Check the cache before executing the query
IPersistent object = dataSource.lookupObjectCache(criteria);
if (object != null) {
if (log.isDebugEnabled())
log.debug("Found the cached object for existence-check by primary-key: " + object);
Collection output = new LinkedList();
Map map = new HashMap();
map.put(fe.getId(), 1);
output.add(map);
return output;
}
if (log.isDebugEnabled())
log.debug("Optimized to use the PreparedStatement for existence-check by primary-key");
return executeExistsWithPreparedStatement(criteria, dataSource, classMetaData);
}
}
}
// Utilize the pagingPlugin if the Criteria contains values for the firstResult and/or maxResults properties
IPagingPlugin pagingPlugin = createPagingPlugin(criteria, dataSource.getEngineType());
if (usePreparedStatement(dataSource)) {
// Perform a query using a PreparedStatement
PreparedStatement pstmt = QueryStatementHelper.getPreparedStatement(criteria, dataSource, pagingPlugin);
return dataSource.executeQuery(pstmt, classMetaData, criteria, (criteria.getLocking() == Criteria.LOCKING_PARANOID ? QUERY_TIMEOUT_FOR_LOCKING : 0), pagingPlugin);
} else {
// Perform a query using a regular Statement
String sql = QueryStatementHelper.getSQL(criteria, dataSource, pagingPlugin);
return dataSource.executeQuery(sql, classMetaData, criteria, (criteria.getLocking() == Criteria.LOCKING_PARANOID ? QUERY_TIMEOUT_FOR_LOCKING : 0), pagingPlugin);
}
}
use of org.jaffa.persistence.IPersistent in project jaffa-framework by jaffa-projects.
the class MoldingService method getObject.
/**
* Creates an instance of the persistent class, as defined in the input ClassMetaData defintion.
* @param classMetaData The ClassMetaData object, whose corresponding persistent class is to be instantiated.
* @throws ClassNotFoundException if the Persistent class is not found.
* @throws InstantiationException if this Class represents an abstract class, an interface, an array class, a primitive type, or void; or if the class has no nullary constructor; or if the instantiation fails for some other reason.
* @throws IllegalAccessException if the class or its nullary constructor is not accessible.
* @return an instance of the Persistent class, defined in the ClassMetaData defintion.
*/
public static IPersistent getObject(ClassMetaData classMetaData) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String className = classMetaData.getClassName();
Class clazz = Class.forName(className);
Object object = PersistentInstanceFactory.newPersistentInstance(clazz);
return (IPersistent) object;
}
use of org.jaffa.persistence.IPersistent in project jaffa-framework by jaffa-projects.
the class AttachmentHandler method checkFunctionAccess.
private void checkFunctionAccess(Attachment attachment, boolean forMaintenance) throws ApplicationExceptions, FrameworkException, AccessControlException {
if (attachment != null && attachment.getSerializedKey() != null) {
// Retrieve the domain object to which the attachment belongs
IPersistent attachTo = null;
try {
attachTo = PersistentHelper.loadFromSerializedKey(attachment.getUOW(), attachment.getSerializedKey());
} catch (Exception e) {
log.error("Exception thrown while retrieving the domain object to which the attachment belongs", e);
throw ExceptionHelper.throwAFR(e);
}
if (attachTo != null) {
// Ensure that the user has access to the domain object's attachments
String function = "Attachment." + attachTo.getClass().getSimpleName() + (forMaintenance ? ".Maintenance" : ".Inquiry");
if (!SecurityManager.checkFunctionAccess(function)) {
String str = "Access to business-function '" + function + "' is required to be able to " + (forMaintenance ? "manage" : "view") + " attachments for the domain class " + attachTo.getClass().getName();
log.error(str);
throw new AccessControlException(str);
}
}
}
}
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 updateGraph.
/**
* Take a source object and try and mold it back it its domain object
*
* @param path The path of this object being processed. This identifies possible parent and/or indexed entries where this object is contained.
* @param source Source object to mould from, typically a GraphDataObject
* @param uow Transaction handle all creates/update will be performed within. Throws an exception if null.
* @param handler Possible bean handler to be used when processing this source object graph
* @return In VALIDATE_ONLY mode the source object will be returned with default data. Else a GraphDataObject with just the key-fields of the root object will be returned if that object was newly created. Else a null will be returned.
* @throws ApplicationExceptions Thrown if one or more application logic errors are generated during moulding
* @throws FrameworkException Thrown if any runtime moulding error has occured.
*/
private static GraphDataObject updateGraph(String path, GraphDataObject source, UOW uow, ITransformationHandler handler, Mode mode, GraphDataObject newGraph) throws ApplicationExceptions, FrameworkException {
if (log.isDebugEnabled())
log.debug("Update Bean " + path);
if (source.getDeleteObject() != null && source.getDeleteObject()) {
if (mode == Mode.VALIDATE_ONLY) {
if (log.isDebugEnabled())
log.debug("The 'deleteObject' property is true. No prevalidations will be performed. The input object will be returned as is.");
return source;
} else {
if (log.isDebugEnabled())
log.debug("The 'deleteObject' property is true. Invoking deleteGraph()");
deleteGraph(path, source, uow, handler);
return null;
}
} else {
try {
IPersistent domainObject = null;
GraphMapping mapping = MappingFactory.getInstance(source);
Map keys = new LinkedHashMap();
Class doClass = mapping.getDomainClass();
// Get the key fields used in the domain object
// In CLONE mode, get the keys from the new graph, and force the creation of the domain object
boolean gotKeys = false;
if (mode == Mode.CLONE) {
if (newGraph != null)
gotKeys = TransformerUtils.fillInKeys(path, newGraph, mapping, keys);
} else
gotKeys = TransformerUtils.fillInKeys(path, source, mapping, keys);
// read DO based on key
if (gotKeys) {
// get the method on the DO to read via PK
Method[] ma = doClass.getMethods();
Method findByPK = null;
for (int i = 0; i < ma.length; i++) {
if (ma[i].getName().equals("findByPK")) {
if (ma[i].getParameterTypes().length == (keys.size() + 1) && (ma[i].getParameterTypes())[0] == UOW.class) {
// Found with name and correct no. of input params
findByPK = ma[i];
break;
}
}
}
if (findByPK == null)
throw new ApplicationExceptions(new DomainObjectNotFoundException(TransformerUtils.findDomainLabel(doClass)));
// Build input array
Object[] inputs = new Object[keys.size() + 1];
{
inputs[0] = uow;
int i = 1;
for (Iterator it = keys.values().iterator(); it.hasNext(); i++) {
inputs[i] = it.next();
}
}
// Find Object based on key
domainObject = (IPersistent) findByPK.invoke(null, inputs);
if (domainObject != null && mode == Mode.CLONE)
throw new ApplicationExceptions(new DuplicateKeyException(TransformerUtils.findDomainLabel(doClass)));
} else {
if (log.isDebugEnabled())
log.debug("Object " + path + " has either missing or null key values - Assume Create is needed");
}
// Create object if not found
boolean createMode = false;
if (domainObject == null) {
// In MASS_UPDATE mode, error if DO not found
if (mode == Mode.MASS_UPDATE)
throw new ApplicationExceptions(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...");
domainObject = (IPersistent) doClass.newInstance();
// 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);
TransformerUtils.updateProperty(mapping.getDomainFieldDescriptor(keyField), value, domainObject);
}
createMode = true;
} else {
if (log.isDebugEnabled())
log.debug("Found DO '" + mapping.getDomainClassShortName() + "' with key,");
}
// Now update all domain fields
TransformerUtils.updateBeanData(path, source, uow, handler, mapping, domainObject, mode, newGraph);
// Invoke the changeDone trigger
if (handler != null && handler.isChangeDone()) {
for (ITransformationHandler transformationHandler : handler.getTransformationHandlers()) {
transformationHandler.changeDone(path, source, domainObject, uow);
}
}
// Return an appropriate output
if (mode == Mode.VALIDATE_ONLY) {
// In VALIDATE_ONLY mode, return the input graph (with defaulted data)
return source;
} else if (createMode) {
// In create-mode, Create a new graph and stamp just the keys
GraphDataObject outputGraph = source.getClass().newInstance();
for (Iterator i = keys.keySet().iterator(); i.hasNext(); ) {
String keyField = (String) i.next();
PropertyDescriptor pd = mapping.getDomainFieldDescriptor(keyField);
if (pd != null && pd.getReadMethod() != null) {
Method m = pd.getReadMethod();
if (!m.isAccessible())
m.setAccessible(true);
Object value = m.invoke(domainObject, (Object[]) null);
AccessibleObject accessibleObject = mapping.getDataMutator(keyField);
setValue(accessibleObject, outputGraph, value);
} else {
TransformException me = new TransformException(TransformException.NO_KEY_ON_OBJECT, path, keyField, source.getClass().getName());
log.error(me.getLocalizedMessage());
throw me;
}
}
return outputGraph;
} else {
// In update-mode, return a null
return null;
}
} 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