001: /**********************************************************************
002: Copyright (c) 2002 Kelly Grizzle and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015: Contributors:
016: 2002 Mike Martin - unknown changes
017: 2003 Andy Jefferson - commented
018: 2003 Erik Bengtson - optimistic transaction
019: ...
020: **********************************************************************/package org.jpox.jdo.state;
021:
022: import javax.jdo.JDOUserException;
023:
024: import org.jpox.FetchPlan;
025: import org.jpox.Transaction;
026: import org.jpox.state.IllegalStateTransitionException;
027: import org.jpox.state.LifeCycleState;
028: import org.jpox.StateManager;
029:
030: /**
031: * Class representing the life cycle state of PersistentNontransactional
032: *
033: * @version $Revision: 1.10 $
034: **/
035: class PersistentNontransactional extends LifeCycleState {
036: /** Protected Constructor to prevent external instantiation. */
037: protected PersistentNontransactional() {
038: isPersistent = true;
039: isDirty = false;
040: isNew = false;
041: isDeleted = false;
042: isTransactional = false;
043:
044: stateType = P_NONTRANS;
045: }
046:
047: /**
048: * Method to transition to delete persistent.
049: * @param sm StateManager.
050: * @return new LifeCycle state.
051: **/
052: public LifeCycleState transitionDeletePersistent(StateManager sm) {
053: sm.clearLoadedFlags();
054: return changeState(sm, P_DELETED);
055: }
056:
057: /**
058: * Method to transition to transactional.
059: * @param sm StateManager.
060: * @return new LifeCycle state.
061: **/
062: public LifeCycleState transitionMakeTransactional(StateManager sm) {
063: sm.refreshLoadedFields();
064: return changeState(sm, P_CLEAN);
065: }
066:
067: /**
068: * Method to transition to transient.
069: * @param sm StateManager.
070: * @param useFetchPlan to make transient the fields in the fetch plan
071: * @return new LifeCycle state.
072: **/
073: public LifeCycleState transitionMakeTransient(StateManager sm,
074: boolean useFetchPlan, boolean detachAllOnCommit) {
075: if (useFetchPlan) {
076: sm.loadUnloadedFieldsInFetchPlan();
077: }
078: return changeState(sm, TRANSIENT);
079: }
080:
081: /**
082: * Method to transition to commit state.
083: * @param sm StateManager.
084: * @param tx the Transaction been committed.
085: * @return new LifeCycle state.
086: **/
087: public LifeCycleState transitionCommit(StateManager sm,
088: Transaction tx) {
089: throw new IllegalStateTransitionException(this , "commit", sm);
090: }
091:
092: /**
093: * Method to transition to rollback state.
094: * @param sm StateManager.
095: * @param tx The transaction
096: * @return new LifeCycle state.
097: **/
098: public LifeCycleState transitionRollback(StateManager sm,
099: Transaction tx) {
100: throw new IllegalStateTransitionException(this , "rollback", sm);
101: }
102:
103: /**
104: * Method to transition to refresh state.
105: * @param sm StateManager.
106: * @return new LifeCycle state.
107: **/
108: public LifeCycleState transitionRefresh(StateManager sm) {
109: // Refresh the FetchPlan fields and unload all others
110: sm.refreshFieldsInFetchPlan();
111: sm.unloadNonFetchPlanFields();
112:
113: return this ;
114: }
115:
116: /**
117: * Method to transition to evict state.
118: * @param sm StateManager.
119: * @return new LifeCycle state.
120: **/
121: public LifeCycleState transitionEvict(StateManager sm) {
122: sm.clearNonPrimaryKeyFields();
123: sm.clearSavedFields();
124: return changeState(sm, HOLLOW);
125: }
126:
127: /**
128: * Method to transition to read-field state.
129: * @param sm StateManager.
130: * @param isLoaded if the field was previously loaded.
131: * @return new LifeCycle state.
132: **/
133: public LifeCycleState transitionReadField(StateManager sm,
134: boolean isLoaded) {
135: Transaction tx = sm.getObjectManager().getTransaction();
136: if (!tx.isActive() && !tx.getNontransactionalRead()) {
137: throw new JDOUserException(LOCALISER.msg("027002"), sm
138: .getInternalObjectId());
139: }
140: if (tx.isActive() && !tx.getOptimistic()) {
141: // Save the fields for rollback.
142: sm.saveFields();
143: sm.refreshLoadedFields();
144: return changeState(sm, P_CLEAN);
145: } else {
146: return this ;
147: }
148: }
149:
150: /**
151: * Method to transition to write-field state.
152: * @param sm StateManager.
153: * @return new LifeCycle state.
154: **/
155: public LifeCycleState transitionWriteField(StateManager sm) {
156: Transaction tx = sm.getObjectManager().getTransaction();
157: if (tx.isActive()) {
158: // Save the fields for rollback.
159: sm.saveFields();
160:
161: // This line was present previously (from 1.1.0-beta-4 approx until 1.1.4) but resulted in optimistic tests
162: // failing due to refreshing all fields (including version) from the datastore when only one was updated
163: // No idea why it was here since it had no comment to explain its purpose but is now commented out
164: // If it is required please provide a comment what is its role relative to the spec
165: // sm.refreshLoadedFields();
166:
167: return changeState(sm, P_DIRTY);
168: } else {
169: // Save the fields for rollback.
170: sm.saveFields();
171: return changeState(sm, P_NONTRANS_DIRTY);
172: }
173: }
174:
175: /**
176: * Method to transition to retrieve state.
177: * @param sm StateManager.
178: * @param fgOnly only the current fetch group fields
179: * @return new LifeCycle state.
180: **/
181: public LifeCycleState transitionRetrieve(StateManager sm,
182: boolean fgOnly) {
183: Transaction tx = sm.getObjectManager().getTransaction();
184: if (tx.isActive() && !tx.getOptimistic()) {
185: // Save the fields for rollback.
186: sm.saveFields();
187: if (fgOnly) {
188: sm.loadUnloadedFieldsInFetchPlan();
189: } else {
190: sm.loadUnloadedFields();
191: }
192: return changeState(sm, P_CLEAN);
193: } else if (tx.isActive() && tx.getOptimistic()) {
194: // Save the fields for rollback.
195: sm.saveFields(); //TODO this is wrong... saving all the time, retrieve is asked... side effects besides performance?
196: if (fgOnly) {
197: sm.loadUnloadedFieldsInFetchPlan();
198: } else {
199: sm.loadUnloadedFields();
200: }
201: return this ;
202: } else {
203: if (fgOnly) {
204: sm.loadUnloadedFieldsInFetchPlan();
205: } else {
206: sm.loadUnloadedFields();
207: }
208: return this ;
209: }
210: }
211:
212: /**
213: * Method to transition to retrieve state.
214: * @param sm StateManager.
215: * @param fetchPlan the fetch plan to load fields
216: * @return new LifeCycle state.
217: **/
218: public LifeCycleState transitionRetrieve(StateManager sm,
219: FetchPlan fetchPlan) {
220: Transaction tx = sm.getObjectManager().getTransaction();
221: if (tx.isActive() && !tx.getOptimistic()) {
222: // Save the fields for rollback.
223: sm.saveFields();
224: sm.loadUnloadedFieldsOfClassInFetchPlan(fetchPlan);
225: return changeState(sm, P_CLEAN);
226: } else if (tx.isActive() && tx.getOptimistic()) {
227: // Save the fields for rollback.
228: sm.saveFields(); //TODO this is wrong... saving all the time, retrieve is asked... side effects besides performance?
229: sm.loadUnloadedFieldsOfClassInFetchPlan(fetchPlan);
230: return this ;
231: } else {
232: sm.loadUnloadedFieldsOfClassInFetchPlan(fetchPlan);
233: return this ;
234: }
235: }
236:
237: /**
238: * Method to transition when serialised.
239: * @param sm State Manager
240: * @return The new LifeCycle state
241: */
242: public LifeCycleState transitionSerialize(StateManager sm) {
243: Transaction tx = sm.getObjectManager().getTransaction();
244: if (tx.isActive() && !tx.getOptimistic()) {
245: return changeState(sm, P_CLEAN);
246: }
247: return this ;
248: }
249:
250: /**
251: * Method to transition to detached-clean.
252: * @param sm StateManager.
253: * @return new LifeCycle state.
254: */
255: public LifeCycleState transitionDetach(StateManager sm) {
256: return changeState(sm, DETACHED_CLEAN);
257: }
258:
259: /**
260: * Method to return a string version of this object.
261: * @return The string "P_NONTRANS".
262: **/
263: public String toString() {
264: return "P_NONTRANS";
265: }
266: }
|