001: package com.completex.objective.components.persistency.core.impl;
002:
003: import com.completex.objective.components.persistency.AbstractPersistentObject;
004: import com.completex.objective.components.persistency.Call;
005: import com.completex.objective.components.persistency.CallFactory;
006: import com.completex.objective.components.persistency.ColumnType;
007: import com.completex.objective.components.persistency.CompoundPersistentObject;
008: import com.completex.objective.components.persistency.LifeCycleController;
009: import com.completex.objective.components.persistency.Link;
010: import com.completex.objective.components.persistency.LockType;
011: import com.completex.objective.components.persistency.MappingPersistency;
012: import com.completex.objective.components.persistency.OdalPersistencyException;
013: import com.completex.objective.components.persistency.OdalRuntimePersistencyException;
014: import com.completex.objective.components.persistency.Persistency;
015: import com.completex.objective.components.persistency.PersistentObject;
016: import com.completex.objective.components.persistency.Query;
017: import com.completex.objective.components.persistency.QueryFactory;
018: import com.completex.objective.components.persistency.SelectQueryBuilder;
019: import com.completex.objective.components.persistency.core.DatabasePolicy;
020: import com.completex.objective.components.persistency.mapper.AdHocPoBeanConverter;
021: import com.completex.objective.components.persistency.mapper.Mapper;
022: import com.completex.objective.components.persistency.mapper.ThreadSession;
023: import com.completex.objective.components.persistency.transact.TransactionManager;
024: import com.completex.objective.components.persistency.type.CollectionFactory;
025: import com.completex.objective.components.persistency.type.MultipartCollection;
026: import com.completex.objective.components.persistency.type.TracingCollection;
027: import com.completex.objective.components.persistency.type.TypeHandler;
028: import com.completex.objective.components.log.Log;
029:
030: import java.util.ArrayList;
031: import java.util.Collection;
032: import java.util.HashSet;
033: import java.util.Iterator;
034: import java.util.List;
035: import java.util.Set;
036:
037: /**
038: * @author Gennady Krizhevsky
039: */
040: public class DatabaseMappingPersistencyImpl implements
041: MappingPersistency {
042:
043: private boolean cacheQueriesInSession = true;
044: private Persistency persistency;
045: private Mapper mapper = Mapper.NULL_MAPPER;
046: private AdHocPoBeanConverter adHocPoBeanConverter;
047: private Log logger = Log.NULL_LOGGER;
048:
049: protected DatabaseMappingPersistencyImpl() {
050: }
051:
052: public DatabaseMappingPersistencyImpl(Persistency persistency,
053: Mapper mapper, AdHocPoBeanConverter adHocPoBeanConverter,
054: Log logger) {
055: this .persistency = persistency;
056: this .mapper = mapper;
057: this .adHocPoBeanConverter = adHocPoBeanConverter;
058: this .logger = logger;
059: }
060:
061: public Log getLogger() {
062: return logger;
063: }
064:
065: public void setLogger(Log logger) {
066: this .logger = logger;
067: }
068:
069: protected void setCacheQueriesInSession(
070: boolean cacheQueriesInSession) {
071: this .cacheQueriesInSession = cacheQueriesInSession;
072: }
073:
074: protected void setPersistency(Persistency persistency) {
075: this .persistency = persistency;
076: }
077:
078: protected void setMapper(Mapper mapper) {
079: this .mapper = mapper;
080: }
081:
082: protected void setAdHocPoBeanConverter(
083: AdHocPoBeanConverter adHocPoBeanConverter) {
084: this .adHocPoBeanConverter = adHocPoBeanConverter;
085: }
086:
087: public Object load(PersistentObject persistentObject)
088: throws OdalPersistencyException {
089: return load(persistentObject, LockType.NONE);
090: }
091:
092: public Object load(PersistentObject persistentObject,
093: LockType lockType) throws OdalPersistencyException {
094: return load(persistentObject, lockType, NO_TIMEOUT);
095: }
096:
097: public Object load(PersistentObject persistentObject,
098: LifeCycleController controller)
099: throws OdalPersistencyException {
100: return load(persistentObject, controller, LockType.NONE,
101: NO_TIMEOUT);
102: }
103:
104: public Object load(PersistentObject persistentObject,
105: LockType lockType, long timeout)
106: throws OdalPersistencyException {
107: return load(persistentObject, null, lockType, timeout);
108: }
109:
110: public Object load(PersistentObject persistentObject,
111: LifeCycleController controller, LockType lockType,
112: long timeout) throws OdalPersistencyException {
113: Object po = persistency.load(persistentObject, controller,
114: lockType, timeout);
115: return convert(po, true);
116: }
117:
118: public Object loadForUpdate(PersistentObject persistentObject)
119: throws OdalPersistencyException {
120: return load(persistentObject, LockType.FOR_UPDATE);
121: }
122:
123: public Collection select(Query query)
124: throws OdalPersistencyException {
125: return select(query, null);
126: }
127:
128: public Collection select(Query query, LifeCycleController controller)
129: throws OdalPersistencyException {
130: Collection colOfPos = persistency.select(query, controller);
131: return convertCollection(colOfPos, isCacheQueriesInSession());
132: }
133:
134: public Collection select(PersistentObject persistentObject)
135: throws OdalPersistencyException {
136: return select(persistentObject, null);
137: }
138:
139: public Collection select(PersistentObject persistentObject,
140: LifeCycleController controller)
141: throws OdalPersistencyException {
142: return select(persistentObject, controller, LockType.NONE);
143: }
144:
145: public Collection select(PersistentObject persistentObject,
146: LifeCycleController controller, LockType lock)
147: throws OdalPersistencyException {
148: return select(persistentObject, controller, lock, NO_TIMEOUT);
149: }
150:
151: public Collection select(PersistentObject persistentObject,
152: LifeCycleController controller, LockType lock, long timeout)
153: throws OdalPersistencyException {
154: Collection colPos = persistency.select(persistentObject,
155: controller, lock, timeout);
156: return convertCollection(colPos, isCacheQueriesInSession());
157: }
158:
159: public Collection selectForUpdate(PersistentObject persistentObject)
160: throws OdalPersistencyException {
161: Collection colPos = persistency
162: .selectForUpdate(persistentObject);
163: return convertCollection(colPos, isCacheQueriesInSession());
164: }
165:
166: public boolean selectExists(Query query)
167: throws OdalPersistencyException {
168: return persistency.selectExists(query);
169: }
170:
171: public boolean selectExists(PersistentObject persistentObject)
172: throws OdalPersistencyException {
173: return persistency.selectExists(persistentObject);
174: }
175:
176: public long selectCount(Query query)
177: throws OdalPersistencyException {
178: return persistency.selectCount(query);
179: }
180:
181: public long selectCount(PersistentObject persistentObject)
182: throws OdalPersistencyException {
183: return persistency.selectCount(persistentObject);
184: }
185:
186: public Object selectFirst(Query query)
187: throws OdalPersistencyException {
188: return selectFirst(query,
189: LifeCycleController.NULL_LIFE_CYCLE_CONTROLLER);
190: }
191:
192: public Object selectFirst(final Query query,
193: final LifeCycleController controller)
194: throws OdalPersistencyException {
195: AbstractPersistentObject po = (AbstractPersistentObject) persistency
196: .selectFirst(query, controller);
197: return convert(po, true);
198: }
199:
200: public Object selectFirst(PersistentObject persistentObject)
201: throws OdalPersistencyException {
202: return selectFirst(persistentObject, null);
203: }
204:
205: public Object selectFirst(PersistentObject persistentObject,
206: LifeCycleController controller)
207: throws OdalPersistencyException {
208: PersistentObject po = (PersistentObject) persistency
209: .selectFirst(persistentObject, controller);
210: return convert(po, true);
211: }
212:
213: public Object selectFirstForUpdate(PersistentObject persistentObject)
214: throws OdalPersistencyException {
215: AbstractPersistentObject po = (AbstractPersistentObject) persistency
216: .selectFirstForUpdate(persistentObject);
217: return convert(po, true);
218: }
219:
220: public Object selectSingle(Query query)
221: throws OdalPersistencyException {
222: return persistency.selectSingle(query);
223: }
224:
225: public long getNextSeqValue(String name)
226: throws OdalPersistencyException {
227: return persistency.getNextSeqValue(name);
228: }
229:
230: public Collection selectSinglePartResultCall(Call query)
231: throws OdalPersistencyException {
232: return selectSinglePartResultCall(query, null);
233: }
234:
235: public Collection selectSinglePartResultCall(Call query,
236: LifeCycleController controller)
237: throws OdalPersistencyException {
238: Collection colPos = persistency.selectSinglePartResultCall(
239: query, controller);
240: return convertCollection(colPos, false);
241: }
242:
243: public MultipartCollection selectMultiPartResultCall(Call query)
244: throws OdalPersistencyException {
245: return selectMultiPartResultCall(query, null);
246: }
247:
248: public MultipartCollection selectMultiPartResultCall(Call query,
249: LifeCycleController controller)
250: throws OdalPersistencyException {
251: MultipartCollection sourceCollection = persistency
252: .selectMultiPartResultCall(query, controller);
253: MultipartCollection targetCollection = new MultipartCollection(
254: sourceCollection.size());
255: for (int i = 0; i < sourceCollection.size(); i++) {
256: Collection collection = sourceCollection.get(i);
257: targetCollection.add(convertCollection(collection, false));
258: }
259: return targetCollection;
260: }
261:
262: public Object update(Object bean) throws OdalPersistencyException {
263: return update(bean, null);
264: }
265:
266: public Object update(Object bean, LifeCycleController controller)
267: throws OdalPersistencyException {
268: boolean conversionNeeded = conversionToPoNeeded(bean);
269:
270: Object savedBean = null;
271: PersistentObject po;
272: if (conversionNeeded) {
273: boolean containsBean = ThreadSession.containsBean(mapper,
274: bean);
275: PersistentObject poNew = convertBeanToPoIfNeeded(bean,
276: conversionNeeded);
277: if (!containsBean) {
278: PersistentObject loadedPo = (PersistentObject) persistency
279: .load(poNew, controller);
280: loadedPo = merge(loadedPo, poNew);
281: if (loadedPo == null) {
282: return null;
283: }
284: po = loadedPo;
285: } else {
286: po = poNew;
287: }
288: } else {
289: po = (PersistentObject) bean;
290: savedBean = bean;
291: }
292:
293: persistency.update(po, controller);
294: if (conversionNeeded) {
295: mapper.convertPoToBean(po, true);
296: savedBean = ThreadSession.getBean(mapper, po);
297: }
298:
299: return savedBean;
300: }
301:
302: protected PersistentObject merge(PersistentObject loadedPo,
303: PersistentObject poNew) {
304: if (poNew == null) {
305: return loadedPo;
306: }
307: if (loadedPo == null) {
308: return null;
309: }
310: if (loadedPo.getClass() != poNew.getClass()) {
311: throw new OdalRuntimePersistencyException(
312: "loadedPo.getClass() [" + loadedPo.getClass()
313: + "] != poNew.getClass() ["
314: + poNew.getClass() + "]");
315: }
316:
317: loadedPo.copyDirty(poNew, null);
318: if (loadedPo.complex()) {
319: for (LinkIterator it = poNew.linkIterator(); it.hasNext();) {
320: Link childNew = it.nextLink();
321: Link loadedChild = loadedPo.child(childNew.getName());
322: if (childNew.getResult() instanceof PersistentObject) {
323: PersistentObject childPoNew = (PersistentObject) childNew
324: .getResult();
325: PersistentObject childPoLoaded = (PersistentObject) loadedChild
326: .getResult();
327: if (childPoLoaded == null) {
328: loadedChild.setResult(childPoNew.clone());
329:
330: } else {
331: merge(childPoLoaded, poNew);
332: }
333: } else if (childNew.getResult() instanceof Collection) {
334: Collection childColNew = (Collection) childNew
335: .getResult();
336: Collection childColLoaded = (Collection) loadedChild
337: .getResult();
338: if (childColLoaded == null) {
339: Query query = loadedChild.getQuery();
340: if (query != null) {
341: CollectionFactory multipleResultFactory = query
342: .getMultipleResultFactory();
343: Collection collection = multipleResultFactory
344: .newCollection();
345: if (collection instanceof TracingCollection) {
346: ((TracingCollection) collection)
347: .trace(childColNew);
348: }
349: }
350: } else if (childColLoaded instanceof TracingCollection) {
351: TracingCollection tracingCollection = ((TracingCollection) childColLoaded);
352: tracingCollection.trace(childColNew);
353: List updated = tracingCollection.getUpdated();
354: for (int i = 0; i < updated.size(); i++) {
355: PersistentObject persistentLoaded = (PersistentObject) updated
356: .get(i);
357: PersistentObject persistentNew = null;
358: // Find sibling:
359: for (Iterator iterator = childColNew
360: .iterator(); iterator.hasNext();) {
361: PersistentObject persistentObjectNew = (PersistentObject) iterator
362: .next();
363: if (persistentObjectNew.toKey().equals(
364: persistentLoaded.toKey())) {
365: persistentNew = persistentObjectNew;
366: }
367: }
368: merge(persistentLoaded, persistentNew);
369: }
370: }
371: }
372: }
373: }
374:
375: return loadedPo;
376: }
377:
378: private void convertPoToBeanIfNeeded(PersistentObject po,
379: boolean conversionNeeded) {
380: if (conversionNeeded) {
381: mapper.convertPoToBean(po, false);
382: }
383: }
384:
385: private PersistentObject convertBeanToPoIfNeeded(Object bean,
386: boolean conversionNeeded) {
387: PersistentObject po;
388: if (conversionNeeded) {
389: po = (PersistentObject) mapper.convertBeanToPo(bean, true);
390: } else {
391: po = (PersistentObject) bean;
392: }
393: return po;
394: }
395:
396: protected boolean conversionToPoNeeded(Object bean) {
397: return !(bean instanceof PersistentObject);
398: }
399:
400: public int insert(Object bean) throws OdalPersistencyException {
401: return insert(bean, null);
402: }
403:
404: public int insert(Object bean, LifeCycleController controller)
405: throws OdalPersistencyException {
406: boolean conversionNeeded = conversionToPoNeeded(bean);
407: PersistentObject po = convertBeanToPoIfNeeded(bean,
408: conversionNeeded);
409: int rc = persistency.insert(po, controller);
410: convertPoToBeanIfNeeded(po, conversionNeeded);
411: return rc;
412: }
413:
414: public int delete(Object bean) throws OdalPersistencyException {
415: return delete(bean, null);
416: }
417:
418: public int delete(Object bean, LifeCycleController controller)
419: throws OdalPersistencyException {
420: boolean conversionNeeded = conversionToPoNeeded(bean);
421: PersistentObject po = convertBeanToPoIfNeeded(bean,
422: conversionNeeded);
423: return persistency.delete(po, controller);
424: }
425:
426: protected Object convert(Object po, boolean forModification) {
427: if (po == null) {
428: return null;
429: } else if (po instanceof CompoundPersistentObject) {
430: CompoundPersistentObject compound = (CompoundPersistentObject) po;
431: PersistentObject[] persistentObjects = compound
432: .compoundEntries();
433: Object[] values = new Object[persistentObjects.length];
434: for (int i = 0; i < values.length; i++) {
435: PersistentObject persistent = persistentObjects[i];
436: values[i] = convert(persistent, getClass(persistent),
437: forModification);
438: }
439: return values;
440: } else if (po instanceof PersistentObject) {
441: PersistentObject persistent = (PersistentObject) po;
442: return convert(persistent, getClass(persistent),
443: forModification);
444: } else {
445: return po;
446: }
447: }
448:
449: protected static Class getClass(PersistentObject persistent) {
450: if (persistent == null) {
451: return null;
452: } else {
453: return persistent.getClass();
454: }
455: }
456:
457: public boolean isCacheQueriesInSession() {
458: return cacheQueriesInSession;
459: }
460:
461: protected Object convert(PersistentObject po, Class poClass,
462: boolean forModification) {
463: Object value = po;
464: if (mapper.mappingExists(null, poClass)) {
465: value = mapper.convertPoToBean(po, forModification);
466: }
467: return value;
468: }
469:
470: protected Collection convertCollection(Collection sourceCollection,
471: boolean forModification) {
472: if (DatabasePersistencyImpl.isCollectionOfPOs(sourceCollection)) {
473: Collection targetCollection = newCollection(sourceCollection);
474: convertCollection(sourceCollection, targetCollection,
475: forModification);
476: return targetCollection;
477: } else {
478: return sourceCollection;
479: }
480: }
481:
482: protected void convertCollection(Collection collectionOfPos,
483: Collection targetCollection, boolean forModification) {
484: for (Iterator iterator = collectionOfPos.iterator(); iterator
485: .hasNext();) {
486: PersistentObject po = (PersistentObject) iterator.next();
487: targetCollection.add(convert(po, forModification));
488: }
489: }
490:
491: protected Collection newCollection(Collection source) {
492: int size = source == null ? 0 : source.size();
493: if (source instanceof Set) {
494: return new HashSet(size);
495: } else {
496: return new ArrayList(size);
497: }
498: }
499:
500: public boolean isUseBatchModify() {
501: return persistency.isUseBatchModify();
502: }
503:
504: public DatabasePolicy getDatabasePolicy() {
505: return persistency.getDatabasePolicy();
506: }
507:
508: public QueryFactory getQueryFactory() {
509: return persistency.getQueryFactory();
510: }
511:
512: public CallFactory getCallFactory() {
513: return persistency.getCallFactory();
514: }
515:
516: public SelectQueryBuilder getSelectQueryBuilder() {
517: return persistency.getSelectQueryBuilder();
518: }
519:
520: public void registerTypeHandler(ColumnType columnType,
521: TypeHandler typeHandler) {
522: persistency.registerTypeHandler(columnType, typeHandler);
523: }
524:
525: public Object reset(Object[] params) {
526: return persistency.reset(params);
527: }
528:
529: /**
530: * Return underlying PO persistency
531: *
532: * @return underlying PO persistency
533: */
534: public Persistency getPersistency() {
535: return persistency;
536: }
537:
538: public TransactionManager getTransactionManager() {
539: return persistency.getTransactionManager();
540: }
541:
542: public Mapper getMapper() {
543: return mapper;
544: }
545:
546: public AdHocPoBeanConverter getAdHocPoMappingHandler() {
547: return adHocPoBeanConverter;
548: }
549:
550: }
|