001: package org.apache.ojb.junit;
002:
003: import java.util.HashMap;
004: import java.util.Iterator;
005: import java.util.Map;
006:
007: import junit.framework.TestCase;
008: import org.apache.commons.lang.SerializationUtils;
009: import org.apache.ojb.broker.OJBRuntimeException;
010: import org.apache.ojb.broker.PersistenceBroker;
011: import org.apache.ojb.broker.PersistenceBrokerFactory;
012: import org.apache.ojb.broker.metadata.ClassDescriptor;
013: import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
014:
015: /**
016: * Extension of the JUnit test class.
017: *
018: * @author <a href="mailto:arminw@apache.org">Armin Waibel</a>
019: * @version $Id: OJBTestCase.java,v 1.5.2.6 2005/03/18 19:22:30 arminw Exp $
020: */
021: public class OJBTestCase extends TestCase {
022: private static final String SKIP_STR = "OJB.skip.issues";
023: private static final String SKIP_DEFAULT_VALUE = "false";
024: private MetadataHelper referenceHelper;
025:
026: public OJBTestCase() {
027: }
028:
029: public OJBTestCase(String name) {
030: super (name);
031: }
032:
033: protected void setUp() throws Exception {
034: super .setUp();
035: // sleep thread to guarantee different timestamp values for
036: // each test
037: ojbSleep();
038: }
039:
040: protected void tearDown() throws Exception {
041: super .tearDown();
042: if (referenceHelper != null) {
043: PersistenceBroker temp = PersistenceBrokerFactory
044: .defaultPersistenceBroker();
045: try {
046: referenceHelper.restoreMetadataSettings(temp);
047: } finally {
048: if (temp != null) {
049: temp.close();
050: }
051: }
052: }
053: }
054:
055: /**
056: * Sleep current thread for a minimal period.
057: */
058: public void ojbSleep() {
059: try {
060: // most systems has system time precision of 10 msec
061: // so wait to guarantee new system time value for each test.
062: Thread.sleep(11);
063: } catch (InterruptedException ignore) {
064: }
065: }
066:
067: /**
068: * This method could be used to print a message before skip 'problematic' test cases.
069: */
070: public void ojbSkipTestMessage(String message) {
071: if (message == null) {
072: message = "No description, please see test case";
073: }
074: String className = this .getClass().getName();
075: System.out.println("# [Skip test in " + className + "] "
076: + message + " #");
077: }
078:
079: /**
080: * This method could be used to skip 'problematic' test cases or known issues before
081: * a release was made. To enable the skipped tests set a system property 'skip.issues'
082: * to <tt>false</tt>.
083: */
084: public boolean ojbSkipKnownIssueProblem() {
085: return ojbSkipKnownIssueProblem(null);
086: }
087:
088: /**
089: * This method could be used to skip 'problematic' test cases or known issues before
090: * a release was made. To enable the skipped tests set a system property 'skip.issues'
091: * to <tt>false</tt>.
092: */
093: public boolean ojbSkipKnownIssueProblem(String message) {
094: String result = SKIP_DEFAULT_VALUE;
095: boolean skip = false;
096: try {
097: result = System.getProperty(SKIP_STR, result);
098: skip = new Boolean(result).booleanValue();
099: } catch (Exception e) {
100: System.err.println("Seems that system property '"
101: + SKIP_STR + "=" + result
102: + "' is not a valid boolean value");
103: }
104: if (skip) {
105: if (message == null) {
106: message = "No description, please see test case";
107: }
108: String className = this .getClass().getName();
109: System.out.println("# [Skip known issue in " + className
110: + "] " + message + " #");
111: }
112: return skip;
113: }
114:
115: /**
116: * Allows to do a global change of object/collection reference settings. When the test
117: * is tear down the old settings will be restored. Be careful when override setUp/tearDown method, don't
118: * forget the "super call", else this method couldn't work properly.
119: *
120: * @param clazz
121: * @param referenceField
122: * @param autoRetrieve
123: * @param autoUpdate
124: * @param autoDelete
125: * @param useProxy
126: */
127: public void ojbChangeReferenceSetting(Class clazz,
128: String referenceField, boolean autoRetrieve,
129: int autoUpdate, int autoDelete, boolean useProxy) {
130: if (referenceHelper == null) {
131: referenceHelper = new MetadataHelper();
132: }
133: PersistenceBroker temp = PersistenceBrokerFactory
134: .defaultPersistenceBroker();
135: try {
136: referenceHelper.changeReferenceSetting(temp, clazz,
137: referenceField, autoRetrieve, autoUpdate,
138: autoDelete, useProxy);
139: } finally {
140: if (temp != null) {
141: temp.close();
142: }
143: }
144: }
145:
146: /**
147: * Allows to do a global change of object/collection reference settings. When the test
148: * is tear down the old settings will be restored. Be careful when override setUp/tearDown method, don't
149: * forget the "super call", else this method couldn't work properly.
150: *
151: * @param clazz
152: * @param referenceField
153: * @param autoRetrieve
154: * @param autoUpdate
155: * @param autoDelete
156: * @param useProxy
157: */
158: public void ojbChangeReferenceSetting(Class clazz,
159: String referenceField, boolean autoRetrieve,
160: boolean autoUpdate, boolean autoDelete, boolean useProxy) {
161: if (referenceHelper == null) {
162: referenceHelper = new MetadataHelper();
163: }
164: PersistenceBroker temp = PersistenceBrokerFactory
165: .defaultPersistenceBroker();
166: try {
167: referenceHelper.changeReferenceSetting(temp, clazz,
168: referenceField, autoRetrieve, autoUpdate,
169: autoDelete, useProxy);
170: } finally {
171: if (temp != null) {
172: temp.close();
173: }
174: }
175: }
176:
177: //================================================================
178: // inner class
179: //================================================================
180: /**
181: * Class that help us to do changes on metadata and restore old state on
182: * tear down of the test.
183: * NOTE: This strategy is not recommended in production application because
184: * the made changes will be global and all threads will recognize them immediately.
185: *
186: */
187: public class MetadataHelper {
188: private Map oldSettings;
189:
190: public MetadataHelper() {
191: oldSettings = new HashMap();
192: }
193:
194: protected void restoreMetadataSettings(PersistenceBroker broker) {
195: if (oldSettings.size() == 0)
196: return;
197: Iterator it = oldSettings.entrySet().iterator();
198: Map.Entry entry;
199: while (it.hasNext()) {
200: entry = (Map.Entry) it.next();
201: String clazz = (String) entry.getKey();
202: Map fieldMap = (Map) entry.getValue();
203: Iterator iter = fieldMap.entrySet().iterator();
204: Map.Entry entry2;
205: ClassDescriptor cld = broker.getDescriptorRepository()
206: .getDescriptorFor(clazz);
207: while (iter.hasNext()) {
208: entry2 = (Map.Entry) iter.next();
209: String oldRefName = (String) entry2.getKey();
210: ObjectReferenceDescriptor oldRef = (ObjectReferenceDescriptor) entry2
211: .getValue();
212: // lookup single object or collection descriptor
213: ObjectReferenceDescriptor ref = cld
214: .getCollectionDescriptorByName(oldRefName);
215: if (ref == null)
216: ref = cld
217: .getObjectReferenceDescriptorByName(oldRefName);
218:
219: // System.out.println("Restoring metadata for " + clazz
220: // + " from " + ref.toXML()
221: // + " === to ===> " + oldRef.toXML());
222: ref.setCascadeRetrieve(oldRef.getCascadeRetrieve());
223: ref.setCascadingStore(oldRef.getCascadingStore());
224: ref.setCascadingDelete(oldRef.getCascadingDelete());
225: ref.setLazy(oldRef.isLazy());
226: // System.out.println("Restore metadata for " + clazz
227: // + " to " + ref.toXML());
228: }
229: }
230: oldSettings.clear();
231: }
232:
233: public void changeReferenceSetting(PersistenceBroker broker,
234: Class clazz, String referenceField,
235: boolean autoRetrieve, int autoUpdate, int autoDelete,
236: boolean useProxy) {
237: ClassDescriptor cld = broker.getClassDescriptor(clazz);
238: ObjectReferenceDescriptor ref = cld
239: .getCollectionDescriptorByName(referenceField);
240: ref = cld.getCollectionDescriptorByName(referenceField);
241: if (ref == null)
242: ref = cld
243: .getObjectReferenceDescriptorByName(referenceField);
244: if (ref == null) {
245: throw new OJBRuntimeException("Given field "
246: + referenceField
247: + " does not match a reference in " + clazz);
248: }
249:
250: prepareSetting(ref, cld, clazz, referenceField);
251:
252: ref.setLazy(useProxy);
253: ref.setCascadeRetrieve(autoRetrieve);
254: ref.setCascadingStore(autoUpdate);
255: ref.setCascadingDelete(autoDelete);
256:
257: // System.out.println("old settings: " + oldRef.toXML());
258: // System.out.println("new settings: " + ref.toXML());
259: }
260:
261: public void changeReferenceSetting(PersistenceBroker broker,
262: Class clazz, String referenceField,
263: boolean autoRetrieve, boolean autoUpdate,
264: boolean autoDelete, boolean useProxy) {
265: ClassDescriptor cld = broker.getClassDescriptor(clazz);
266: ObjectReferenceDescriptor ref = cld
267: .getCollectionDescriptorByName(referenceField);
268: ref = cld.getCollectionDescriptorByName(referenceField);
269: if (ref == null)
270: ref = cld
271: .getObjectReferenceDescriptorByName(referenceField);
272: if (ref == null) {
273: throw new OJBRuntimeException("Given field "
274: + referenceField
275: + " does not match a reference in " + clazz);
276: }
277:
278: prepareSetting(ref, cld, clazz, referenceField);
279:
280: ref.setLazy(useProxy);
281: ref.setCascadeRetrieve(autoRetrieve);
282: ref.setCascadeStore(autoUpdate);
283: ref.setCascadeDelete(autoDelete);
284:
285: // System.out.println("old settings: " + oldRef.toXML());
286: // System.out.println("new settings: " + ref.toXML());
287: }
288:
289: void prepareSetting(ObjectReferenceDescriptor ref,
290: ClassDescriptor cld, Class clazz, String referenceField) {
291: HashMap fieldMap = (HashMap) oldSettings.get(cld
292: .getClassNameOfObject());
293: if (fieldMap == null) {
294: fieldMap = new HashMap();
295: oldSettings.put(cld.getClassNameOfObject(), fieldMap);
296: }
297:
298: ObjectReferenceDescriptor oldRef = (ObjectReferenceDescriptor) fieldMap
299: .get(ref.getPersistentField().getName());
300: // if we don't find old settings buffer it
301: if (oldRef == null) {
302: // buffer deep copy of old settings
303: oldRef = (ObjectReferenceDescriptor) SerializationUtils
304: .clone(ref);
305: fieldMap
306: .put(ref.getPersistentField().getName(), oldRef);
307: }
308: }
309: }
310: }
|