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.dao.ojb;
017:
018: import java.util.Collection;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Map;
022: import java.util.Set;
023:
024: import org.apache.ojb.broker.query.Criteria;
025: import org.apache.ojb.broker.query.QueryByCriteria;
026: import org.apache.ojb.broker.query.QueryFactory;
027: import org.kuali.RicePropertyConstants;
028: import org.kuali.core.bo.PersistableBusinessObject;
029: import org.kuali.core.dao.BusinessObjectDao;
030: import org.kuali.core.service.PersistenceStructureService;
031: import org.kuali.core.util.ObjectUtils;
032: import org.kuali.core.util.OjbCollectionAware;
033: import org.kuali.rice.KNSServiceLocator;
034: import org.springframework.dao.DataAccessException;
035:
036: /**
037: * This class is the OJB implementation of the BusinessObjectDao interface and should be used for generic business object unit
038: * tests.
039: */
040: public class BusinessObjectDaoOjb extends PlatformAwareDaoBaseOjb
041: implements BusinessObjectDao, OjbCollectionAware {
042: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
043: .getLogger(BusinessObjectDaoOjb.class);
044:
045: private PersistenceStructureService persistenceStructureService;
046:
047: /**
048: * @see org.kuali.core.dao.BusinessObjectDao#findByPrimaryKey(java.lang.Class, java.util.Map)
049: */
050: public PersistableBusinessObject findByPrimaryKey(Class clazz,
051: Map primaryKeys) {
052: Criteria criteria = buildCriteria(primaryKeys);
053:
054: return (PersistableBusinessObject) getPersistenceBrokerTemplate()
055: .getObjectByQuery(
056: QueryFactory.newQuery(clazz, criteria));
057: }
058:
059: /**
060: * Retrieves all of the records for a given class name.
061: *
062: * @param clazz - the name of the object being used, either KualiCodeBase or a subclass
063: * @return Collection
064: * @see org.kuali.core.dao.BusinessObjectDao#findAll(java.lang.Class)
065: */
066: public Collection findAll(Class clazz) {
067: return getPersistenceBrokerTemplate().getCollectionByQuery(
068: QueryFactory.newQuery(clazz, (Criteria) null));
069: }
070:
071: /**
072: * @see org.kuali.core.dao.BusinessObjectDao#findAllOrderBy(java.lang.Class, java.lang.String, boolean)
073: */
074: public Collection findAllOrderBy(Class clazz, String sortField,
075: boolean sortAscending) {
076: QueryByCriteria queryByCriteria = new QueryByCriteria(clazz,
077: (Criteria) null);
078:
079: if (sortAscending) {
080: queryByCriteria.addOrderByAscending(sortField);
081: } else {
082: queryByCriteria.addOrderByDescending(sortField);
083: }
084:
085: return getPersistenceBrokerTemplate().getCollectionByQuery(
086: queryByCriteria);
087: }
088:
089: /**
090: * This is the default impl that comes with Kuali - uses OJB.
091: *
092: * @see org.kuali.core.dao.BusinessObjectDao#findMatching(java.lang.Class, java.util.Map)
093: */
094: public Collection findMatching(Class clazz, Map fieldValues) {
095: Criteria criteria = buildCriteria(fieldValues);
096:
097: return getPersistenceBrokerTemplate().getCollectionByQuery(
098: QueryFactory.newQuery(clazz, criteria));
099: }
100:
101: /**
102: * @see org.kuali.core.dao.BusinessObjectDao#findAllActive(java.lang.Class)
103: */
104: public Collection findAllActive(Class clazz) {
105: return getPersistenceBrokerTemplate().getCollectionByQuery(
106: QueryFactory.newQuery(clazz, buildActiveCriteria()));
107: }
108:
109: /**
110: * @see org.kuali.core.dao.BusinessObjectDao#findAllActiveOrderBy(java.lang.Class, java.lang.String, boolean)
111: */
112: public Collection findAllActiveOrderBy(Class clazz,
113: String sortField, boolean sortAscending) {
114: QueryByCriteria queryByCriteria = new QueryByCriteria(clazz,
115: buildActiveCriteria());
116:
117: if (sortAscending) {
118: queryByCriteria.addOrderByAscending(sortField);
119: } else {
120: queryByCriteria.addOrderByDescending(sortField);
121: }
122:
123: return getPersistenceBrokerTemplate().getCollectionByQuery(
124: queryByCriteria);
125: }
126:
127: /**
128: * @see org.kuali.core.dao.BusinessObjectDao#findMatchingActive(java.lang.Class, java.util.Map)
129: */
130: public Collection findMatchingActive(Class clazz, Map fieldValues) {
131: Criteria criteria = buildCriteria(fieldValues);
132: criteria.addAndCriteria(buildActiveCriteria());
133:
134: return getPersistenceBrokerTemplate().getCollectionByQuery(
135: QueryFactory.newQuery(clazz, criteria));
136: }
137:
138: /**
139: * This is the default impl that comes with Kuali - uses OJB.
140: *
141: * @see org.kuali.core.dao.BusinessObjectDao#countMatching(java.lang.Class, java.util.Map)
142: */
143: public int countMatching(Class clazz, Map fieldValues) {
144: Criteria criteria = buildCriteria(fieldValues);
145:
146: return getPersistenceBrokerTemplate().getCount(
147: QueryFactory.newQuery(clazz, criteria));
148: }
149:
150: /**
151: * This is the default impl that comes with Kuali - uses OJB.
152: *
153: * @see org.kuali.core.dao.BusinessObjectDao#countMatching(java.lang.Class, java.util.Map, java.util.Map)
154: */
155: public int countMatching(Class clazz, Map positiveFieldValues,
156: Map negativeFieldValues) {
157: Criteria criteria = buildCriteria(positiveFieldValues);
158: Criteria negativeCriteria = buildNegativeCriteria(negativeFieldValues);
159: criteria.addAndCriteria(negativeCriteria);
160: return getPersistenceBrokerTemplate().getCount(
161: QueryFactory.newQuery(clazz, criteria));
162: }
163:
164: /**
165: * This is the default impl that comes with Kuali - uses OJB.
166: *
167: * @see org.kuali.core.dao.BusinessObjectDao#findMatching(java.lang.Class, java.util.Map)
168: */
169: public Collection findMatchingOrderBy(Class clazz, Map fieldValues,
170: String sortField, boolean sortAscending) {
171: Criteria criteria = buildCriteria(fieldValues);
172: QueryByCriteria queryByCriteria = new QueryByCriteria(clazz,
173: criteria);
174:
175: if (sortAscending) {
176: queryByCriteria.addOrderByAscending(sortField);
177: } else {
178: queryByCriteria.addOrderByDescending(sortField);
179: }
180:
181: return getPersistenceBrokerTemplate().getCollectionByQuery(
182: queryByCriteria);
183: }
184:
185: /**
186: * Saves a business object.
187: *
188: * @see org.kuali.core.dao.BusinessObjectDao#save(org.kuali.core.bo.PersistableBusinessObject)
189: */
190: public void save(PersistableBusinessObject bo)
191: throws DataAccessException {
192: // refresh bo to get db copy of collections
193: PersistableBusinessObject savedBo = (PersistableBusinessObject) ObjectUtils
194: .deepCopy(bo);
195:
196: Set<String> boCollections = getPersistenceStructureService()
197: .listCollectionObjectTypes(savedBo.getClass()).keySet();
198: for (String boCollection : boCollections) {
199: if (getPersistenceStructureService().isCollectionUpdatable(
200: savedBo.getClass(), boCollection)) {
201: savedBo.refreshReferenceObject(boCollection);
202: }
203: }
204: KNSServiceLocator.getOjbCollectionHelper().processCollections(
205: this , bo, savedBo);
206:
207: getPersistenceBrokerTemplate().store(bo);
208: }
209:
210: /**
211: * Saves a business object.
212: *
213: * @see org.kuali.core.dao.BusinessObjectDao#save(org.kuali.core.bo.PersistableBusinessObject)
214: */
215: public void save(List businessObjects) throws DataAccessException {
216: for (Iterator i = businessObjects.iterator(); i.hasNext();) {
217: Object bo = i.next();
218: getPersistenceBrokerTemplate().store(bo);
219: }
220: }
221:
222: /**
223: * Deletes the business object passed in.
224: *
225: * @param bo
226: * @throws DataAccessException
227: * @see org.kuali.core.dao.BusinessObjectDao#delete(org.kuali.core.bo.PersistableBusinessObject)
228: */
229: public void delete(PersistableBusinessObject bo) {
230: getPersistenceBrokerTemplate().delete(bo);
231: }
232:
233: /**
234: * @see org.kuali.core.dao.BusinessObjectDao#delete(java.util.List)
235: */
236: public void delete(List<PersistableBusinessObject> boList) {
237: for (PersistableBusinessObject bo : boList) {
238: getPersistenceBrokerTemplate().delete(bo);
239: }
240: }
241:
242: /**
243: * @see org.kuali.core.dao.BusinessObjectDao#deleteMatching(java.lang.Class, java.util.Map)
244: */
245: public void deleteMatching(Class clazz, Map fieldValues) {
246: Criteria criteria = buildCriteria(fieldValues);
247:
248: getPersistenceBrokerTemplate().deleteByQuery(
249: QueryFactory.newQuery(clazz, criteria));
250:
251: // An ojb delete by query doesn't update the cache so we need to clear the cache for everything to work property.
252: // don't believe me? Read the source code to OJB
253: getPersistenceBrokerTemplate().clearCache();
254: }
255:
256: /**
257: * @see org.kuali.core.dao.BusinessObjectDao#retrieve(org.kuali.core.bo.PersistableBusinessObject)
258: */
259: public PersistableBusinessObject retrieve(
260: PersistableBusinessObject object) {
261: return (PersistableBusinessObject) getPersistenceBrokerTemplate()
262: .getObjectByQuery(
263: QueryFactory.newQueryByIdentity(object));
264: }
265:
266: /**
267: * This method will build out criteria in the key-value paradigm (attribute-value).
268: *
269: * @param fieldValues
270: * @return
271: */
272: private Criteria buildCriteria(Map fieldValues) {
273: Criteria criteria = new Criteria();
274: for (Iterator i = fieldValues.entrySet().iterator(); i
275: .hasNext();) {
276: Map.Entry e = (Map.Entry) i.next();
277:
278: String key = (String) e.getKey();
279: Object value = e.getValue();
280: if (value instanceof Collection) {
281: criteria.addIn(key, (Collection) value);
282: } else {
283: criteria.addEqualTo(key, value);
284: }
285: }
286:
287: return criteria;
288: }
289:
290: /**
291: * Builds a Criteria object for active field set to true
292: * @return Criteria
293: */
294: private Criteria buildActiveCriteria() {
295: Criteria criteria = new Criteria();
296: criteria.addEqualTo(RicePropertyConstants.ACTIVE, true);
297:
298: return criteria;
299: }
300:
301: /**
302: * This method will build out criteria in the key-value paradigm (attribute-value).
303: *
304: * @param negativeFieldValues
305: * @return
306: */
307: private Criteria buildNegativeCriteria(Map negativeFieldValues) {
308: Criteria criteria = new Criteria();
309: for (Iterator i = negativeFieldValues.entrySet().iterator(); i
310: .hasNext();) {
311: Map.Entry e = (Map.Entry) i.next();
312:
313: String key = (String) e.getKey();
314: Object value = e.getValue();
315: if (value instanceof Collection) {
316: criteria.addNotIn(key, (Collection) value);
317: } else {
318: criteria.addNotEqualTo(key, value);
319: }
320: }
321:
322: return criteria;
323: }
324:
325: /**
326: * Gets the persistenceStructureService attribute.
327: * @return Returns the persistenceStructureService.
328: */
329: protected PersistenceStructureService getPersistenceStructureService() {
330: return persistenceStructureService;
331: }
332:
333: /**
334: * Sets the persistenceStructureService attribute value.
335: * @param persistenceStructureService The persistenceStructureService to set.
336: */
337: public void setPersistenceStructureService(
338: PersistenceStructureService persistenceStructureService) {
339: this.persistenceStructureService = persistenceStructureService;
340: }
341:
342: }
|