Source code: nl/aidministrator/rdf/ral/SynchronizationRAL.java
1 /* Sesame - Storage and Querying architecture for RDF and RDF Schema
2 * Copyright (C) 2002 Aidministrator Nederland b.v.
3 *
4 * Contact:
5 * Aidministrator Nederland b.v.
6 * Julianaplein 14b
7 * 3817 CS Amersfoort
8 * The Netherlands
9 * tel. +31(0)33 4659987
10 * fax. +31(0)33 4659987
11 * sesame@aidministrator.nl
12 *
13 * http://www.aidministrator.nl/
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30 package nl.aidministrator.rdf.ral;
31
32 import nl.aidministrator.rdf.sail.model.*;
33 import nl.aidministrator.util.servlets.*;
34 import java.sql.*;
35 import java.util.Map;
36
37 /**
38 * An implementation of the Repository Abstraction Layer which handles
39 * synchronization between write- and read-threads. This RAL implements
40 * a policy where read-threads can run concurrently, but write-threads
41 * need exclusive access to the abstraction layer, including the blocking
42 * of read-threads. No guarantees are given on the order in which threads
43 * take turn. Once threads have started they can finish their jobs.
44 **/
45 public class SynchronizationRAL implements RAL {
46
47 /*---------------------------------------------+
48 | Variables |
49 +---------------------------------------------*/
50
51 protected RAL _persistentRAL;
52
53 /*---------------------------------------------+
54 | Constructors |
55 +---------------------------------------------*/
56
57 /**
58 * Creates a new SynchronizationRAL that adds synchronization to the
59 * supplied RAL.
60 **/
61 public SynchronizationRAL(RAL persistentRAL) {
62 _persistentRAL = persistentRAL;
63 }
64
65 /**
66 */
67 public void initialize(Map configParams)
68 throws Exception
69 {
70 _persistentRAL.initialize(configParams);
71
72 ServletLog.trace("SynchronizationRAL initialized");
73 }
74
75 public void shutDown() {
76 _getWriteLock();
77 try {
78 _persistentRAL.shutDown();
79 }
80 finally {
81 _releaseWriteLock();
82 }
83 }
84
85 /*---------------------------------------------+
86 | Adding statements to the database |
87 +---------------------------------------------*/
88
89 public void addDataStatement(Resource subject, Resource predicate,
90 Value object)
91 throws SQLException
92 {
93 _getWriteLock();
94 try {
95 _persistentRAL.addDataStatement(subject, predicate, object);
96 }
97 finally {
98 _releaseWriteLock();
99 }
100 }
101
102 public void addProperty(Resource propertyResource)
103 throws SQLException
104 {
105 _getWriteLock();
106 try {
107 _persistentRAL.addProperty(propertyResource);
108 }
109 finally {
110 _releaseWriteLock();
111 }
112 }
113
114 public void addClass(Resource classResource)
115 throws SQLException
116 {
117 _getWriteLock();
118 try {
119 _persistentRAL.addClass(classResource);
120 }
121 finally {
122 _releaseWriteLock();
123 }
124 }
125
126 public void addInstance(Value dataValue, Resource classResource)
127 throws SQLException
128 {
129 _getWriteLock();
130 try {
131 _persistentRAL.addInstance(dataValue, classResource);
132 }
133 finally {
134 _releaseWriteLock();
135 }
136 }
137
138 public void addSubProperty(Resource subProp, Resource superProp)
139 throws SQLException
140 {
141 _getWriteLock();
142 try {
143 _persistentRAL.addSubProperty(subProp, superProp);
144 }
145 finally {
146 _releaseWriteLock();
147 }
148 }
149
150 public void addSubClass(Resource subClass, Resource superClass)
151 throws SQLException
152 {
153 _getWriteLock();
154 try {
155 _persistentRAL.addSubClass(subClass, superClass);
156 }
157 finally {
158 _releaseWriteLock();
159 }
160 }
161
162 public void addDomain(Resource property, Resource domainClass)
163 throws SQLException
164 {
165 _getWriteLock();
166 try {
167 _persistentRAL.addDomain(property, domainClass);
168 }
169 finally {
170 _releaseWriteLock();
171 }
172 }
173
174 public void addRange(Resource property, Resource rangeClass)
175 throws SQLException
176 {
177 _getWriteLock();
178 try {
179 _persistentRAL.addRange(property, rangeClass);
180 }
181 finally {
182 _releaseWriteLock();
183 }
184 }
185
186 public void addComment(Resource resource, Literal comment)
187 throws SQLException
188 {
189 _getWriteLock();
190 try {
191 _persistentRAL.addComment(resource, comment);
192 }
193 finally {
194 _releaseWriteLock();
195 }
196 }
197
198 public void addLabel(Resource resource, Literal label)
199 throws SQLException
200 {
201 _getWriteLock();
202 try {
203 _persistentRAL.addLabel(resource, label);
204 }
205 finally {
206 _releaseWriteLock();
207 }
208 }
209
210 public void removeDataStatements(Resource subject, Resource predicate, Value object)
211 throws SQLException
212 {
213 _getWriteLock();
214 try {
215 _persistentRAL.removeDataStatements(subject, predicate, object);
216 }
217 finally {
218 _releaseWriteLock();
219 }
220 }
221
222 public void clearRepository()
223 throws SQLException
224 {
225 _getWriteLock();
226 try {
227 _persistentRAL.clearRepository();
228 }
229 finally {
230 _releaseWriteLock();
231 }
232 }
233
234 public NamespaceIterator getNamespaces() {
235 NamespaceIterator result = null;
236 _getReadLock();
237 try {
238 result = _persistentRAL.getNamespaces();
239 }
240 finally {
241 _releaseReadLock();
242 }
243 return result;
244 }
245
246 /*---------------------------------------------+
247 | Retrieving Class information |
248 +---------------------------------------------*/
249
250 public ResourceIterator getClasses() {
251 ResourceIterator result = null;
252 _getReadLock();
253 try {
254 result = _persistentRAL.getClasses();
255 }
256 finally {
257 _releaseReadLock();
258 }
259 return result;
260 }
261
262 public boolean isClass(Value resource) {
263 boolean result = false;
264 _getReadLock();
265 try {
266 result = _persistentRAL.isClass(resource);
267 }
268 finally {
269 _releaseReadLock();
270 }
271 return result;
272 }
273
274 public ResourceIterator getSubClassesOf(Resource classResource, boolean recursive)
275 {
276 ResourceIterator result = null;
277 _getReadLock();
278 try {
279 result = _persistentRAL.getSubClassesOf(classResource, recursive);
280 }
281 finally {
282 _releaseReadLock();
283 }
284 return result;
285 }
286
287 public ResourceIterator getSuperClassesOf(Resource classResource, boolean recursive)
288 {
289 ResourceIterator result = null;
290 _getReadLock();
291 try {
292 result = _persistentRAL.getSuperClassesOf(classResource, recursive);
293 }
294 finally {
295 _releaseReadLock();
296 }
297 return result;
298 }
299
300 public boolean isSubClassOf(Value subClass, Value superClass)
301 {
302 boolean result = false;
303 _getReadLock();
304 try {
305 result = _persistentRAL.isSubClassOf(subClass, superClass);
306 }
307 finally {
308 _releaseReadLock();
309 }
310 return result;
311 }
312
313
314 /*---------------------------------------------+
315 | Retrieving Property information |
316 +---------------------------------------------*/
317
318 public ResourceIterator getProperties() {
319 ResourceIterator result = null;
320 _getReadLock();
321 try {
322 result = _persistentRAL.getProperties();
323 }
324 finally {
325 _releaseReadLock();
326 }
327 return result;
328 }
329
330 public boolean isProperty(Value resource) {
331 boolean result = false;
332 _getReadLock();
333 try {
334 result = _persistentRAL.isProperty(resource);
335 }
336 finally {
337 _releaseReadLock();
338 }
339 return result;
340 }
341
342 public ResourceIterator getSubPropertiesOf(Resource propertyResource, boolean recursive)
343 {
344 ResourceIterator result = null;
345 _getReadLock();
346 try {
347 result = _persistentRAL.getSubPropertiesOf(propertyResource, recursive);
348 }
349 finally {
350 _releaseReadLock();
351 }
352 return result;
353 }
354
355 public ResourceIterator getSuperPropertiesOf(Resource propertyResource, boolean recursive)
356 {
357 ResourceIterator result = null;
358 _getReadLock();
359 try {
360 result = _persistentRAL.getSuperPropertiesOf(propertyResource, recursive);
361 }
362 finally {
363 _releaseReadLock();
364 }
365 return result;
366 }
367
368 public boolean isSubPropertyOf(
369 Value subProperty, Value superProperty)
370 {
371 boolean result = false;
372 _getReadLock();
373 try {
374 result = _persistentRAL.isSubPropertyOf(subProperty, superProperty);
375 }
376 finally {
377 _releaseReadLock();
378 }
379 return result;
380 }
381
382 public Value getDomainFor(Resource propertyResource) {
383 Value result = null;
384 _getReadLock();
385 try {
386 result = _persistentRAL.getDomainFor(propertyResource);
387 }
388 finally {
389 _releaseReadLock();
390 }
391 return result;
392 }
393
394 public Value getRangeFor(Resource propertyResource) {
395 Value result = null;
396 _getReadLock();
397 try {
398 result = _persistentRAL.getRangeFor(propertyResource);
399 }
400 finally {
401 _releaseReadLock();
402 }
403 return result;
404 }
405
406
407 /*---------------------------------------------+
408 | Retrieving Instance information |
409 +---------------------------------------------*/
410
411 public ResourceIterator getInstancesOf(
412 Resource classResource, boolean properInstances)
413 {
414 ResourceIterator result = null;
415 _getReadLock();
416 try {
417 result = _persistentRAL.getInstancesOf(classResource, properInstances);
418 }
419 finally {
420 _releaseReadLock();
421 }
422 return result;
423 }
424
425 public boolean isInstanceOf(
426 Value dataValue, Resource classResource, boolean properInstances)
427 {
428 boolean result = false;
429 _getReadLock();
430 try {
431 result = _persistentRAL.isInstanceOf(
432 dataValue, classResource, properInstances);
433 }
434 finally {
435 _releaseReadLock();
436 }
437 return result;
438 }
439
440 /**
441 * Gets all comments for the supplied resource.
442 **/
443 public ResourceIterator getCommentsFor(Resource resource) {
444 ResourceIterator result = null;
445 _getReadLock();
446 try {
447 result = _persistentRAL.getCommentsFor(resource);
448 }
449 finally {
450 _releaseReadLock();
451 }
452 return result;
453 }
454
455 /**
456 * Checks whether a comment with the specified source and target exisits.
457 **/
458 public boolean isComment(Resource source, Literal target) {
459 boolean result = false;
460 _getReadLock();
461 try {
462 result = _persistentRAL.isComment(source, target);
463 }
464 finally {
465 _releaseReadLock();
466 }
467 return result;
468 }
469
470 /**
471 * Gets all labels for the supplied resource.
472 **/
473 public ResourceIterator getLabelsFor(Resource resource) {
474 ResourceIterator result = null;
475 _getReadLock();
476 try {
477 result = _persistentRAL.getLabelsFor(resource);
478 }
479 finally {
480 _releaseReadLock();
481 }
482 return result;
483 }
484
485 /**
486 * Checks whether a label with the specified source and target exisits.
487 **/
488 public boolean isLabel(Resource source, Literal target) {
489 boolean result = false;
490 _getReadLock();
491 try {
492 result = _persistentRAL.isLabel(source, target);
493 }
494 finally {
495 _releaseReadLock();
496 }
497 return result;
498 }
499
500 public StatementIterator getStatements(Resource source, Resource predicate,
501 Value target, boolean recursive)
502 {
503 StatementIterator result = null;
504 _getReadLock();
505 try {
506 result = _persistentRAL.getStatements(
507 source, predicate, target, recursive);
508 }
509 finally {
510 _releaseReadLock();
511 }
512 return result;
513 }
514
515 public boolean isStatement(Resource source, Resource predicate,
516 Value target, boolean recursive)
517 {
518 boolean result = false;
519 _getReadLock();
520 try {
521 result = _persistentRAL.isStatement(
522 source, predicate, target, recursive);
523 }
524 finally {
525 _releaseReadLock();
526 }
527 return result;
528 }
529
530 /*-----------------------------------------+
531 | Synchronization methods |
532 +-----------------------------------------*/
533
534 private boolean _writeRequested = false;
535 private int _readingThreads = 0;
536
537 private void _getWriteLock() {
538 synchronized (this) {
539 //ServletLog.trace("entering _getWriteLock()");
540 while (_writeRequested) {
541 // Someone else wants to write
542 try {
543 ServletLog.trace("waiting for other writer to finish");
544 wait();
545 ServletLog.trace("waking up");
546 } catch (InterruptedException ignore) {
547 }
548 }
549
550 _writeRequested = true;
551 //ServletLog.trace("Got the lock");
552
553 // Wait for the readingThreads to finish
554 while (_readingThreads > 0) {
555 try {
556 ServletLog.trace("Waiting for readers to finish");
557 wait();
558 ServletLog.trace("waking up");
559 } catch (InterruptedException ignore) {
560 }
561 }
562 //ServletLog.trace("We've got a go!!!");
563 }
564 }
565
566 private void _releaseWriteLock() {
567 synchronized (this) {
568 //ServletLog.trace("Releasing write lock");
569 _writeRequested = false;
570 notifyAll();
571 }
572 }
573
574 private void _getReadLock() {
575 synchronized (this) {
576 //ServletLog.trace("entering _getReadLock()");
577 // Wait for any writing threads to finish
578 while (_writeRequested) {
579 try {
580 ServletLog.trace("Waiting for writer to finish");
581 wait();
582 ServletLog.trace("waking up");
583 } catch (InterruptedException ignore) {
584 }
585 }
586
587 // No candidates for writing anymore, go ahead
588 _readingThreads++;
589 //ServletLog.trace("We've got a go!!! (" + _readingThreads + ")");
590 }
591 }
592
593 private void _releaseReadLock() {
594 synchronized (this) {
595 _readingThreads--;
596 //ServletLog.trace("Releasing read lock (" + _readingThreads + ")");
597 if (_readingThreads == 0) {
598 // Maybe someone wants to write?
599 notifyAll();
600 }
601 }
602 }
603 }