01/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 02
using System; 03
using Db4objects.Db4o; 04
using Db4objects.Db4o.Query; 05
using Sharpen.Lang; 06
07
namespace Db4objects.Db4odoc.Semaphores 08
{ 09
/** 10
* This class demonstrates the use of a semaphore to ensure that only 11
* one instance of a certain class is stored to an IObjectContainer. 12
* 13
* Caution !!! The getSingleton method contains a commit() call. 14
*/ 15
public class Singleton 16
{ 17
/** 18
* returns a singleton object of one class for an IObjectContainer. 19
* <br><b>Caution !!! This method contains a commit() call.</b> 20
*/ 21
public static Object GetSingleton(IObjectContainer objectContainer, Class clazz) 22
{ 23
Object obj = queryForSingletonClass(objectContainer, clazz); 24
if (obj != null) 25
{ 26
return obj; 27
} 28
29
String semaphore = "Singleton#getSingleton_" + clazz.GetName(); 30
31
if (!objectContainer.Ext().SetSemaphore(semaphore, 10000)) 32
{ 33
throw new Exception("Blocked semaphore " + semaphore); 34
} 35
36
obj = queryForSingletonClass(objectContainer, clazz); 37
38
if (obj == null) 39
{ 40
41
try 42
{ 43
obj = clazz.NewInstance(); 44
} 45
catch (Exception e) 46
{ 47
System.Console.WriteLine(e.Message); 48
} 49
50
objectContainer.Set(obj); 51
52
/* !!! CAUTION !!! 53
* There is a commit call here. 54
* 55
* The commit call is necessary, so other transactions 56
* can see the new inserted object. 57
*/ 58
objectContainer.Commit(); 59
60
} 61
62
objectContainer.Ext().ReleaseSemaphore(semaphore); 63
64
return obj; 65
} 66
67
private static Object queryForSingletonClass(IObjectContainer objectContainer, Sharpen.Lang.Class clazz) 68
{ 69
IQuery q = objectContainer.Query(); 70
q.Constrain(clazz); 71
IObjectSet objectSet = q.Execute(); 72
if (objectSet.Size() == 1) 73
{ 74
return objectSet.Next(); 75
} 76
if (objectSet.Size() > 1) 77
{ 78
throw new Exception( 79
"Singleton problem. Multiple instances of: " + clazz.GetName()); 80
} 81
return null; 82
} 83
84
} 85
86
}
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02
Imports System 03
Imports Db4objects.Db4o 04
Imports Db4objects.Db4o.Query 05
06
Namespace Db4objects.Db4odoc.Semaphores 07
' This class demonstrates the use of a semaphore to ensure that only 08
' one instance of a certain class is stored to an IObjectContainer. 09
' 10
' Caution !!! The getSingleton method contains a commit() call. 11
12
Public Class Singleton 13
14
' returns a singleton object of one class for an IObjectContainer. 15
' Caution !!! This method contains a commit() call. 16
17
Public Shared Function GetSingleton(ByVal objectContainer As IObjectContainer, ByVal clazz As System.Type) As Object 18
Dim obj As Object = queryForSingletonClass(objectContainer, clazz) 19
If Not obj Is Nothing Then 20
Return obj 21
End If 22
23
Dim semaphore As String = "Singleton#getSingleton_" + clazz.FullName 24
25
If Not objectContainer.Ext().SetSemaphore(semaphore, 10000) Then 26
Throw New Exception("Blocked semaphore " + semaphore) 27
End If 28
29
obj = queryForSingletonClass(objectContainer, clazz) 30
31
If obj Is Nothing Then 32
33
Try 34
obj = System.Activator.CreateInstance(clazz) 35
Catch e As Exception 36
System.Console.WriteLine(e.Message) 37
End Try 38
39
objectContainer.Set(obj) 40
' Not Not Not CAUTION Not Not Not 41
' * There is a commit call here. 42
' * 43
' * The commit call is necessary, so other transactions 44
' * can see the New inserted Object. 45
' */ 46
objectContainer.Commit() 47
48
End If 49
50
objectContainer.Ext().ReleaseSemaphore(semaphore) 51
52
Return obj 53
End Function 54
55
Private Shared Function queryForSingletonClass(ByVal objectContainer As IObjectContainer, ByVal clazz As System.Type) As Object 56
Dim q As IQuery = objectContainer.Query() 57
q.Constrain(clazz) 58
Dim objectSet As IObjectSet = q.Execute() 59
If objectSet.Size() = 1 Then 60
Return objectSet.Next() 61
End If 62
If objectSet.Size() > 1 Then 63
Throw New Exception("Singleton problem. Multiple instances of: " + clazz.FullName) 64
End If 65
Return Nothing 66
End Function 67
68
End Class 69
70
End Namespace