KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > runtime > tck > JdoLifecycleTck


1 /**
2  * Copyright (C) 2001-2004 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.speedo.runtime.tck;
19
20 import java.util.Iterator JavaDoc;
21
22 import javax.jdo.Extent;
23 import javax.jdo.JDOHelper;
24 import javax.jdo.PersistenceManager;
25 import javax.jdo.Transaction;
26
27 import org.objectweb.speedo.pobjects.tck.StateTransitionObj;
28 import org.objectweb.speedo.SpeedoTestHelper;
29 import org.objectweb.util.monolog.api.BasicLevel;
30
31
32
33
34
35
36
37     
38
39
40 public class JdoLifecycleTck extends SpeedoTestHelper {
41
42     public static final int TRANSIENT = 0;
43     public static final int PERSISTENT_NEW = 1;
44     public static final int PERSISTENT_CLEAN = 2;
45     public static final int PERSISTENT_DIRTY = 3;
46     public static final int HOLLOW = 4;
47     public static final int TRANSIENT_CLEAN = 5;
48     public static final int TRANSIENT_DIRTY = 6;
49     public static final int PERSISTENT_NEW_DELETED = 7;
50     public static final int PERSISTENT_DELETED = 8;
51     public static final int PERSISTENT_NONTRANSACTIONAL = 9;
52     public static final int NUM_STATES = 10;
53     public static final int ILLEGAL_STATE = 10;
54
55     public static final String JavaDoc[] states = {
56             "transient",
57             "persistent-new",
58             "persistent-clean",
59             "persistent-dirty",
60             "hollow",
61             "transient-clean",
62             "transient-dirty",
63             "persistent-new-deleted",
64             "persistent-deleted",
65             "persistent-nontransactional",
66             "illegal"
67     };
68     private static final int IS_PERSISTENT = 0;
69     private static final int IS_TRANSACTIONAL = 1;
70     private static final int IS_DIRTY = 2;
71     private static final int IS_NEW = 3;
72     private static final int IS_DELETED = 4;
73     private static final int NUM_STATUSES = 5;
74
75     /*
76      * This table indicates the values returned by the status interrogation
77      * methods for each state. This is used to determine the current lifecycle
78      * state of an object.
79      */

80     private static final boolean state_statuses[][] = {
81 // IS_PERSISTENT IS_TRANSACTIONAL IS_DIRTY IS_NEW IS_DELETED
82
// transient
83
{ false, false, false, false, false},
84
85 // persistent-new
86
{ true, true, true, true, false},
87
88 // persistent-clean
89
{ true, true, false, false, false},
90
91 // persistent-dirty
92
{ true, true, true, false, false},
93
94 // hollow
95
{ true, false, false, false, false},
96
97 // transient-clean
98
{ false, true, false, false, false},
99
100 // transient-dirty
101
{ false, true, true, false, false},
102
103 // persistent-new-deleted
104
{ true, true, true, true, true},
105
106 // persistent-deleted
107
{ true, true, true, false, true},
108
109 // persistent-nontransactional
110
{ true, false, false, false, false}
111     };
112
113
114 // These values MUST correspond to index in sorted array below.
115
private static final int OPTION_APPLICATIONIDENTITY = 0;
116     private static final int OPTION_ARRAY = 1;
117     private static final int OPTION_ARRAYLIST = 2;
118     private static final int OPTION_CHANGEAPPLICATIONIDENTITY = 3;
119     private static final int OPTION_DATASTOREIDENTITY = 4;
120     private static final int OPTION_HASHMAP = 5;
121     private static final int OPTION_HASHTABLE = 6;
122     private static final int OPTION_LINKEDLIST = 7;
123     private static final int OPTION_LIST = 8;
124     private static final int OPTION_MAP = 9;
125     private static final int OPTION_NONDURABLEIDENTITY = 10;
126     private static final int OPTION_NONTRANSACTIONALREAD = 11;
127     private static final int OPTION_NONTRANSACTIONALWRITE = 12;
128     private static final int OPTION_NULLCOLLECTION = 13;
129     private static final int OPTION_OPTIMISTIC = 14;
130     private static final int OPTION_RETAINVALUES = 15;
131     private static final int OPTION_TRANSIENTTRANSACTIONAL = 16;
132     private static final int OPTION_TREEMAP = 17;
133     private static final int OPTION_TREESET = 18;
134     private static final int OPTION_VECTOR = 19;
135
136     private static boolean[] options = new boolean[OPTION_VECTOR + 1];
137     private static Boolean JavaDoc syncObj = new Boolean JavaDoc(false);
138     private static boolean syncFlag = false;
139
140     private static String JavaDoc[] optionNames = { // MUST be in "natural sorted order"
141
"-ApplicationIdentity",
142             "-Array",
143             "-ArrayList",
144             "-ChangeApplicationIdentity",
145             "-DatastoreIdentity",
146             "-HashMap",
147             "-Hashtable",
148             "-LinkedList",
149             "-List",
150             "-Map",
151             "-NonDurableIdentity",
152             "-NontransactionalRead",
153             "-NontransactionalWrite",
154             "-NullCollection",
155             "-Optimistic",
156             "-RetainValues",
157             "-TransientTransactional",
158             "-TreeMap",
159             "-TreeSet",
160             "-Vector"
161     };
162
163     
164     
165     
166     
167     private PersistenceManager pm;
168     private Transaction transaction;
169     private int scenario;
170     private int operation;
171     private int current_state;
172     private int expected_state;
173     private int new_state;
174     private String JavaDoc pmfName;
175     private String JavaDoc contextFactory;
176     private String JavaDoc providerURL;
177     private String JavaDoc connectionUserName;
178     private String JavaDoc connectionPassword;
179     private String JavaDoc connectionURL;
180
181 private static final String JavaDoc PMFNAME = "pmfName";
182 private static final String JavaDoc JNDICONTEXTFACTORY = "PMFProperties";
183
184 /**
185  * Operations that cause state changes
186  */

187 private static final int MAKEPERSISTENT = 0;
188 private static final int DELETEPERSISTENT = 1;
189 private static final int MAKETRANSACTIONAL = 2;
190 private static final int MAKENONTRANSACTIONAL = 3;
191 private static final int MAKETRANSIENT = 4;
192 private static final int COMMITNORETAINVALUES = 5;
193 private static final int COMMITRETAINVALUES = 6;
194 private static final int ROLLBACKNORETAINVALUES = 7;
195 private static final int ROLLBACKRETAINVALUES = 8;
196 private static final int REFRESHDATASTORE = 9;
197 private static final int REFRESHOPTIMISTIC = 10;
198 private static final int EVICT = 11;
199 private static final int READOUTSIDETX = 12;
200 private static final int READOPTIMISTIC = 13;
201 private static final int READDATASTORE = 14;
202 private static final int WRITEOUTSIDETX = 15;
203 private static final int WRITEINSIDETX = 16;
204
205 private static final String JavaDoc[] operations = {
206     "makePersistent",
207     "deletePersistent",
208     "makeTransactional",
209     "makeNontransactional",
210     "makeTransient",
211     "commit, retainValues=false",
212     "commit, retainValues=true",
213     "rollback, retainValues=false",
214     "rollback, retainValues=true",
215     "refresh with active datastore tx",
216     "refresh with active optimistic tx",
217     "evict",
218     "read field outside tx",
219     "read field with active optimistic tx",
220     "read field with active datastore tx",
221     "write field outside tx",
222     "write field with active tx"
223 };
224 private static final int NUM_OPERATIONS = 17;
225
226 private static final boolean[] closes_transaction =
227 { false, false, false, false, false, true, true, true, true, false,
228 false, false, false, false, false, false, false };
229
230 /**
231  * Illegal state transitions
232  */

233 private static final int UNCHANGED = -1;
234 private static final int ERROR = -2;
235 private static final int IMPOSSIBLE = -3;
236 private static final int NOT_APPLICABLE = -4;
237
238 /**
239  * State transitions
240  */

241
242 public static final int[][] transitions = { // [operation] [current state] = new state
243
// makePersistent
244
{ PERSISTENT_NEW, UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_NEW,
245       PERSISTENT_NEW, UNCHANGED, UNCHANGED, UNCHANGED},
246
247 // deletePersistent
248
{ ERROR, PERSISTENT_NEW_DELETED, PERSISTENT_DELETED, PERSISTENT_DELETED,
249       PERSISTENT_DELETED, ERROR, ERROR, UNCHANGED, UNCHANGED, PERSISTENT_DELETED},
250
251 // makeTransactional
252
{ TRANSIENT_CLEAN, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN,
253       UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN},
254     
255 // makeNontransactional
256
{ ERROR, ERROR, PERSISTENT_NONTRANSACTIONAL, ERROR, UNCHANGED,
257       TRANSIENT, ERROR, ERROR, ERROR, UNCHANGED},
258
259 // makeTransient
260
{ UNCHANGED, ERROR, TRANSIENT, ERROR, TRANSIENT,
261       UNCHANGED, UNCHANGED, ERROR, ERROR, TRANSIENT},
262
263 // commit, retainValues = false
264
{ UNCHANGED, HOLLOW, HOLLOW, HOLLOW, UNCHANGED, UNCHANGED,
265       TRANSIENT_CLEAN, TRANSIENT, TRANSIENT, UNCHANGED},
266
267 // commit, retainValues = true
268
{ UNCHANGED, PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NONTRANSACTIONAL,
269       PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED, TRANSIENT_CLEAN,
270       TRANSIENT, TRANSIENT, UNCHANGED},
271
272 // rollback, retainValues = false
273
{ UNCHANGED, TRANSIENT, HOLLOW, HOLLOW, UNCHANGED, UNCHANGED,
274       TRANSIENT_CLEAN, TRANSIENT, HOLLOW, UNCHANGED},
275
276 // rollback, retainValues = true
277
{ UNCHANGED, TRANSIENT, PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NONTRANSACTIONAL,
278       UNCHANGED, UNCHANGED, TRANSIENT_CLEAN, TRANSIENT, PERSISTENT_NONTRANSACTIONAL, UNCHANGED},
279
280 // refresh with active datastore transaction
281
{ UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
282       UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED},
283
284 // refresh with active optimistic transaction
285
{ UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
286       UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED},
287
288 // evict
289
{ UNCHANGED, UNCHANGED, HOLLOW, UNCHANGED, UNCHANGED,
290       UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, HOLLOW},
291
292 // read field outside transaction
293
{ UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL,
294       UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, UNCHANGED},
295
296 // read field with active optimistic transaction
297
{ UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_NONTRANSACTIONAL,
298       UNCHANGED, UNCHANGED, ERROR, ERROR, UNCHANGED},
299
300 // read field with active datastore transaction
301
{ UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN,
302       UNCHANGED, UNCHANGED, ERROR, ERROR, PERSISTENT_CLEAN},
303
304 // write field outside transaction
305
{ UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL,
306       UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, UNCHANGED},
307     
308 // write field with active transaction
309
{ UNCHANGED, UNCHANGED, PERSISTENT_DIRTY, UNCHANGED, PERSISTENT_DIRTY,
310       TRANSIENT_DIRTY, UNCHANGED, ERROR, ERROR, PERSISTENT_DIRTY}
311 };
312
313     private static final int DATASTORE_TX = 0;
314     private static final int OPTIMISTIC_TX = 1;
315     private static final int NO_TX = 2;
316     
317     private static final String JavaDoc[] scenario_string = {
318         "datastore transaction", "optimistic transaction", "no transaction"
319     };
320     
321     private static final boolean[][] applies_to_scenario = {
322     // Datastore Optimistic No tx
323
{ true, true, false }, // makePersistent
324
{ true, true, false }, // deletePersistent
325
{ true, true, false }, // makeTransactional
326
{ true, true, false }, // makeNontransactional
327
{ true, true, false }, // makeTransient
328
{ true, true, false }, // commit RetainValues = false
329
{ true, true, false }, // commit RetainValues = true
330
{ true, true, false }, // rollback RetainValues = false
331
{ true, true, false }, // rollback RetainValues = true
332
{ true, false, false }, // refresh with active datastore
333
{ false, true, false }, // refresh with active optimistic
334
{ true, true, false }, // evict
335
{ false, false, true }, // read field outside transaction
336
{ false, true, false }, // read field with optimistic
337
{ true, false, false }, // read field with datastore
338
{ false, false, true }, // write field outside transaction
339
{ true, true, false } // write field with active transaction
340
};
341     
342         
343     /**
344      *Reports whether TransientTransactional is supported.
345      */

346     public static boolean isTransientTransactionalSupported()
347     {
348         return options[OPTION_TRANSIENTTRANSACTIONAL];
349     }
350     
351     /**
352      *Reports whether NontransactionalRead is supported.
353      */

354     public static boolean isNontransactionalReadSupported()
355     {
356         return options[OPTION_NONTRANSACTIONALREAD];
357     }
358     
359     /**
360      *Reports whether NontransactionalWrite is supported.
361      */

362     public static boolean isNontransactionalWriteSupported()
363     {
364         return options[OPTION_NONTRANSACTIONALWRITE];
365     }
366     
367     /**
368      *Reports whether RetainValues is supported.
369      */

370     public static boolean isRetainValuesSupported()
371     {
372         return options[OPTION_RETAINVALUES];
373     }
374     
375     /**
376      *Reports whether Optimistic is supported.
377      */

378     public static boolean isOptimisticSupported()
379     {
380         return options[OPTION_OPTIMISTIC];
381     }
382     
383     /**
384      *Reports whether Application Identity is supported.
385      */

386     public static boolean isApplicationIdentitySupported()
387     {
388         return options[OPTION_APPLICATIONIDENTITY];
389     }
390     
391     /**
392      * Reports whether Changing Application Identity is supported.
393      */

394     public static boolean isChangeApplicationIdentitySupported()
395     {
396         return options[OPTION_CHANGEAPPLICATIONIDENTITY];
397     }
398     /**
399      *Reports whether Datastore Identity is supported.
400      */

401     public static boolean isDatastoreIdentitySupported()
402     {
403         return options[OPTION_DATASTOREIDENTITY];
404     }
405     
406     /**
407      *Reports whether Non-Durable Identity is supported.
408      */

409     public static boolean isNonDurableIdentitySupported()
410     {
411         return options[OPTION_NONDURABLEIDENTITY];
412     }
413     
414     /**
415      *Reports whether an <code>ArrayList</code> collection is supported.
416      */

417     public static boolean isArrayListSupported()
418     {
419         return options[OPTION_ARRAYLIST];
420     }
421     
422     /**
423      *Reports whether a <code>HashMap</code> collection is supported.
424      */

425     public static boolean isHashMapSupported()
426     {
427         return options[OPTION_HASHMAP];
428     }
429     
430     /**
431      *Reports whether a <code>Hashtable</code> collection is supported.
432      */

433     public static boolean isHashtableSupported()
434     {
435         return options[OPTION_HASHTABLE];
436     }
437     
438     /**
439      *Reports whether a <code>LinkedList</code> collection is supported.
440      */

441     public static boolean isLinkedListSupported()
442     {
443         return options[OPTION_LINKEDLIST];
444     }
445     
446     /**
447      *Reports whether a <code>TreeMap</code> collection is supported.
448      */

449     public static boolean isTreeMapSupported()
450     {
451         return options[OPTION_TREEMAP];
452     }
453     
454     /**
455      *Reports whether a <code>TreeSet</code> collection is supported.
456      */

457     public static boolean isTreeSetSupported()
458     {
459         return options[OPTION_TREESET];
460     }
461     
462     /**
463      *Reports whether a <code>Vector</code> collection is supported.
464      */

465     public static boolean isVectorSupported()
466     {
467         return options[OPTION_VECTOR];
468     }
469     
470     /**
471      *Reports whether a <code>Map</code> collection is supported.
472      */

473     public static boolean isMapSupported()
474     {
475         return options[OPTION_MAP];
476     }
477     
478     /**
479      *Reports whether a <code>List</code> collection is supported.
480      */

481     public static boolean isListSupported()
482     {
483         return options[OPTION_LIST];
484     }
485     
486     /**
487      *Reports whether arrays are supported.
488      */

489     public static boolean isArraySupported()
490     {
491         return options[OPTION_ARRAY];
492     }
493     
494     /**
495      *Reports whether a null collection is supported.
496      */

497     public static boolean isNullCollectionSupported()
498     {
499         return options[OPTION_NULLCOLLECTION];
500     }
501     
502     /**
503      * This method will return the current lifecycle state of an instance.
504      */

505     public static int currentState(Object JavaDoc o)
506     {
507         boolean[] status = new boolean[5];
508         status[IS_PERSISTENT] = JDOHelper.isPersistent(o);
509         status[IS_TRANSACTIONAL] = JDOHelper.isTransactional(o);
510         status[IS_DIRTY] = JDOHelper.isDirty(o);
511         status[IS_NEW] = JDOHelper.isNew(o);
512         status[IS_DELETED] = JDOHelper.isDeleted(o);
513         int i, j;
514         outerloop:
515             for( i = 0; i < NUM_STATES; ++i ){
516                 for( j = 0; j < NUM_STATUSES; ++j ){
517                     if( status[j] != state_statuses[i][j] )
518                         continue outerloop;
519                 }
520                 return i;
521             }
522             return NUM_STATES;
523     }
524
525     
526     public JdoLifecycleTck(String JavaDoc s) {
527         super(s);
528                 
529     }
530
531     protected String JavaDoc getLoggerName() {
532         return LOG_NAME + ".rt.tck.JdoLifecycleTck";
533     }
534
535     public void testStateTransitions() {
536         logger.log(BasicLevel.INFO, "testStateTransitions");
537         try {
538             pmf = getPMF();
539             if( pmf == null ){
540                 fail("StateTransitions: Unable to acquire a PMF");
541             }
542             pm = pmf.getPersistenceManager();
543             generatePersistentInstances();
544             
545             scenario = DATASTORE_TX;
546             logger.log(BasicLevel.INFO, "###scenario = DATASTORE_TX###");
547             checkTransitions();
548             if( isOptimisticSupported() ){
549                 scenario = OPTIMISTIC_TX;
550                 logger.log(BasicLevel.INFO, "###scenario = OPTIMISTIC_TX###");
551                 checkTransitions();
552             }
553             if( isNontransactionalReadSupported() || isNontransactionalWriteSupported() ){
554                 scenario = NO_TX;
555                 logger.log(BasicLevel.INFO, "###scenario = NO_TX###");
556                 checkTransitions();
557             }
558         } catch (Exception JavaDoc e) {
559             logger.log(BasicLevel.ERROR, "Unexception caught in testStateTransitions", e);
560             fail(e.getMessage());
561         } finally {
562             Transaction tx = pm.currentTransaction();
563             if (tx.isActive()) {
564                 tx.rollback();
565             }
566             pm.close();
567         }
568         /*
569         int errCnt = getErrorCount();
570         if( errCnt == 0 ){
571             return Status.passed("StateTransitions passed");
572         } else{
573             return Status.failed("StateTransitions failed, number of errors detected is " + errCnt);
574         }
575         */

576     }
577     
578     private void generatePersistentInstances()
579     {
580         if( doPersistentInstancesExist() ) return;
581         int i;
582         Transaction t = pm.currentTransaction();
583         t.begin();
584         for( i = 0; i < 50; ++i ){
585             StateTransitionObj sto = new StateTransitionObj(i);
586             sto.writeField(i);
587             pm.makePersistent(sto);
588         }
589         t.commit();
590         if( !doPersistentInstancesExist() )
591             logger.log(BasicLevel.INFO, "StateTransitions unable to create instances of StateTransitionsObj");
592     }
593
594     private boolean doPersistentInstancesExist()
595     {
596         boolean ret;
597         Transaction t = pm.currentTransaction();
598         t.begin();
599         Extent e = pm.getExtent(StateTransitionObj.class, false);
600         Iterator JavaDoc iter = e.iterator();
601         ret = iter.hasNext();
602         t.rollback();
603         return ret;
604     }
605
606     void checkTransitions()
607     {
608         for( operation = 0; operation < NUM_OPERATIONS; ++operation ){
609             
610             
611             // rule out situations that do not apply
612
if( ! applies_to_scenario[operation][scenario] ) continue;
613             if( operation == READOUTSIDETX && !isNontransactionalReadSupported() ) continue;
614             if( operation == WRITEOUTSIDETX && !isNontransactionalWriteSupported() ) continue;
615             if( (operation == COMMITRETAINVALUES || operation == ROLLBACKRETAINVALUES) &&
616                     !isRetainValuesSupported() ) continue;
617             if( operation == MAKENONTRANSACTIONAL &&
618                     !(isNontransactionalReadSupported() || isNontransactionalWriteSupported()) )
619                 continue;
620             
621             for( current_state = 0; current_state < NUM_STATES; ++current_state){
622                 if( scenario == OPTIMISTIC_TX && current_state == PERSISTENT_CLEAN ) continue;
623                 if( (current_state == TRANSIENT_CLEAN || current_state == TRANSIENT_DIRTY) &&
624                         !isTransientTransactionalSupported() )
625                     continue; // this state is not supported by implementation
626
if( current_state == PERSISTENT_NONTRANSACTIONAL &&
627                         !(isNontransactionalReadSupported() || isNontransactionalWriteSupported()) )
628                     continue; // this state is not supported by implementation
629
expected_state = transitions[operation][current_state];
630                 if( expected_state == IMPOSSIBLE ) continue;
631                 if( expected_state == UNCHANGED ) expected_state = current_state;
632                 try {
633                     transaction = pm.currentTransaction();
634                     if( transaction.isActive()){
635                         logger.log(BasicLevel.INFO, "Transaction is active (but should not be), rolling back");
636                         transaction.rollback();
637                     }
638                     if( scenario != NO_TX ){
639
640                         if( operation == COMMITNORETAINVALUES || operation == ROLLBACKNORETAINVALUES )
641                             transaction.setRetainValues(false);
642                         if( operation == COMMITRETAINVALUES || operation == ROLLBACKRETAINVALUES )
643                             transaction.setRetainValues(true);
644                         /* possibly switch above 4 lines to the following line
645                          transaction.setRetainValues( operation == COMMITRETAINVALUES || operation == ROLLBACKRETAINVALUES );
646                          */

647                         transaction.setOptimistic(scenario == OPTIMISTIC_TX);
648                         transaction.begin();
649                         if( !transaction.isActive() )
650                             logger.log(BasicLevel.INFO, "StateTransitions: Transaction should be active, but it is not");
651                     }
652
653                     // get and verify object is in right initial state
654
StateTransitionObj obj = getInstanceInState(current_state);
655                     if( obj == null ){ // could not get object in state
656
if( transaction.isActive() ) transaction.rollback();
657                         continue;
658                     }
659                     
660                     // Apply operation, catching possible exception
661
Exception JavaDoc e = null;
662                     try {
663                         logger.log(BasicLevel.DEBUG, "##initial state="+states[current_state]);
664                         logger.log(BasicLevel.DEBUG, "##operation="+operations[operation]);
665                         
666                         applyOperation(operation, obj);
667                     } catch( Exception JavaDoc excep ){
668                         if( excep instanceof javax.jdo.JDOUserException ){
669                             e = excep;
670                         } else {
671                             logger.log(BasicLevel.ERROR, "StateTransitions: Unexpected exception:"+excep);
672                             printSituation();
673                             //incrementErrorCount();
674
continue;
675                         }
676                     }
677                     
678                     // Get new state, verify correct transition and exceptions occurred
679
logger.log(BasicLevel.DEBUG, "##expected state="+states[new_state]);
680                     new_state = currentState(obj);
681                     logger.log(BasicLevel.DEBUG, "##new state ="+states[expected_state]);
682                     if( expected_state == ERROR || expected_state == NOT_APPLICABLE ){
683                         if( e == null ){
684                             logger.log(BasicLevel.ERROR, "StateTransitions: JDOUserException should have been thrown");
685                             printSituation();
686                             //incrementErrorCount();
687
} else {
688                             if( new_state != current_state ){
689                                 logger.log(BasicLevel.ERROR, "JDOUserException properly thrown, but instance should remain in current state, instance changed state to "+states[new_state]);
690                                 printSituation();
691                                 //incrementErrorCount();
692
}
693                         }
694                     }
695                     if( expected_state >= 0 && new_state != expected_state &&
696                             !((new_state == HOLLOW && expected_state == PERSISTENT_NONTRANSACTIONAL) ||
697                                     (new_state == PERSISTENT_NONTRANSACTIONAL && expected_state == HOLLOW)) ){
698                         logger.log(BasicLevel.ERROR, "StateTransitions: Invalid state transition to "+states[new_state] + ", new state should be "+states[expected_state]);
699                         printSituation();
700                         //incrementErrorCount();
701
}
702                     if( transaction.isActive() ) transaction.rollback();
703                 } catch(Exception JavaDoc unexpected_exception){
704                     logger.log(BasicLevel.ERROR, "Unexpected exception caught in StateTransitions "+unexpected_exception);
705                     printSituation();
706                     //unexpected_exception.printStackTrace(out);
707
//incrementErrorCount();
708
if( transaction.isActive() ) transaction.rollback();
709                 }
710             }
711         }
712
713     }
714
715     void printSituation()
716     {
717         logger.log(BasicLevel.INFO, "========================");
718         logger.log(BasicLevel.INFO, scenario_string[scenario]);
719         logger.log(BasicLevel.INFO, "initial state="+states[current_state]);
720         logger.log(BasicLevel.INFO, "operation="+operations[operation]);
721         logger.log(BasicLevel.INFO, "========================");
722     }
723
724     void applyOperation(int operation, StateTransitionObj stobj)
725     {
726         StateTransitionObj obj = (StateTransitionObj) stobj;
727         switch( operation ){
728         case MAKEPERSISTENT:
729         {
730             pm.makePersistent(obj);
731             break;
732         }
733         case DELETEPERSISTENT:
734         {
735             pm.deletePersistent(obj);
736             break;
737         }
738         case MAKETRANSACTIONAL:
739         {
740             pm.makeTransactional(obj);
741             break;
742         }
743         case MAKENONTRANSACTIONAL:
744         {
745             pm.makeNontransactional(obj);
746             break;
747         }
748         case MAKETRANSIENT:
749         {
750             pm.makeTransient(obj);
751             break;
752         }
753         case COMMITNORETAINVALUES:
754         {
755             pm.currentTransaction().commit();
756             break;
757         }
758         case COMMITRETAINVALUES:
759         {
760             pm.currentTransaction().commit();
761             break;
762         }
763         case ROLLBACKNORETAINVALUES:
764         {
765             pm.currentTransaction().rollback();
766             break;
767         }
768         case ROLLBACKRETAINVALUES:
769         {
770             pm.currentTransaction().rollback();
771             break;
772         }
773         case REFRESHDATASTORE:
774         {
775             pm.refresh(obj);
776             break;
777         }
778         case REFRESHOPTIMISTIC:
779         {
780             pm.refresh(obj);
781             break;
782         }
783         case EVICT:
784         {
785             pm.evict(obj);
786             break;
787         }
788         case READOUTSIDETX:
789         {
790             int val = obj.readField();
791             break;
792         }
793         case READOPTIMISTIC:
794         {
795             int val = obj.readField();
796             break;
797         }
798         case READDATASTORE:
799         {
800             int val = obj.readField();
801             break;
802         }
803         case WRITEOUTSIDETX:
804         {
805             obj.writeField(42);
806             break;
807         }
808         case WRITEINSIDETX:
809         {
810             obj.writeField(42);
811             break;
812         }
813         default:
814         {
815             logger.log(BasicLevel.ERROR, "StateTransitions internal error, illegal operation "+operation);
816         }
817         }
818     }
819
820
821     /**
822      * Get an instance in the specified state.
823      */

824     private StateTransitionObj getInstanceInState(int state)
825     {
826         switch(state) {
827         case TRANSIENT:
828             return getTransientInstance();
829         case PERSISTENT_NEW:
830             return getPersistentNewInstance();
831         case PERSISTENT_CLEAN:
832             return getPersistentCleanInstance();
833         case PERSISTENT_DIRTY:
834             return getPersistentDirtyInstance();
835         case HOLLOW:
836             return getHollowInstance();
837         case TRANSIENT_CLEAN:
838             return getTransientCleanInstance();
839         case TRANSIENT_DIRTY:
840             return getTransientDirtyInstance();
841         case PERSISTENT_NEW_DELETED:
842             return getPersistentNewDeletedInstance();
843         case PERSISTENT_DELETED:
844             return getPersistentDeletedInstance();
845         case PERSISTENT_NONTRANSACTIONAL:
846             return getPersistentNontransactionalInstance();
847         default:
848         {
849             return null;
850         }
851         }
852     }
853
854     private StateTransitionObj getTransientInstance()
855     {
856         StateTransitionObj obj = new StateTransitionObj(23);
857         int curr = currentState(obj);
858         if( curr != TRANSIENT ){
859             logger.log(BasicLevel.INFO, "StateTransitions: Unable to create transient instance, state is "+states[curr]);
860             printSituation();
861             return null;
862         }
863         return obj;
864     }
865
866     private StateTransitionObj getPersistentNewInstance()
867     {
868         StateTransitionObj obj = getTransientInstance();
869         if( obj == null ) return null;
870         pm.makePersistent(obj); // should transition to persistent-new
871
int curr = currentState(obj);
872         if( curr != PERSISTENT_NEW ){
873             logger.log(BasicLevel.INFO, "StateTransitions: Unable to create persistent-new instance");
874             logger.log(BasicLevel.INFO, " from transient instance via makePersistent(), state is "+states[curr]);
875             printSituation();
876             return null;
877         }
878         return obj;
879     }
880
881     public StateTransitionObj getPersistentCleanInstance()
882     {
883         StateTransitionObj obj = getHollowInstance();
884         if( obj == null ) return null;
885         StateTransitionObj sto = (StateTransitionObj) obj;
886         int val = sto.readField();
887         int curr = currentState(sto);
888         if( curr != PERSISTENT_CLEAN ){
889             logger.log(BasicLevel.INFO, "StateTransitions: Unable to create persistent-clean instance");
890             logger.log(BasicLevel.INFO, " from a hollow instance by reading a field, state is "+states[curr]);
891             printSituation();
892             return null;
893         }
894         return obj;
895     }
896
897     public StateTransitionObj getPersistentDirtyInstance()
898     {
899         StateTransitionObj obj = getHollowInstance();
900         if( obj == null ) return null;
901         StateTransitionObj pcobj = (StateTransitionObj) obj;
902         pcobj.writeField(23);
903         int curr = currentState(obj);
904         if( curr != PERSISTENT_DIRTY ){
905             logger.log(BasicLevel.INFO, "StateTransitions: Unable to create persistent-dirty instance");
906             logger.log(BasicLevel.INFO, " from a hollow instance by writing a field, state is "+states[curr]);
907             printSituation();
908             return null;
909         }
910         return obj;
911     }
912
913     public StateTransitionObj getHollowInstance()
914     {
915         Extent extent = pm.getExtent(StateTransitionObj.class, false);
916         Iterator JavaDoc iter = extent.iterator();
917         if( !iter.hasNext() ){
918             logger.log(BasicLevel.INFO, "Extent for StateTransitionObj should not be empty");
919             return null;
920         }
921         StateTransitionObj obj = (StateTransitionObj) iter.next();
922         int curr = currentState(obj);
923         if( curr != HOLLOW && curr != PERSISTENT_NONTRANSACTIONAL ){
924             logger.log(BasicLevel.INFO, "StateTransition: Attempt to get hollow instance via accessing extent failed, state is "+states[curr]);
925             printSituation();
926             return null;
927         }
928         return obj;
929     }
930
931     public StateTransitionObj getTransientCleanInstance()
932     {
933         StateTransitionObj obj = getTransientInstance();
934         if( obj == null ) return null;
935         pm.makeTransactional(obj);
936         int curr = currentState(obj);
937         if( curr != TRANSIENT_CLEAN ){
938             logger.log(BasicLevel.INFO, "StateTransitions: Unable to create transient-clean instance");
939             logger.log(BasicLevel.INFO, " from a transient instance via makeTransactional(), state is "+states[curr]);
940             printSituation();
941             return null;
942         }
943         return obj;
944     }
945
946     public StateTransitionObj getTransientDirtyInstance()
947     {
948         StateTransitionObj obj = getTransientCleanInstance();
949         if( obj == null ) return null;
950         StateTransitionObj pcobj = (StateTransitionObj) obj;
951         pcobj.writeField(23);
952         int curr = currentState(obj);
953         if( curr != TRANSIENT_DIRTY ){
954             logger.log(BasicLevel.INFO, "StateTransitions: Unable to create transient-dirty instance");
955             logger.log(BasicLevel.INFO, " from a transient clean instance via modifying a field, state is "+states[curr]);
956             printSituation();
957             return null;
958         }
959         return obj;
960     }
961
962     public StateTransitionObj getPersistentNewDeletedInstance()
963     {
964         StateTransitionObj obj = getPersistentNewInstance();
965         if( obj == null ) return null;
966         pm.deletePersistent(obj); // should transition to persistent-new-deleted
967
int curr = currentState(obj);
968         if( curr != PERSISTENT_NEW_DELETED ){
969             logger.log(BasicLevel.INFO, "StateTransitions: Unable to create transient-new-deleted instance");
970             logger.log(BasicLevel.INFO, " from a persistent-new instance via deletePersistent, state is "+states[curr]);
971             printSituation();
972             return null;
973         }
974         return obj;
975     }
976
977     public StateTransitionObj getPersistentDeletedInstance()
978     {
979         StateTransitionObj obj = getHollowInstance();
980         if( obj == null ) return null;
981         pm.deletePersistent(obj);
982         int curr = currentState(obj);
983         if( curr != PERSISTENT_DELETED ){
984             logger.log(BasicLevel.INFO, "StateTransitions: Unable to create persistent-deleted instance");
985             logger.log(BasicLevel.INFO, " from a persistent instance via deletePersistent(), state is "+states[curr]);
986             printSituation();
987             return null;
988         }
989         return obj;
990     }
991
992     public StateTransitionObj getPersistentNontransactionalInstance()
993     {
994         StateTransitionObj obj = getHollowInstance();
995         if( obj == null ) return null;
996         pm.makeNontransactional(obj);
997         int curr = currentState(obj);
998         if( curr != PERSISTENT_NONTRANSACTIONAL && curr != HOLLOW ){
999             logger.log(BasicLevel.INFO, "StateTransitions: Unable to create persistent-nontransactional instance");
1000            logger.log(BasicLevel.INFO, " from a persistent clean instance via makeNontransactional(), state is "+states[curr]);
1001            printSituation();
1002            return null;
1003        }
1004        return null;
1005    }
1006}
1007
1008
Popular Tags