01
/**//* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */
02
03
package com.db4odoc.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>
19
* <b>Caution !!! This method contains a commit() call.</b>
20
*/
21
public static Object getSingleton(
22
ObjectContainer objectContainer, Class clazz) ...{
23
24
Object obj = queryForSingletonClass(objectContainer, clazz);
25
if (obj != null) ...{
26
return obj;
27
}
28
29
String semaphore = "Singleton#getSingleton_"
30
+ clazz.getName();
31
32
if (!objectContainer.ext().setSemaphore(semaphore, 10000)) ...{
33
throw new RuntimeException("Blocked semaphore "
34
+ semaphore);
35
}
36
37
obj = queryForSingletonClass(objectContainer, clazz);
38
39
if (obj == null) ...{
40
41
try ...{
42
obj = clazz.newInstance();
43
} catch (InstantiationException e) ...{
44
e.printStackTrace();
45
} catch (IllegalAccessException e) ...{
46
e.printStackTrace();
47
}
48
49
objectContainer.set(obj);
50
51
/**//*
52
* !!! CAUTION !!! There is a commit call here.
53
*
54
* The commit call is necessary, so other transactions can
55
* see the new inserted object.
56
*/
57
objectContainer.commit();
58
59
}
60
61
objectContainer.ext().releaseSemaphore(semaphore);
62
63
return obj;
64
}
65
66
private static Object queryForSingletonClass(
67
ObjectContainer objectContainer, Class clazz) ...{
68
Query q = objectContainer.query();
69
q.constrain(clazz);
70
ObjectSet objectSet = q.execute();
71
if (objectSet.size() == 1) ...{
72
return objectSet.next();
73
}
74
if (objectSet.size() > 1) ...{
75
throw new RuntimeException(
76
"Singleton problem. Multiple instances of: "
77
+ clazz.getName());
78
}
79
return null;
80
}
81
82
}