Initial commit from SVN.
This commit is contained in:
477
Foundation/src/com/foundation/controller/ModelInterface.java
Normal file
477
Foundation/src/com/foundation/controller/ModelInterface.java
Normal file
@@ -0,0 +1,477 @@
|
||||
package com.foundation.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.exception.MethodNotSupportedException;
|
||||
import com.common.io.IExternalizable;
|
||||
import com.common.io.IObjectInputStream;
|
||||
import com.common.io.IObjectOutputStream;
|
||||
import com.common.orb.Orb;
|
||||
import com.common.util.IList;
|
||||
import com.common.util.LiteList;
|
||||
import com.foundation.attribute.IReflectable;
|
||||
import com.foundation.attribute.IReflectableCollection;
|
||||
import com.foundation.common.Entity;
|
||||
import com.foundation.common.IEntity;
|
||||
import com.foundation.metadata.Attribute;
|
||||
import com.foundation.transaction.ReadTransaction;
|
||||
import com.foundation.util.IManagedList;
|
||||
|
||||
/**
|
||||
* The interface used by application components to access shared models regardless of where they are located.
|
||||
*
|
||||
* TODO: Reflect all results from a remote source. This should be "pass-through" in that any synchronizations automatically get forwarded to the reflected object and don't get applied if the reflected object rejects the change set.
|
||||
*
|
||||
* TODO: Listen to remote sources for lost connections - automatically reconnect the reflection(s) when a source is lost.
|
||||
*
|
||||
* TODO: Allow calls to some methods to not return the reflected object; Allow additional result information to be returned - such as the "duplicate value for Customer.LOGIN found" error.
|
||||
*
|
||||
*/
|
||||
public class ModelInterface {
|
||||
/** The one and only instance of this class. */
|
||||
private static final ModelInterface singleton = new ModelInterface();
|
||||
/**
|
||||
* ModelInterface constructor.
|
||||
*/
|
||||
private ModelInterface() {
|
||||
}//ModelInterface()//
|
||||
/**
|
||||
* Adds the entity to the shared set of models.
|
||||
* <p>This is used for Mapped and List type models.</p>
|
||||
* @param entity The entity to be added. This object must be serializable in the event that the model management occurs on a remote process.
|
||||
* @param returnAddition Whether to return the added value. This will be a local reflection if the model management is remote.
|
||||
* @return A result object containing the reflection of the added value if successful.
|
||||
*/
|
||||
public static ReflectionResult addEntity(IEntity entity, boolean returnAddition) {
|
||||
ReflectionResult result = null;
|
||||
Class type = entity != null ? entity.getClass() : null;
|
||||
|
||||
if(type != null) {
|
||||
IModelManager modelManager = singleton.locateModelManager(type);
|
||||
|
||||
if(entity.isObjectRepositoryBound()) {
|
||||
if(!entity.isObjectNew()) {
|
||||
throw new IllegalArgumentException("Must only add new objects to the manager.");
|
||||
}//if//
|
||||
else if(entity.isReflection()) {
|
||||
throw new IllegalArgumentException("Cannot send a reflection.");
|
||||
}//else if//
|
||||
}//if//
|
||||
|
||||
if(modelManager != null) {
|
||||
if(modelManager instanceof ISingleListModelManager) {
|
||||
result = ((ISingleListModelManager) modelManager).addEntity(entity, returnAddition);
|
||||
}//if//
|
||||
else if(modelManager instanceof ISingleMappedModelManager) {
|
||||
result = ((ISingleMappedModelManager) modelManager).addEntity(entity, returnAddition);
|
||||
}//else if//
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid model manager type.");
|
||||
}//else//
|
||||
|
||||
//Reflect the added value if it is returned and the management is remote.//
|
||||
if(returnAddition && !Orb.isLocal(modelManager) && result instanceof ReflectionSuccess && ((ReflectionSuccess) result).getResult() != null) {
|
||||
|
||||
//TODO: Reflect the result with a weak & pass through reflection manager.
|
||||
//TODO: Must ensure that synchronization to the reflection propegates automatically to the remote reflected object and any failures propegate back to the synchronizer.
|
||||
// reflect((IReflectable) ((ReflectionSuccess) result).getResult());
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Specify an identifier.
|
||||
result = new ReflectionNetworkError(0, "Failed to locate a Model Manager.");
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//addEntity()//
|
||||
/**
|
||||
* Adds the entities to the shared set of models.
|
||||
* <p>This is used for Mapped and List type models.</p>
|
||||
* @param entities The list of entity instances to be added. This object must be serializable in the event that the model management occurs on a remote process.
|
||||
* @param returnAdditions
|
||||
* @return A result object containing an IList collection of reflectable references to the entities added. These may not be the same objects as was passed to this method.
|
||||
*/
|
||||
public static ReflectionResult addEntities(IList entities, boolean returnAdditions) {
|
||||
ReflectionResult result = null;
|
||||
Class type = entities == null || entities.getSize() == 0 || entities.getFirst() == null ? null : entities.getFirst().getClass();
|
||||
|
||||
if(type != null) {
|
||||
IModelManager modelManager = singleton.locateModelManager(type);
|
||||
|
||||
if(modelManager != null) {
|
||||
for(int index = 0, size = entities.getSize(); index < size; index++) {
|
||||
Entity next = (Entity) entities.get(index);
|
||||
|
||||
if(!next.isObjectNew()) {
|
||||
throw new IllegalArgumentException("Must only add new objects to the manager.");
|
||||
}//if//
|
||||
else if(next.isReflection()) {
|
||||
throw new IllegalArgumentException("Cannot send a reflection.");
|
||||
}//else if//
|
||||
}//for//
|
||||
|
||||
if(modelManager instanceof ISingleListModelManager) {
|
||||
result = ((ISingleListModelManager) modelManager).addEntities(entities, returnAdditions);
|
||||
}//if//
|
||||
else if(modelManager instanceof ISingleMappedModelManager) {
|
||||
result = ((ISingleMappedModelManager) modelManager).addEntities(entities, returnAdditions);
|
||||
}//else if//
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid model manager type.");
|
||||
}//else//
|
||||
|
||||
//If results were returned then reflect them using a pass through & weak reflection manager so that we have a single point to recover from failures.//
|
||||
if(returnAdditions && !Orb.isLocal(modelManager) && result instanceof ReflectionSuccess && ((ReflectionSuccess) result).getResult() instanceof IList && ((IList) ((ReflectionSuccess) result).getResult()).getSize() > 0) {
|
||||
//Reflect the results.//
|
||||
// reflectAll((IList) ((ReflectionSuccess) result).getResult());
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Specify an identifier.
|
||||
result = new ReflectionNetworkError(0, "Failed to locate a Model Manager.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
result = new ReflectionSuccess(LiteList.EMPTY_LIST);
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//addEntity()//
|
||||
/**
|
||||
* Removes (deletes) the entity from the shared set of models. The values will also be deleted to any attached repository.
|
||||
* <p>This is used for Mapped and List type models.</p>
|
||||
* @param entity The entity to be removed. This object must be serializable in the event that the model management occurs on a remote process. The value may be a reflection or proxy - the code will de-reflect and de-proxy where possible.
|
||||
* @return A result object reporting success or failure of the operation.
|
||||
*/
|
||||
public static ReflectionResult removeEntity(IEntity entity) {
|
||||
ReflectionResult result = null;
|
||||
|
||||
try {
|
||||
if(entity != null) {
|
||||
Class type = Orb.isProxy(entity) ? Orb.getNonProxyClass(entity) : entity.getClass();
|
||||
|
||||
if(type != null) {
|
||||
IModelManager modelManager = singleton.locateModelManager(type);
|
||||
|
||||
if(modelManager != null) {
|
||||
//First ensure we are not using a local proxy.//
|
||||
if(Orb.isProxy(entity) && Orb.isLocal(entity)) {
|
||||
entity = (IEntity) Orb.getLocal(entity);
|
||||
}//if//
|
||||
|
||||
//Ensure we don't send a reflection (it can't be a reflection if it is a proxy).//
|
||||
while(!Orb.isProxy(entity) && entity.isReflection()) {
|
||||
entity = (IEntity) entity.getReflected();
|
||||
|
||||
//De-proxy the object if possible.//
|
||||
if(Orb.isProxy(entity) && Orb.isLocal(entity)) {
|
||||
entity = (IEntity) Orb.getLocal(entity);
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
if(modelManager instanceof ISingleListModelManager) {
|
||||
((ISingleListModelManager) modelManager).removeEntity(entity);
|
||||
}//if//
|
||||
else if(modelManager instanceof ISingleMappedModelManager) {
|
||||
((ISingleMappedModelManager) modelManager).removeEntity(entity);
|
||||
}//else if//
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid model manager type.");
|
||||
}//else//
|
||||
|
||||
result = new ReflectionSuccess(null);
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Specify an identifier.
|
||||
result = new ReflectionNetworkError(0, "Failed to locate a Model Manager.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
//Shouldn't ever get here.//
|
||||
throw new ClassNotFoundException();
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new NullPointerException();
|
||||
}//else//
|
||||
}//try//
|
||||
catch(ClassNotFoundException e) {
|
||||
Debug.log(e);
|
||||
result = new ReflectionCustomError(e);
|
||||
}//catch//
|
||||
|
||||
return result;
|
||||
}//removeEntity()//
|
||||
/**
|
||||
* Removes (deletes) the entities from the shared set of models. The values will also be deleted to any attached repository.
|
||||
* <p>This is used for Mapped and List type models.</p>
|
||||
* @param entities The list of entity instances to be removed. This object must be serializable in the event that the model management occurs on a remote process. List values may be reflections or proxies - the code will de-reflect and de-proxy where possible.
|
||||
* @return A result object reporting success or failure of the operation.
|
||||
*/
|
||||
public static ReflectionResult removeEntities(IList entities) {
|
||||
ReflectionResult result;
|
||||
|
||||
try {
|
||||
IReflectable first = entities == null || entities.getSize() == 0 || entities.getFirst() == null ? null : (IReflectable) entities.getFirst();
|
||||
Class type = Orb.isProxy(first) ? Orb.getNonProxyClass(first) : first.getClass();
|
||||
|
||||
if(type != null) {
|
||||
IModelManager modelManager = singleton.locateModelManager(type);
|
||||
|
||||
if(modelManager != null) {
|
||||
//Iterate over the entities and de-reflect and de-proxy where ever possible.//
|
||||
for(int index = 0, size = entities.getSize(); index < size; index++) {
|
||||
IReflectable next = (IReflectable) entities.get(index);
|
||||
|
||||
//First ensure we are not using a local proxy.//
|
||||
if(Orb.isProxy(next) && Orb.isLocal(next)) {
|
||||
next = (IReflectable) Orb.getLocal(next);
|
||||
}//if//
|
||||
|
||||
//Ensure we don't send a reflection (it can't be a reflection if it is a proxy).//
|
||||
while(!Orb.isProxy(next) && next.isReflection()) {
|
||||
next = next.getReflected();
|
||||
|
||||
//De-proxy the object if possible.//
|
||||
if(Orb.isProxy(next) && Orb.isLocal(next)) {
|
||||
next = (IReflectable) Orb.getLocal(next);
|
||||
}//if//
|
||||
}//while//
|
||||
|
||||
entities.set(index, next);
|
||||
}//for//
|
||||
|
||||
if(modelManager instanceof ISingleListModelManager) {
|
||||
((ISingleListModelManager) modelManager).removeEntities(entities);
|
||||
}//if//
|
||||
else if(modelManager instanceof ISingleMappedModelManager) {
|
||||
((ISingleMappedModelManager) modelManager).removeEntities(entities);
|
||||
}//else if//
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid model manager type.");
|
||||
}//else//
|
||||
|
||||
result = new ReflectionSuccess(null);
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Specify an identifier.
|
||||
result = new ReflectionNetworkError(0, "Failed to locate a Model Manager.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
//Shouldn't ever get here.//
|
||||
throw new ClassNotFoundException();
|
||||
}//else//
|
||||
}//try//
|
||||
catch(ClassNotFoundException e) {
|
||||
Debug.log(e);
|
||||
result = new ReflectionCustomError(e);
|
||||
}//catch//
|
||||
|
||||
return result;
|
||||
}//removeEntities()//
|
||||
/**
|
||||
* Finds the first entity matching the query.
|
||||
* @param query The query by example object.
|
||||
* @return A result object containing an IReflectable instance of the first result if the operation was successful.
|
||||
*/
|
||||
public static ReflectionResult findEntity(IEntity query) {
|
||||
ReflectionResult result = null;
|
||||
|
||||
try {
|
||||
Class type = query != null ? query.getClass() : null;
|
||||
|
||||
if(type != null) {
|
||||
IModelManager modelManager = singleton.locateModelManager(type);
|
||||
|
||||
if(modelManager != null) {
|
||||
if(query.isReflection()) {
|
||||
throw new IllegalArgumentException("Cannot send a reflection.");
|
||||
}//if//
|
||||
|
||||
if(modelManager instanceof ISingleListModelManager) {
|
||||
throw new MethodNotSupportedException("The class " + type.getName() + " uses a list model manager which doesn't support querying for elements.");
|
||||
}//if//
|
||||
else if(modelManager instanceof ISingleMappedModelManager) {
|
||||
result = ((ISingleMappedModelManager) modelManager).findEntity(query);
|
||||
}//else if//
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid model manager type.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Specify an identifier.
|
||||
result = new ReflectionNetworkError(0, "Failed to locate a Model Manager.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IllegalArgumentException();
|
||||
}//else//
|
||||
}//try//
|
||||
// catch(ClassNotFoundException e) {
|
||||
// Debug.log(e);
|
||||
// result = new ReflectionCustomError(e);
|
||||
// }//catch//
|
||||
finally {}
|
||||
|
||||
return result;
|
||||
}//findEntity()//
|
||||
/**
|
||||
* Finds all entities matching the query.
|
||||
* @param query The query by example object.
|
||||
* @return A result object containing an IList containing IReflectable instances matching the query if the operation was successful.
|
||||
*/
|
||||
public static ReflectionResult findEntities(IEntity query) {
|
||||
ReflectionResult result = null;
|
||||
Class type = query != null ? query.getClass() : null;
|
||||
|
||||
if(type != null) {
|
||||
IModelManager modelManager = singleton.locateModelManager(type);
|
||||
|
||||
if(modelManager != null) {
|
||||
if(query.isReflection()) {
|
||||
throw new IllegalArgumentException("Cannot send a reflection.");
|
||||
}//if//
|
||||
|
||||
if(modelManager instanceof ISingleListModelManager) {
|
||||
throw new MethodNotSupportedException("The class " + type.getName() + " uses a list model manager which doesn't support querying for elements.");
|
||||
}//if//
|
||||
else if(modelManager instanceof ISingleMappedModelManager) {
|
||||
result = ((ISingleMappedModelManager) modelManager).findEntities(query);
|
||||
}//else if//
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid model manager type.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Specify an identifier.
|
||||
result = new ReflectionNetworkError(0, "Failed to locate a Model Manager.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IllegalArgumentException();
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//findEntity()//
|
||||
/**
|
||||
* Gets all entities of the given type.
|
||||
* @param type The model type whose instances will be returned.
|
||||
* @return A result object containing an IReflectableCollection (reflect this which will contain reflections of all instances of the given type) if the operation was successful.
|
||||
*/
|
||||
public static ReflectionResult getEntities(Class type) {
|
||||
ReflectionResult result = null;
|
||||
|
||||
if(type != null) {
|
||||
IModelManager modelManager = singleton.locateModelManager(type);
|
||||
|
||||
if(modelManager != null) {
|
||||
if(modelManager instanceof ISingleListModelManager) {
|
||||
result = ((ISingleListModelManager) modelManager).getEntities();
|
||||
}//if//
|
||||
else if(modelManager instanceof ISingleMappedModelManager) {
|
||||
throw new MethodNotSupportedException("The class " + type.getName() + " uses a mapped model manager which doesn't support retrieving a collection of all elements.");
|
||||
}//else if//
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid model manager type.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Specify an identifier.
|
||||
result = new ReflectionNetworkError(0, "Failed to locate a Model Manager.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IllegalArgumentException();
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//getEntities()//
|
||||
/**
|
||||
* Gets all (or first) entities of the given type.
|
||||
* @param type The model type whose instances will be returned.
|
||||
* @param transaction The read many or read single transaction to be run. The transaction must result in instance(s) of the passed <code>type</code>.
|
||||
* @return A result object containing an IReflectableCollection (reflect this which will contain reflections of all instances of the given type) if the operation was successful.
|
||||
*/
|
||||
public static ReflectionResult findEntities(Class type, ReadTransaction transaction) {
|
||||
ReflectionResult result = null;
|
||||
|
||||
if(type != null) {
|
||||
IModelManager modelManager = singleton.locateModelManager(type);
|
||||
|
||||
if(modelManager != null) {
|
||||
if(modelManager instanceof ISingleListModelManager) {
|
||||
result = ((ISingleListModelManager) modelManager).findEntities(transaction);
|
||||
}//if//
|
||||
else if(modelManager instanceof ISingleMappedModelManager) {
|
||||
result = ((ISingleMappedModelManager) modelManager).findEntities(transaction);
|
||||
}//else if//
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid model manager type.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Specify an identifier.
|
||||
result = new ReflectionNetworkError(0, "Failed to locate a Model Manager.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IllegalArgumentException();
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//findEntities()//
|
||||
/**
|
||||
* Gets all entities of the given type.
|
||||
* @param type The model type whose instances will be returned.
|
||||
* @param keys The set of keys that uniquely identify each model to be found.
|
||||
* @return A result object containing an IReflectableCollection (reflect this which will contain reflections of all instances of the given type) if the operation was successful.
|
||||
*/
|
||||
public static ReflectionResult findEntities(Class type, Object[] keys) {
|
||||
ReflectionResult result = null;
|
||||
|
||||
if(type != null) {
|
||||
IModelManager modelManager = singleton.locateModelManager(type);
|
||||
|
||||
if(modelManager != null) {
|
||||
if(modelManager instanceof ISingleListModelManager) {
|
||||
result = ((ISingleListModelManager) modelManager).findEntities(keys);
|
||||
}//if//
|
||||
else if(modelManager instanceof ISingleMappedModelManager) {
|
||||
result = ((ISingleMappedModelManager) modelManager).findEntities(keys);
|
||||
}//else if//
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid model manager type.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
//TODO: Specify an identifier.
|
||||
result = new ReflectionNetworkError(0, "Failed to locate a Model Manager.");
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
throw new IllegalArgumentException();
|
||||
}//else//
|
||||
|
||||
return result;
|
||||
}//findEntities()//
|
||||
/**
|
||||
* Locates the model manager
|
||||
* @param type The class whose model manager is to be found.
|
||||
* @return The non-null model manager reference.
|
||||
*/
|
||||
private IModelManager locateModelManager(Class type) {
|
||||
IModelManager result = null;
|
||||
|
||||
//The model manager will always be local. Each process has its own model manager which synchronizes with others via the ADA server network (when the app is deployed).//
|
||||
result = ModelManagerContainer.getSingleton().getModelManager(type);
|
||||
|
||||
if(result == null) {
|
||||
throw new IllegalArgumentException("The class " + type.getName() + " either is not marked for management or a model manager could not be found. The type should contain something similar to this code: static {registerTypeMetadata(xxxx.class, Entity.AO_MANAGEMENT_TYPE_LOAD_AS_NEEDED);}");
|
||||
}//if//
|
||||
|
||||
return result;
|
||||
}//locateModelManager()//
|
||||
}//ModelInterface//
|
||||
Reference in New Issue
Block a user