001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: *
005: * Licensed under the Educational Community License, Version 1.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.opensource.org/licenses/ecl1.php
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package edu.iu.uis.eden.test;
018:
019: import org.junit.Test;
020: import org.kuali.workflow.test.WorkflowTestCase;
021: import org.springframework.transaction.TransactionStatus;
022: import org.springframework.transaction.support.TransactionCallback;
023: import org.springmodules.orm.ojb.PersistenceBrokerTemplate;
024:
025: import edu.iu.uis.eden.KEWServiceLocator;
026: import edu.iu.uis.eden.util.OptimisticLockFailureService;
027:
028: /**
029: * @author ewestfal
030: */
031: public abstract class OjbBeanTestCase extends WorkflowTestCase {
032:
033: private Object lock = new Object();
034:
035: @Test
036: public void testOptimisticLocking() throws Exception {
037: if (isOptimisticallyLocked()) {
038: getTransactionTemplate().execute(new TransactionCallback() {
039: public Object doInTransaction(TransactionStatus status) {
040: try {
041: Object bean = loadBean();
042: modifyBean(bean);
043: synchronized (lock) {
044: modifyConcurrently();
045: try {
046: lock.wait();
047: } catch (InterruptedException e) {
048: throw new RuntimeException(e);
049: }
050: }
051: // transaction from other thread should be commited at this point
052: try {
053: getPersistenceBrokerTemplate().store(bean);
054: fail("The bean was modified by a different transaction, OptimisticLockFailureException should have been thrown.");
055: } catch (Exception e) {
056: if (!getOptimisticLockFailureService()
057: .checkForOptimisticLockFailure(e)) {
058: throw e;
059: }
060: }
061: return null;
062: } catch (Exception e) {
063: throw new RuntimeException(e);
064: }
065: }
066: });
067: }
068: }
069:
070: private void modifyConcurrently() {
071: Runnable runnable = new Runnable() {
072: public void run() {
073: synchronized (lock) {
074: try {
075: getTransactionTemplate().execute(
076: new TransactionCallback() {
077: public Object doInTransaction(
078: TransactionStatus nestedStatus) {
079: try {
080: Object bean = loadBean();
081: modifyBean(bean);
082: getPersistenceBrokerTemplate()
083: .store(bean);
084: return null;
085: } catch (Exception e) {
086: throw new RuntimeException(
087: e);
088: }
089: }
090: });
091: } catch (Throwable t) {
092: t.printStackTrace();
093: fail(t.getMessage());
094: } finally {
095: lock.notify();
096: }
097: }
098: }
099: };
100: new Thread(runnable).start();
101: }
102:
103: protected abstract Object loadBean() throws Exception;
104:
105: protected abstract void modifyBean(Object bean) throws Exception;
106:
107: protected abstract boolean isOptimisticallyLocked();
108:
109: protected PersistenceBrokerTemplate getPersistenceBrokerTemplate() {
110: return new PersistenceBrokerTemplate();
111: }
112:
113: protected OptimisticLockFailureService getOptimisticLockFailureService() {
114: return (OptimisticLockFailureService) KEWServiceLocator
115: .getService(KEWServiceLocator.OPTIMISTIC_LOCK_FAILURE_SERVICE);
116: }
117:
118: }
|