001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.ejb;
012:
013: import com.versant.core.metadata.ClassMetaData;
014: import com.versant.core.metadata.ModelMetaData;
015: import com.versant.core.metadata.MDStatics;
016: import com.versant.core.metadata.FieldMetaData;
017: import com.versant.core.jdo.*;
018: import com.versant.core.common.*;
019:
020: import javax.jdo.spi.StateManager;
021: import javax.jdo.spi.PersistenceCapable;
022: import javax.jdo.PersistenceManager;
023:
024: /**
025: * StateManager used for ejb3
026: */
027: public class StateManagerImp implements VersantStateManager {
028: private EMProxy emProxy;
029: OID oid;
030: public ClassMetaData cmd;
031: private ModelMetaData modelMetaData;
032: State state;
033: private State origState;
034: PersistenceCapable pc;
035: private byte jdoFlags;
036: /**
037: * array that indicates which fields the pc instance contains.
038: */
039: private boolean[] loadedFields;
040: private boolean addedForDelete;
041: /**
042: * If the entity is marked to be removed.
043: */
044: private boolean removed;
045: private State toStoreState;
046:
047: public StateManagerImp(EMProxy em, ModelMetaData modelMetaData) {
048: this .emProxy = em;
049: this .modelMetaData = modelMetaData;
050: }
051:
052: /**
053: * Accepts a {@link LifeCycleStatus.NEW} entity and manage it.
054: *
055: * @param pc
056: */
057: public void manageNew(PersistenceCapable pc, LocalCache cache,
058: int newOidVal) {
059: this .pc = (PersistenceCapable) pc;
060: pc.jdoReplaceStateManager(this );
061: cmd = modelMetaData.getClassMetaData(pc.getClass());
062: loadedFields = new boolean[cmd.stateFields.length];
063:
064: //create the state instance
065: state = cmd.createState();
066: state.setClassMetaData(cmd);
067:
068: //ask to provide all managed fields to state
069: pc.jdoProvideFields(cmd.allManagedFieldNosArray);
070: //create a new OID
071: oid = createNewOid(newOidVal);
072:
073: //add by newOid
074: cache.add(oid, this );
075: //add by realOID if available
076: if (oid.isNew() && oid.getRealOID() != null) {
077: cache.add(oid.getRealOID(), this );
078: }
079:
080: //mark all fields as READ_OK
081: updateJdoFlag(pc, PersistenceCapable.LOAD_REQUIRED);
082: //set all fields as loaded
083: setBooleanArray(loadedFields, true);
084: }
085:
086: /**
087: * Manage an existing instance.
088: * @param oidVal
089: * @param stateVal
090: */
091: public void manage(OID oidVal, State stateVal, LocalCache cache) {
092: this .oid = oidVal;
093: cmd = stateVal.getClassMetaData(modelMetaData);
094: try {
095: pc = (PersistenceCapable) cmd.cls.newInstance();
096: } catch (Exception e) {
097: throw new RuntimeException("The class '"
098: + cmd.cls.getName()
099: + "' does not have a default constructor", e);
100: }
101: loadedFields = new boolean[cmd.stateFields.length];
102:
103: pc.jdoReplaceStateManager(this );
104:
105: //create the state instance
106: state = cmd.createState();
107: state.setClassMetaData(cmd);
108: state.updateFrom(stateVal);
109:
110: updateOrigState(stateVal);
111:
112: //add to cache
113: cache.add(oidVal, this );
114:
115: updateJdoFlag(pc, PersistenceCapable.LOAD_REQUIRED);
116:
117: //fill the pk fields on the pc
118: if (cmd.identityType == MDStatics.IDENTITY_TYPE_APPLICATION) {
119: state.copyFields(oid);
120: pc.jdoReplaceFields(cmd.pkFieldNos);
121: }
122: }
123:
124: private void updateOrigState(State aState) {
125: if (aState == null)
126: return;
127: if (origState == null) {
128: origState = cmd.createState();
129: origState.setClassMetaData(cmd);
130: }
131: if (cmd.changedOptimisticLocking) {
132: origState.updateNonFilled(aState);
133: } else if (cmd.optimisticLockingField != null) {
134: origState.copyOptimisticLockingField(aState);
135: }
136: }
137:
138: private void updateJdoFlag(PersistenceCapable pc, byte val) {
139: jdoFlags = val;
140: pc.jdoReplaceFlags();
141: }
142:
143: private void setBooleanArray(boolean[] fields, boolean val) {
144: for (int i = fields.length - 1; i >= 0; i--) {
145: fields[i] = val;
146: }
147: }
148:
149: /**
150: * Do post commit updated.
151: */
152: public void postStore(StatesReturned sr, boolean flush) {
153: if (removed) {
154: } else {
155: EntrySet.Entry e = sr.getEntry(oid);
156: if (e != null) {
157: updateAutoFields((State) e.getValue());
158: if (flush) {
159: updateOrigState((State) e.getValue());
160: }
161: }
162: if (oid.isNew()) {
163: //updates the real oid on the newOid and also update this.oid reference to the realOID
164: oid = ((NewObjectOID) oid)
165: .setRealOid(((OID) e.getKey()).getRealOID());
166: state.copyFields(oid);
167: }
168: pc.jdoReplaceFields(cmd.dfgAbsFieldNos);
169: if (cmd.autoSetManagedFieldNos.length > 0) {
170: pc.jdoReplaceFields(cmd.autoSetManagedFieldNos);
171: }
172: state.makeClean();
173: }
174: }
175:
176: /**
177: * Called on commit to detach the pc.
178: * @param dsm
179: */
180: public void detachOnCommit(VersantDetachedStateManager dsm) {
181: //already detached
182: if (state == null)
183: return;
184: //do not detach if removed
185: if (removed) {
186: pc.jdoReplaceStateManager(null);
187: } else {
188: //load dfg if non loaded
189: if (!state.containsFetchGroup(cmd.fetchGroups[0])) {
190: getEm().fetchState(this , cmd.fetchGroups[0]);
191: }
192:
193: //fill the pc with the dfg
194: pc.jdoReplaceFields(cmd.dfgAbsFieldNos);
195:
196: ((VersantDetachable) pc).versantSetOID(getExternalOID());
197: ((VersantDetachable) pc).versantSetVersion(state
198: .getOptimisticLockingValue());
199: ((VersantDetachable) pc).jdoReplaceStateManager(dsm);
200: //todo add a batch update for loaded fields
201:
202: for (int i = 0; i < loadedFields.length; i++) {
203: if (loadedFields[i])
204: ((VersantDetachable) pc)
205: .versantSetLoaded(cmd.stateFields[i].managedFieldNo);
206: }
207: }
208: state.clear();
209: state = null;
210: pc = null;
211: }
212:
213: public Object getOptimisticLockingValue() {
214: if (oid.isNew())
215: return null;
216: // getEm().checkNonTxRead();
217: // loadRequiredFetchGroup();
218: return state.getOptimisticLockingValue();
219: }
220:
221: private Object getExternalOID() {
222: if (oid.isNew())
223: throw new RuntimeException("Not to be called on new oid");
224: if (cmd.identityType == MDStatics.IDENTITY_TYPE_DATASTORE) {
225: return new VersantOid(oid, modelMetaData, oid.isResolved());
226: } else if (cmd.identityType == MDStatics.IDENTITY_TYPE_APPLICATION) {
227: if (cmd.objectIdClass == null) {
228: return new VersantOid(oid, modelMetaData, oid
229: .isResolved());
230: } else {
231: throw new RuntimeException("NOT IMPLEMENTED");
232: // Object pcID = jdoImplHelper.newObjectIdInstance(
233: // classMetaData.cls);
234: // oid.populateObjectIdClassInstance(pcID);
235: // return pcID;
236: }
237: } else {
238: throw BindingSupportImpl.getInstance().unsupported();
239: }
240: }
241:
242: private EntityManagerImp getEm() {
243: return emProxy.getEm();
244: }
245:
246: public void makeDirty(PersistenceCapable persistenceCapable,
247: int managedFieldNo) {
248: //To change body of implemented methods use File | Settings | File Templates.
249: }
250:
251: public void fillNewAppPKField(int fieldNo) {
252: if (oid.isNew()) {
253: NewObjectOID newObjectOID = (NewObjectOID) oid;
254: if (newObjectOID.realOID == null) {
255: if (cmd.postInsertKeyGenerator) {
256: getEm().flush();
257: } else {
258: newObjectOID.realOID = getEm().storageMan
259: .createOID(cmd);
260: state.copyFields(newObjectOID.realOID);
261: pc.jdoReplaceFields(cmd.pkFieldNos);
262: }
263: }
264: }
265: }
266:
267: /**
268: * Update the state with autoset fields returned from the store operation.
269: */
270: public void updateAutoFields(State autoS) {
271: if (autoS != null && cmd.hasAutoSetFields) {
272: this .state.updateFrom(autoS);
273: }
274: }
275:
276: public OID getOID() {
277: return oid;
278: }
279:
280: public PersistenceCapable getPersistenceCapable() {
281: return pc;
282: }
283:
284: public void flush() {
285: }
286:
287: /**
288: * Manage all the references as per spec. Should look at the annotations
289: * and decide on which references to follow.
290: */
291: public void manageReferences() {
292: }
293:
294: /**
295: * Must create an oid for a {@link LifeCycleStatus.NEW} instance.
296: */
297: private OID createNewOid(int newOIDVal) {
298: NewObjectOID newOID = cmd.createNewObjectOID();
299: newOID.idNo = newOIDVal;
300: getRealOIDIfAppId(cmd, newOID, state);
301: return newOID;
302: }
303:
304: /**
305: * Create the real oid for this instance if possible. This is done by looking
306: * at
307: * @return
308: */
309: public static OID getRealOIDIfAppId(ClassMetaData cmd,
310: NewObjectOID newOID, State state) {
311: if (newOID.realOID != null)
312: return newOID.realOID;
313: if (!cmd.postInsertKeyGenerator
314: && cmd.identityType == MDStatics.IDENTITY_TYPE_APPLICATION
315: && state.containsValidAppIdFields()) {
316:
317: final OID rOid = cmd.createOID(true);
318: state.copyKeyFields(rOid);
319:
320: newOID.realOID = rOid;
321: return rOid;
322: }
323: return null;
324: }
325:
326: /**
327: * If this instance is marked for removal/Deletion
328: * @return
329: */
330: public boolean isRemoved() {
331: return removed;
332: }
333:
334: /**
335: * Mark this entity as removed
336: */
337: public void remove() {
338: emProxy.getEm().addToTxList(this );
339: removed = true;
340: }
341:
342: FieldMetaData getFmd(int absFieldNo) {
343: return cmd.managedFields[absFieldNo];
344: }
345:
346: /**
347: * This is called on all transactional objects so that they can prepare for
348: * the commit or flush. If the state was deleted it will call add itself
349: * to the list of instances to be deleted etc.
350: */
351: public void prepareCommitOrFlush(boolean commit,
352: DeletePacket toDelete, StatesToStore toStore) {
353: /**
354: * Add all the instance that must be deleted to the toBeDeleted collection.
355: * If the oid is new then it must not be added because it is not in the db and therefore
356: * not to be removed.
357: */
358: if (isRemoved()) {
359: addForDelete(toDelete);
360: //ignore
361: } else if (isDirty()) {
362:
363: // clear transactional fields if this is a commit
364: if (commit)
365: state.clearTransactionNonPersistentFields();
366:
367: State toStoreState = createToStoreState();
368: oid.resolve(state);
369:
370: // If nothing is copied to toStoreState then only transactional
371: // fields were dirty. If this is a commit and the instance is new
372: // then persist it anyway.
373: if (!state.fillToStoreState(toStoreState, getEm(), this )
374: && (!commit || !oid.isNew())) {
375: return;
376: }
377: addToStoreOidContainer(toStoreState, oid.isNew(), toStore);
378: }
379: }
380:
381: private void addToStoreOidContainer(State aState, boolean aNew,
382: StatesToStore toStore) {
383: if (aNew) {
384: toStore.add(oid, aState, null, aNew
385: && cmd.postInsertKeyGenerator);
386: } else {
387: toStore.add(oid, aState, origState, aNew
388: && cmd.postInsertKeyGenerator);
389: }
390: }
391:
392: /**
393: * Add this instance to the todeletelist. This must not be done for instances
394: * that is new. Instance that is flushed must be included.
395: */
396: private void addForDelete(DeletePacket toDelete) {
397: if (!oid.isNew() && !addedForDelete) {
398: toDelete.add(oid, null);
399: addedForDelete = true;
400: }
401: }
402:
403: private State createToStoreState() {
404: if (toStoreState == null) {
405: toStoreState = cmd.createState();
406: toStoreState.setClassMetaData(cmd);
407: } else {
408: toStoreState.clear();
409: }
410: return toStoreState;
411: }
412:
413: /**
414: * If this sm must be flushed to the store.
415: * @return
416: */
417: public boolean isDirty() {
418: return oid.isNew() || state.isDirty();
419: }
420:
421: public OID getInternalOID(PersistenceCapable pc) {
422: return null; //To change body of implemented methods use File | Settings | File Templates.
423: }
424:
425: public Object getObjectById(Object oid, boolean b) {
426: return null; //To change body of implemented methods use File | Settings | File Templates.
427: }
428:
429: public PCStateMan getInternalSM(PersistenceCapable pc) {
430: return null; //To change body of implemented methods use File | Settings | File Templates.
431: }
432:
433: public PersistenceManager getPersistenceManager() {
434: return getEm();
435: }
436:
437: public byte replacingFlags(PersistenceCapable persistenceCapable) {
438: return jdoFlags;
439: }
440:
441: public StateManager replacingStateManager(
442: PersistenceCapable persistenceCapable,
443: StateManager stateManager) {
444: return stateManager;
445: }
446:
447: public boolean isDirty(PersistenceCapable persistenceCapable) {
448: return false;
449: }
450:
451: public boolean isTransactional(PersistenceCapable persistenceCapable) {
452: return false;
453: }
454:
455: public boolean isPersistent(PersistenceCapable persistenceCapable) {
456: return false;
457: }
458:
459: public boolean isNew(PersistenceCapable persistenceCapable) {
460: return false;
461: }
462:
463: public boolean isDeleted(PersistenceCapable persistenceCapable) {
464: return false;
465: }
466:
467: public PersistenceManager getPersistenceManager(
468: PersistenceCapable persistenceCapable) {
469: return getEm();
470: }
471:
472: public void makeDirty(PersistenceCapable persistenceCapable,
473: String s) {
474: //To change body of implemented methods use File | Settings | File Templates.
475: }
476:
477: public Object getObjectId(PersistenceCapable persistenceCapable) {
478: return null;
479: }
480:
481: public Object getTransactionalObjectId(
482: PersistenceCapable persistenceCapable) {
483: return null; //To change body of implemented methods use File | Settings | File Templates.
484: }
485:
486: public boolean isLoaded(PersistenceCapable persistenceCapable, int i) {
487: return loadedFields[getFmd(i).stateFieldNo];
488: }
489:
490: public void preSerialize(PersistenceCapable persistenceCapable) {
491: //To change body of implemented methods use File | Settings | File Templates.
492: }
493:
494: public boolean getBooleanField(
495: PersistenceCapable persistenceCapable, int i, boolean b) {
496: FieldMetaData fmd = getFmd(i);
497: loadedFields[fmd.stateFieldNo] = true;
498: return state.getBooleanField(getFmd(i).stateFieldNo);
499: }
500:
501: public char getCharField(PersistenceCapable persistenceCapable,
502: int i, char c) {
503: FieldMetaData fmd = getFmd(i);
504: loadedFields[fmd.stateFieldNo] = true;
505: return state.getCharField(getFmd(i).stateFieldNo);
506: }
507:
508: public byte getByteField(PersistenceCapable persistenceCapable,
509: int i, byte b) {
510: FieldMetaData fmd = getFmd(i);
511: loadedFields[fmd.stateFieldNo] = true;
512: return state.getByteField(getFmd(i).stateFieldNo);
513: }
514:
515: public short getShortField(PersistenceCapable persistenceCapable,
516: int i, short i1) {
517: FieldMetaData fmd = getFmd(i);
518: loadedFields[fmd.stateFieldNo] = true;
519: return state.getShortField(getFmd(i).stateFieldNo);
520: }
521:
522: public int getIntField(PersistenceCapable persistenceCapable,
523: int i, int i1) {
524: FieldMetaData fmd = getFmd(i);
525: loadedFields[fmd.stateFieldNo] = true;
526: return state.getIntField(getFmd(i).stateFieldNo);
527: }
528:
529: public long getLongField(PersistenceCapable persistenceCapable,
530: int i, long l) {
531: FieldMetaData fmd = getFmd(i);
532: loadedFields[fmd.stateFieldNo] = true;
533: return state.getLongField(getFmd(i).stateFieldNo);
534: }
535:
536: public float getFloatField(PersistenceCapable persistenceCapable,
537: int i, float v) {
538: FieldMetaData fmd = getFmd(i);
539: loadedFields[fmd.stateFieldNo] = true;
540: return state.getFloatField(getFmd(i).stateFieldNo);
541: }
542:
543: public double getDoubleField(PersistenceCapable persistenceCapable,
544: int i, double v) {
545: FieldMetaData fmd = getFmd(i);
546: loadedFields[fmd.stateFieldNo] = true;
547: return state.getDoubleField(getFmd(i).stateFieldNo);
548: }
549:
550: public String getStringField(PersistenceCapable persistenceCapable,
551: int i, String s) {
552: FieldMetaData fmd = getFmd(i);
553: loadedFields[fmd.stateFieldNo] = true;
554: return state.getStringField(getFmd(i).stateFieldNo);
555: }
556:
557: public Object getObjectField(PersistenceCapable persistenceCapable,
558: int i, Object o) {
559: return state.getObjectField(getFmd(i).stateFieldNo, pc,
560: getEm(), oid);
561: }
562:
563: public void setBooleanField(PersistenceCapable persistenceCapable,
564: int i, boolean currentVal, boolean newVal) {
565: emProxy.getEm().addToTxList(this );
566: state.setBooleanField(getFmd(i).stateFieldNo, newVal);
567: pc.jdoReplaceField(i);
568: }
569:
570: public void setCharField(PersistenceCapable persistenceCapable,
571: int i, char currentVal, char newVal) {
572: emProxy.getEm().addToTxList(this );
573: state.setCharField(getFmd(i).stateFieldNo, newVal);
574: pc.jdoReplaceField(i);
575: }
576:
577: public void setByteField(PersistenceCapable persistenceCapable,
578: int i, byte currentVal, byte newVal) {
579: emProxy.getEm().addToTxList(this );
580: state.setByteField(getFmd(i).stateFieldNo, newVal);
581: pc.jdoReplaceField(i);
582: }
583:
584: public void setShortField(PersistenceCapable persistenceCapable,
585: int i, short currentVal, short newVal) {
586: emProxy.getEm().addToTxList(this );
587: state.setShortField(getFmd(i).stateFieldNo, newVal);
588: pc.jdoReplaceField(i);
589: }
590:
591: public void setIntField(PersistenceCapable persistenceCapable,
592: int i, int currentVal, int newVal) {
593: emProxy.getEm().addToTxList(this );
594: state.setIntField(getFmd(i).stateFieldNo, newVal);
595: pc.jdoReplaceField(i);
596: }
597:
598: public void setLongField(PersistenceCapable persistenceCapable,
599: int i, long currentVal, long newVal) {
600: emProxy.getEm().addToTxList(this );
601: state.setLongField(getFmd(i).stateFieldNo, newVal);
602: pc.jdoReplaceField(i);
603: }
604:
605: public void setFloatField(PersistenceCapable persistenceCapable,
606: int i, float currentVal, float newVal) {
607: emProxy.getEm().addToTxList(this );
608: state.setFloatField(getFmd(i).stateFieldNo, newVal);
609: pc.jdoReplaceField(i);
610: }
611:
612: public void setDoubleField(PersistenceCapable persistenceCapable,
613: int i, double currentVal, double newVal) {
614: emProxy.getEm().addToTxList(this );
615: state.setDoubleField(getFmd(i).stateFieldNo, newVal);
616: pc.jdoReplaceField(i);
617: }
618:
619: public void setStringField(PersistenceCapable persistenceCapable,
620: int i, String currentVal, String newVal) {
621: emProxy.getEm().addToTxList(this );
622: state.setStringField(getFmd(i).stateFieldNo, newVal);
623: pc.jdoReplaceField(i);
624: }
625:
626: public void setObjectField(PersistenceCapable persistenceCapable,
627: int i, Object currentVal, Object newVal) {
628: emProxy.getEm().addToTxList(this );
629: state.setObjectField(getFmd(i).stateFieldNo, newVal);
630: pc.jdoReplaceField(i);
631: }
632:
633: public void providedBooleanField(
634: PersistenceCapable persistenceCapable, int i, boolean val) {
635: state.setBooleanField(getFmd(i).stateFieldNo, val);
636: }
637:
638: public void providedCharField(
639: PersistenceCapable persistenceCapable, int i, char val) {
640: state.setCharField(getFmd(i).stateFieldNo, val);
641: }
642:
643: public void providedByteField(
644: PersistenceCapable persistenceCapable, int i, byte val) {
645: state.setByteField(getFmd(i).stateFieldNo, val);
646: }
647:
648: public void providedShortField(
649: PersistenceCapable persistenceCapable, int i, short val) {
650: state.setShortField(getFmd(i).stateFieldNo, val);
651: }
652:
653: public void providedIntField(PersistenceCapable persistenceCapable,
654: int i, int val) {
655: state.setIntField(getFmd(i).stateFieldNo, val);
656: }
657:
658: public void providedLongField(
659: PersistenceCapable persistenceCapable, int i, long val) {
660: state.setLongField(getFmd(i).stateFieldNo, val);
661: }
662:
663: public void providedFloatField(
664: PersistenceCapable persistenceCapable, int i, float val) {
665: state.setFloatField(getFmd(i).stateFieldNo, val);
666: }
667:
668: public void providedDoubleField(
669: PersistenceCapable persistenceCapable, int i, double val) {
670: state.setDoubleField(getFmd(i).stateFieldNo, val);
671: }
672:
673: public void providedStringField(
674: PersistenceCapable persistenceCapable, int i, String val) {
675: state.setStringField(getFmd(i).stateFieldNo, val);
676: }
677:
678: public void providedObjectField(
679: PersistenceCapable persistenceCapable, int i, Object val) {
680: state.setObjectField(getFmd(i).stateFieldNo, val);
681: }
682:
683: public boolean replacingBooleanField(
684: PersistenceCapable persistenceCapable, int i) {
685: FieldMetaData fmd = getFmd(i);
686: loadedFields[fmd.stateFieldNo] = true;
687: return state.getBooleanField(getFmd(i).stateFieldNo);
688: }
689:
690: public char replacingCharField(
691: PersistenceCapable persistenceCapable, int i) {
692: FieldMetaData fmd = getFmd(i);
693: loadedFields[fmd.stateFieldNo] = true;
694: return state.getCharField(getFmd(i).stateFieldNo);
695: }
696:
697: public byte replacingByteField(
698: PersistenceCapable persistenceCapable, int i) {
699: FieldMetaData fmd = getFmd(i);
700: loadedFields[fmd.stateFieldNo] = true;
701: return state.getByteField(getFmd(i).stateFieldNo);
702: }
703:
704: public short replacingShortField(
705: PersistenceCapable persistenceCapable, int i) {
706: FieldMetaData fmd = getFmd(i);
707: loadedFields[fmd.stateFieldNo] = true;
708: return state.getShortField(getFmd(i).stateFieldNo);
709: }
710:
711: public int replacingIntField(PersistenceCapable persistenceCapable,
712: int i) {
713: FieldMetaData fmd = getFmd(i);
714: loadedFields[fmd.stateFieldNo] = true;
715: return state.getIntField(getFmd(i).stateFieldNo);
716: }
717:
718: public long replacingLongField(
719: PersistenceCapable persistenceCapable, int i) {
720: FieldMetaData fmd = getFmd(i);
721: loadedFields[fmd.stateFieldNo] = true;
722: return state.getLongField(getFmd(i).stateFieldNo);
723: }
724:
725: public float replacingFloatField(
726: PersistenceCapable persistenceCapable, int i) {
727: FieldMetaData fmd = getFmd(i);
728: loadedFields[fmd.stateFieldNo] = true;
729: return state.getFloatField(getFmd(i).stateFieldNo);
730: }
731:
732: public double replacingDoubleField(
733: PersistenceCapable persistenceCapable, int i) {
734: FieldMetaData fmd = getFmd(i);
735: loadedFields[fmd.stateFieldNo] = true;
736: return state.getDoubleField(getFmd(i).stateFieldNo);
737: }
738:
739: public String replacingStringField(
740: PersistenceCapable persistenceCapable, int i) {
741: FieldMetaData fmd = getFmd(i);
742: loadedFields[fmd.stateFieldNo] = true;
743: return state.getStringField(getFmd(i).stateFieldNo);
744: }
745:
746: public Object replacingObjectField(
747: PersistenceCapable persistenceCapable, int i) {
748: FieldMetaData fmd = getFmd(i);
749: loadedFields[fmd.stateFieldNo] = true;
750: return state.getObjectField(getFmd(i).stateFieldNo, pc,
751: getEm(), oid);
752: }
753:
754: public void firePostStore(LifecycleListenerManager listeners) {
755: // pc may be null if the instance has been deleted
756: if (pc != null) {
757: listeners.firePostStore(pc);
758: }
759: }
760:
761: public void persistReferences(
762: com.versant.core.ejb.common.EntrySet mergeSet) {
763: FieldMetaData[] fmdsToPersist = cmd.managedFields;
764: for (int i = 0; i < fmdsToPersist.length; i++) {
765: FieldMetaData fmd = fmdsToPersist[i];
766: if ((fmd.cascadeType & MDStatics.CASCADE_PERSIST) == 0)
767: continue;
768: switch (fmd.category) {
769: case MDStatics.CATEGORY_REF:
770: case MDStatics.CATEGORY_POLYREF:
771: Object ref = state.getObjectField(fmd.stateFieldNo, pc,
772: getEm(), oid);
773: if (ref != null)
774: mergeSet.add(ref);
775:
776: }
777: }
778: }
779:
780: public StateManagerImp mergeReferences(
781: com.versant.core.ejb.common.EntrySet mergeSet) {
782: FieldMetaData[] fmdsToPersist = cmd.managedFields;
783: for (int i = 0; i < fmdsToPersist.length; i++) {
784: FieldMetaData fmd = fmdsToPersist[i];
785: if ((fmd.cascadeType & MDStatics.CASCADE_MERGE) == 0)
786: continue;
787: switch (fmd.category) {
788: case MDStatics.CATEGORY_REF:
789: case MDStatics.CATEGORY_POLYREF:
790: if (state.isDirty(fmd.stateFieldNo)) {
791: Object ref = state.getObjectField(fmd.stateFieldNo,
792: pc, getEm(), oid);
793: if (ref != null) {
794: mergeSet.add(ref);
795: state
796: .setInternalObjectField(
797: fmd.stateFieldNo, getEm()
798: .mergeInternal(ref,
799: mergeSet).pc);
800: loadedFields[fmd.stateFieldNo] = false;
801: }
802:
803: }
804:
805: }
806: }
807: return this ;
808: }
809:
810: public void updateState(State state) {
811: state.updateNonFilled(state);
812: }
813: }
|