01
/**//* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */
02
03
package com.db4odoc.f1.semaphores;
04
05
import com.db4o.*;
06
import com.db4o.query.*;
07
08
/** *//**
09
* This class demonstrates the use of a semaphore to ensure that only
10
* one instance of a certain class is stored to an ObjectContainer.
11
*
12
* Caution !!! The getSingleton method contains a commit() call.
13
*/
14
public class Singleton ...{
15
16
/** *//**
17
* returns a singleton object of one class for an ObjectContainer.
18
* <br><b>Caution !!! This method contains a commit() call.</b>
19
*/
20
public static Object getSingleton(ObjectContainer objectContainer, Class clazz) ...{
21
22
Object obj = queryForSingletonClass(objectContainer, clazz);
23
if (obj != null) ...{
24
return obj;
25
}
26
27
String semaphore = "Singleton#getSingleton_" + clazz.getName();
28
29
if (!objectContainer.ext().setSemaphore(semaphore, 10000)) ...{
30
throw new RuntimeException("Blocked semaphore " + semaphore);
31
}
32
33
obj = queryForSingletonClass(objectContainer, clazz);
34
35
if (obj == null) ...{
36
37
try ...{
38
obj = clazz.newInstance();
39
} catch (InstantiationException e) ...{
40
e.printStackTrace();
41
} catch (IllegalAccessException e) ...{
42
e.printStackTrace();
43
}
44
45
objectContainer.set(obj);
46
47
/**//* !!! CAUTION !!!
48
* There is a commit call here.
49
*
50
* The commit call is necessary, so other transactions
51
* can see the new inserted object.
52
*/
53
objectContainer.commit();
54
55
}
56
57
objectContainer.ext().releaseSemaphore(semaphore);
58
59
return obj;
60
}
61
62
private static Object queryForSingletonClass(ObjectContainer objectContainer, Class clazz) ...{
63
Query q = objectContainer.query();
64
q.constrain(clazz);
65
ObjectSet objectSet = q.execute();
66
if (objectSet.size() == 1) ...{
67
return objectSet.next();
68
}
69
if (objectSet.size() > 1) ...{
70
throw new RuntimeException(
71
"Singleton problem. Multiple instances of: " + clazz.getName());
72
}
73
return null;
74
}
75
76
}