001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.core.util;
017:
018: import java.util.ArrayList;
019: import java.util.Collection;
020: import java.util.Iterator;
021: import java.util.List;
022:
023: import org.kuali.core.bo.PersistableBusinessObject;
024: import org.springframework.orm.ObjectRetrievalFailureException;
025:
026: /**
027: * Helper object to deal with persisting collections.
028: */
029: public class OjbCollectionHelper {
030:
031: /**
032: * OJB RemovalAwareLists do not survive through the response/request lifecycle. This method is a work-around to forcibly remove
033: * business objects that are found in Collections stored in the database but not in memory.
034: *
035: * @param orig
036: * @param id
037: * @param template
038: */
039: public void processCollections(OjbCollectionAware template,
040: PersistableBusinessObject orig,
041: PersistableBusinessObject copy) {
042: if (copy == null) {
043: return;
044: }
045:
046: List originalCollections = orig.buildListOfDeletionAwareLists();
047:
048: if (originalCollections != null
049: && !originalCollections.isEmpty()) {
050: /*
051: * Prior to being saved, the version in the database will not yet reflect any deleted collections. So, a freshly
052: * retrieved version will contain objects that need to be removed:
053: */
054: try {
055: List copyCollections = copy
056: .buildListOfDeletionAwareLists();
057: int size = originalCollections.size();
058:
059: if (copyCollections.size() != size) {
060: throw new RuntimeException(
061: "size mismatch while attempting to process list of Collections to manage");
062: }
063:
064: for (int i = 0; i < size; i++) {
065: Collection origSource = (Collection) originalCollections
066: .get(i);
067: Collection copySource = (Collection) copyCollections
068: .get(i);
069: List list = findUnwantedElements(copySource,
070: origSource);
071: cleanse(template, origSource, list);
072: }
073: } catch (ObjectRetrievalFailureException orfe) {
074: // object wasn't found, must be pre-save
075: }
076: }
077: }
078:
079: /**
080: * OJB RemovalAwareLists do not survive through the response/request lifecycle. This method is a work-around to forcibly remove
081: * business objects that are found in Collections stored in the database but not in memory.
082: *
083: * @param orig
084: * @param id
085: * @param template
086: */
087: public void processCollections2(OjbCollectionAware template,
088: PersistableBusinessObject orig,
089: PersistableBusinessObject copy) {
090: // if copy is null this is the first time we are saving the object, don't have to worry about updating collections
091: if (copy == null) {
092: return;
093: }
094:
095: List originalCollections = orig.buildListOfDeletionAwareLists();
096:
097: if (originalCollections != null
098: && !originalCollections.isEmpty()) {
099: /*
100: * Prior to being saved, the version in the database will not yet reflect any deleted collections. So, a freshly
101: * retrieved version will contain objects that need to be removed:
102: */
103: try {
104: List copyCollections = copy
105: .buildListOfDeletionAwareLists();
106: int size = originalCollections.size();
107:
108: if (copyCollections.size() != size) {
109: throw new RuntimeException(
110: "size mismatch while attempting to process list of Collections to manage");
111: }
112:
113: for (int i = 0; i < size; i++) {
114: Collection origSource = (Collection) originalCollections
115: .get(i);
116: Collection copySource = (Collection) copyCollections
117: .get(i);
118: List list = findUnwantedElements(copySource,
119: origSource);
120: cleanse(template, origSource, list);
121: }
122: } catch (ObjectRetrievalFailureException orfe) {
123: // object wasn't found, must be pre-save
124: }
125: }
126: }
127:
128: /**
129: * This method deletes unwanted objects from the database as well as from the given input List
130: *
131: * @param origSource - list containing unwanted business objects
132: * @param unwantedItems - business objects to be permanently removed
133: * @param template
134: */
135: private void cleanse(OjbCollectionAware template,
136: Collection origSource, List unwantedItems) {
137: if (unwantedItems.size() > 0) {
138: Iterator iter = unwantedItems.iterator();
139: while (iter.hasNext()) {
140: template.getPersistenceBrokerTemplate().delete(
141: iter.next());
142: }
143: }
144:
145: }
146:
147: /**
148: * This method identifies items in the first List that are not contained in the second List. It is similar to the (optional)
149: * java.util.List retainAll method.
150: *
151: * @param fromList
152: * @param controlList
153: * @return true iff one or more items were removed
154: */
155: private List findUnwantedElements(Collection fromList,
156: Collection controlList) {
157: List toRemove = new ArrayList();
158:
159: Iterator iter = fromList.iterator();
160: while (iter.hasNext()) {
161: PersistableBusinessObject line = (PersistableBusinessObject) iter
162: .next();
163: if (!ObjectUtils.collectionContainsObjectWithIdentitcalKey(
164: controlList, line)) {
165: toRemove.add(line);
166: }
167: }
168: return toRemove;
169: }
170: }
|