/* * Copyright (c) 2006,2009 Declarative Engineering LLC. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Declarative Engineering LLC * verson 1 which accompanies this distribution, and is available at * http://declarativeengineering.com/legal/DE_Developer_License_v1.txt */ package com.foundation.controller; import com.common.util.ICollection; import com.common.util.IIterator; import com.common.util.LiteList; import com.foundation.common.IEntity; import com.foundation.exception.TransactionException; import com.foundation.transaction.TransactionContextHolder; import com.foundation.transaction.TransactionErrorInfo; import com.foundation.transaction.Transaction; import com.foundation.util.HashSetManager; import com.foundation.util.IManagedCollection; import com.foundation.util.ListManager; public class ModelController extends Controller { /** * A list manager that stores the models in the repository when they are added to the list and removes them from the repository when they are removed from the list. *
Warning: This manager can only handle entities that are attached to the same repository. If the entities in the collection come from multiple repositories this manager should not be used.
*/ public static class ModelListManager extends ListManager { private boolean suspendRepositoryHandling = false; /** * Gets the flag indicating that all repository interaction should be suspended. * This is handy for initializing the collection, or for manipulating it manually. * @return Whether the suspend adding/removing collection values to/from the repository. */ public boolean suspendRepositoryHandling() { return suspendRepositoryHandling; }//suspendRepositoryHandling()// /** * Sets the flag indicating that all repository interaction should be suspended. * This is handy for initializing the collection, or for manipulating it manually. * @param suspendRepositoryHandling Whether the suspend adding/removing collection values to/from the repository. */ public void suspendRepositoryHandling(boolean suspendRepositoryHandling) { this.suspendRepositoryHandling = suspendRepositoryHandling; }//suspendRepositoryHandling()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#checkOnAdd() */ public boolean checkOnAdd() { return !suspendRepositoryHandling; }//checkOnAdd()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#checkOnRemove() */ public boolean checkOnRemove() { return !suspendRepositoryHandling; }//checkOnRemove()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#checkOnReplace() */ public boolean checkOnReplace() { return !suspendRepositoryHandling; }//checkOnReplace()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canAdd(com.common.util.IManagedCollection, java.lang.Object, byte) */ public boolean canAdd(IManagedCollection managed, Object value, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && value instanceof IEntity) { TransactionErrorInfo info = ((IEntity) value).entityUpdate(); if(info != null) { managed.setErrorInfo(info); result = false; }//if// }//if// return result; }//canAdd()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canAddAll(com.common.util.IManagedCollection, com.common.util.IManagedCollection, byte) */ public boolean canAddAll(IManagedCollection managed, IManagedCollection values, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && values.getSize() > 0) { boolean hasError = false; TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); try { IIterator iterator = values.iterator(); //TODO: Would be nice to do a bulk add to the repository using a single query if possible. Not all objects may use the exact same query however! while(result && iterator.hasNext()) { Object value = iterator.next(); if(value instanceof IEntity) { TransactionErrorInfo info = ((IEntity) value).entityUpdate(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//if// }//while// }//try// finally { if(hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canAddAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canAddAll(com.common.util.IManagedCollection, java.lang.Object[], byte) */ public boolean canAddAll(IManagedCollection managed, Object[] values, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && values.length > 0) { boolean hasError = false; TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); try { //TODO: Would be nice to do a bulk add to the repository using a single query if possible. Not all objects may use the exact same query however! for(int valueIndex = values.length - 1; result && valueIndex >= 0; valueIndex--) { Object value = values[valueIndex]; if(value instanceof IEntity) { TransactionErrorInfo info = ((IEntity) value).entityUpdate(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//if// }//for// }//try// finally { if(!hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canAddAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canRemove(com.common.util.IManagedCollection, java.lang.Object, byte) */ public boolean canRemove(IManagedCollection managed, Object value, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && value instanceof IEntity) { /* * Note: This forces the thread to discard its cached object data and causes it to get the latest data from main memory. * This does not ensure another thread will not access the model at the same time. * We don't care about preventing other threads from accessing the entity since we will only be accessing sudo-static data for the deletion operation.// */ synchronized(value) { TransactionErrorInfo info = ((IEntity) value).entityDelete(); if(info != null) { managed.setErrorInfo(info); result = false; }//if// }//synchronized// }//if// return result; }//canRemove()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canRemoveAll(com.common.util.IManagedCollection, byte) */ public boolean canRemoveAll(IManagedCollection managed, byte context) { return canRemoveAll(managed, new LiteList(managed), context); }//canRemoveAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canRemoveAll(com.common.util.IManagedCollection, com.common.util.IManagedCollection, byte) */ public boolean canRemoveAll(IManagedCollection managed, ICollection values, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && values.getSize() > 0) { TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); boolean hasError = false; try { IIterator iterator = values.iterator(); //TODO: Would be nice to do a bulk remove from the repository using a single query if possible. Not all objects may use the exact same query however! while(result && iterator.hasNext()) { Object value = iterator.next(); if(value instanceof IEntity) { /* * Note: This forces the thread to discard its cached object data and causes it to get the latest data from main memory. * This does not ensure another thread will not access the model at the same time. * We don't care about preventing other threads from accessing the entity since we will only be accessing sudo-static data for the deletion operation.// */ synchronized(value) { TransactionErrorInfo info = ((IEntity) value).entityDelete(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//synchronized// }//if// }//while// }//try// finally { if(hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canRemoveAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canRemoveAll(com.common.util.IManagedCollection, java.lang.Object[], byte) */ public boolean canRemoveAll(IManagedCollection managed, Object[] values, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && values.length > 0) { TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); boolean hasError = false; try { //TODO: Would be nice to do a bulk remove from the repository using a single query if possible. Not all objects may use the exact same query however! for(int valueIndex = values.length - 1; result && valueIndex >= 0; valueIndex--) { Object value = values[valueIndex]; if(value instanceof IEntity) { /* * Note: This forces the thread to discard its cached object data and causes it to get the latest data from main memory. * This does not ensure another thread will not access the model at the same time. * We don't care about preventing other threads from accessing the entity since we will only be accessing sudo-static data for the deletion operation.// */ synchronized(value) { TransactionErrorInfo info = ((IEntity) value).entityDelete(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//synchronized// }//if// }//for// }//try// finally { if(hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canRemoveAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canReplace(com.common.util.IManagedCollection, java.lang.Object, java.lang.Object, byte) */ public boolean canReplace(IManagedCollection managed, Object oldValue, Object newValue, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED) { TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); boolean hasError = false; try { if(oldValue instanceof IEntity) { /* * Note: This forces the thread to discard its cached object data and causes it to get the latest data from main memory. * This does not ensure another thread will not access the model at the same time. * We don't care about preventing other threads from accessing the entity since we will only be accessing sudo-static data for the deletion operation.// */ synchronized(oldValue) { TransactionErrorInfo info = ((IEntity) oldValue).entityDelete(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//synchronized// }//if// if(newValue instanceof IEntity && result) { TransactionErrorInfo info = ((IEntity) newValue).entityUpdate(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//if// }//try// finally { if(hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canReplace()// }//ModelListManager// /** * A hash set manager that stores the models in the repository when they are added to the set and removes them from the repository when they are removed from the set. *Warning: This manager can only handle entities that are attached to the same repository. If the entities in the collection come from multiple repositories this manager should not be used.
*/ public static class ModelHashSetManager extends HashSetManager { private boolean suspendRepositoryHandling = false; /** * Gets the flag indicating that all repository interaction should be suspended. * This is handy for initializing the collection, or for manipulating it manually. * @return Whether the suspend adding/removing collection values to/from the repository. */ public boolean suspendRepositoryHandling() { return suspendRepositoryHandling; }//suspendRepositoryHandling()// /** * Sets the flag indicating that all repository interaction should be suspended. * This is handy for initializing the collection, or for manipulating it manually. * @param suspendRepositoryHandling Whether the suspend adding/removing collection values to/from the repository. */ public void suspendRepositoryHandling(boolean suspendRepositoryHandling) { this.suspendRepositoryHandling = suspendRepositoryHandling; }//suspendRepositoryHandling()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#checkOnAdd() */ public boolean checkOnAdd() { return !suspendRepositoryHandling; }//checkOnAdd()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#checkOnRemove() */ public boolean checkOnRemove() { return !suspendRepositoryHandling; }//checkOnRemove()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#checkOnReplace() */ public boolean checkOnReplace() { return !suspendRepositoryHandling; }//checkOnReplace()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canAdd(com.common.util.IManagedCollection, java.lang.Object, byte) */ public boolean canAdd(IManagedCollection managed, Object value, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && value instanceof IEntity) { TransactionErrorInfo info = ((IEntity) value).entityUpdate(); if(info != null) { managed.setErrorInfo(info); result = false; }//if// }//if// return result; }//canAdd()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canAddAll(com.common.util.IManagedCollection, com.common.util.IManagedCollection, byte) */ public boolean canAddAll(IManagedCollection managed, IManagedCollection values, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && values.getSize() > 0) { boolean hasError = false; TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); try { IIterator iterator = values.iterator(); //TODO: Would be nice to do a bulk add to the repository using a single query if possible. Not all objects may use the exact same query however! while(result && iterator.hasNext()) { Object value = iterator.next(); if(value instanceof IEntity) { TransactionErrorInfo info = ((IEntity) value).entityUpdate(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//if// }//while// }//try// finally { if(hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canAddAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canAddAll(com.common.util.IManagedCollection, java.lang.Object[], byte) */ public boolean canAddAll(IManagedCollection managed, Object[] values, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && values.length > 0) { boolean hasError = false; TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); try { //TODO: Would be nice to do a bulk add to the repository using a single query if possible. Not all objects may use the exact same query however! for(int valueIndex = values.length - 1; result && valueIndex >= 0; valueIndex--) { Object value = values[valueIndex]; if(value instanceof IEntity) { TransactionErrorInfo info = ((IEntity) value).entityUpdate(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//if// }//for// }//try// finally { if(!hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canAddAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canRemove(com.common.util.IManagedCollection, java.lang.Object, byte) */ public boolean canRemove(IManagedCollection managed, Object value, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && value instanceof IEntity) { /* * Note: This forces the thread to discard its cached object data and causes it to get the latest data from main memory. * This does not ensure another thread will not access the model at the same time. * We don't care about preventing other threads from accessing the entity since we will only be accessing sudo-static data for the deletion operation.// */ synchronized(value) { TransactionErrorInfo info = ((IEntity) value).entityDelete(); if(info != null) { managed.setErrorInfo(info); result = false; }//if// }//synchronized// }//if// return result; }//canRemove()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canRemoveAll(com.common.util.IManagedCollection, byte) */ public boolean canRemoveAll(IManagedCollection managed, byte context) { return canRemoveAll(managed, new LiteList(managed), context); }//canRemoveAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canRemoveAll(com.common.util.IManagedCollection, com.common.util.IManagedCollection, byte) */ public boolean canRemoveAll(IManagedCollection managed, ICollection values, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && values.getSize() > 0) { TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); boolean hasError = false; try { IIterator iterator = values.iterator(); //TODO: Would be nice to do a bulk remove from the repository using a single query if possible. Not all objects may use the exact same query however! while(result && iterator.hasNext()) { Object value = iterator.next(); if(value instanceof IEntity) { /* * Note: This forces the thread to discard its cached object data and causes it to get the latest data from main memory. * This does not ensure another thread will not access the model at the same time. * We don't care about preventing other threads from accessing the entity since we will only be accessing sudo-static data for the deletion operation.// */ synchronized(value) { TransactionErrorInfo info = ((IEntity) value).entityDelete(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//synchronized// }//if// }//while// }//try// finally { if(hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canRemoveAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canRemoveAll(com.common.util.IManagedCollection, java.lang.Object[], byte) */ public boolean canRemoveAll(IManagedCollection managed, Object[] values, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED && values.length > 0) { TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); boolean hasError = false; try { //TODO: Would be nice to do a bulk remove from the repository using a single query if possible. Not all objects may use the exact same query however! for(int valueIndex = values.length - 1; result && valueIndex >= 0; valueIndex--) { Object value = values[valueIndex]; if(value instanceof IEntity) { /* * Note: This forces the thread to discard its cached object data and causes it to get the latest data from main memory. * This does not ensure another thread will not access the model at the same time. * We don't care about preventing other threads from accessing the entity since we will only be accessing sudo-static data for the deletion operation.// */ synchronized(value) { TransactionErrorInfo info = ((IEntity) value).entityDelete(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//synchronized// }//if// }//for// }//try// finally { if(hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canRemoveAll()// /* (non-Javadoc) * @see com.foundation.util.CollectionManager#canReplace(com.common.util.IManagedCollection, java.lang.Object, java.lang.Object, byte) */ public boolean canReplace(IManagedCollection managed, Object oldValue, Object newValue, byte context) { boolean result = true; if(context != CONTEXT_TRUSTED) { TransactionContextHolder transactionContext = TransactionContextHolder.getInstance(null); boolean hasError = false; try { if(oldValue instanceof IEntity) { /* * Note: This forces the thread to discard its cached object data and causes it to get the latest data from main memory. * This does not ensure another thread will not access the model at the same time. * We don't care about preventing other threads from accessing the entity since we will only be accessing sudo-static data for the deletion operation.// */ synchronized(oldValue) { TransactionErrorInfo info = ((IEntity) oldValue).entityDelete(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//synchronized// }//if// if(newValue instanceof IEntity && result) { TransactionErrorInfo info = ((IEntity) newValue).entityUpdate(transactionContext); if(info != null) { hasError = true; managed.setErrorInfo(info); result = false; }//if// }//if// }//try// finally { if(hasError || !transactionContext.commit()) { transactionContext.rollback(); }//if// transactionContext.close(); }//finally// }//if// return result; }//canReplace()// }//ModelHashSetManager// /** * ModelController constructor. */ public ModelController() { }//ModelController()// /* (non-Javadoc) * @see com.foundation.controller.IController#getDecorationManager() */ public DecorationManager getDecorationManager() { return null; }//getDecorationManager()// }//ModelController//