-
Notifications
You must be signed in to change notification settings - Fork 8
/
service.prefs.html
5292 lines (5238 loc) · 682 KB
/
service.prefs.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>106 PreferencesService Specification - OSGi Compendium 7</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1" />
<link rel="home" href="toc.html" title="OSGi Compendium" />
<link rel="up" href="toc.html" title="OSGi Compendium" />
<link rel="prev" href="service.metatype.html" title="105 Metatype Service Specification" />
<link rel="next" href="service.useradmin.html" title="107 User Admin Service Specification" />
<meta name="Section-title" content="106 PreferencesService Specification" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" href="images/favicon.png" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="css/custom.css" />
<link rel="stylesheet" type="text/css" href="css/github.css" />
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Ubuntu:regular,bold&subset=Latin" /><script type="text/javascript" src="js/highlight.pack.js"></script><script type="text/javascript" src="js/main.js"></script></head>
<body>
<div id="fullbody">
<div id="header">
<div class="menu-top-container"></div>
<div id="shadow-block"><a class="logo" href="index.html"><img src="images/logo.svg" alt="OSGi Alliance Documentation" /><h1>OSGi Compendium Release 7</h1></a></div>
</div>
<div id="mobile-menu-icon">⋮</div>
<div id="column-two">
<div id="content">
<div id="scrollable">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<td width="20%" align="left"><a accesskey="p" href="service.metatype.html">Prev</a>
</td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="service.useradmin.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter">
<div xmlns="" class="titlepage">
<div>
<div>
<h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="service.prefs"></a><span xmlns="" class="number">106</span> PreferencesService Specification
</h1>
</div>
<div>
<p xmlns="http://www.w3.org/1999/xhtml" class="releaseinfo"><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs" title="106.6 org.osgi.service.prefs">Version 1.1</a></p>
</div>
</div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a xmlns="" class="anchor" id="d0e20332"></a><span xmlns="" class="number">106.1</span> Introduction
</h2>
</div>
</div>
</div>
<p>Many bundles need to save some data persistently - in other words,
the data is required to survive the stopping and restarting of the bundle
and OSGi Framework. In some cases, the data is specific to a particular
user. For example, imagine a bundle that implements some kind of game.
User specific persistent data could include things like the user's
preferred difficulty level for playing the game. Some data is not specific
to a user, which we call <span class="emphasis"><em>system</em></span> data. An example
would be a table of high scores for the game.
</p>
<p>Bundles which need to persist data in an OSGi environment can use
the file system via
<code class="code">org.osgi.framework.BundleContext.getDataFile</code>. A file system,
however, can store only bytes and characters, and provides no direct
support for named values and different data types.
</p>
<p>A popular class used to address this problem for Java applications
is the <code class="code">java.util.Properties</code> class. This class allows data to
be stored as key/value pairs, called <span class="emphasis"><em>properties</em></span>. For
example, a property could have a name <code class="code">com.acme.fudd</code> and a
value of <code class="code">elmer</code>. The <code class="code">Properties</code> class has
rudimentary support for storage and retrieving with its <code class="code">load</code>
and <code class="code">store</code> methods. The <code class="code">Properties</code> class,
however, has the following limitations:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>Does not support a naming hierarchy.</p>
</li>
<li class="listitem">
<p>Only supports <code class="code">String</code> property values.
</p>
</li>
<li class="listitem">
<p>Does not allow its content to be easily stored in a back-end
system.
</p>
</li>
<li class="listitem">
<p>Has no user name-space management.</p>
</li>
</ul>
</div>
<p>Since the <code class="code">Properties</code> class was introduced in Java 1.0,
efforts have been undertaken to replace it with a more sophisticated
mechanism. One of these efforts is this Preferences Service
specification.
</p>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20392"></a><span xmlns="" class="number">106.1.1</span> Essentials
</h3>
</div>
</div>
</div>
<p>The focus of this specification is simplicity, not reliable access
to stored data. This specification does <span class="emphasis"><em>not</em></span> define
a general database service with transactions and atomicity guarantees.
Instead, it is optimized to deliver the stored information when needed,
but it will return defaults, instead of throwing an exception, when the
back-end store is not available. This approach may reduce the
reliability of the data, but it makes the service easier to use, and
allows for a variety of compact and efficient implementations.
</p>
<p>This API is made easier to use by the fact that many bundles can
be written to ignore any problems that the Preferences Service may have
in accessing the back-end store, if there is one. These bundles will
mostly or exclusively use the methods of the <code class="code">Preferences</code>
interface which are not declared to throw a
<code class="code">BackingStoreException</code>.
</p>
<p><span class="emphasis"><em>This service only supports the storage of scalar values
and byte arrays</em></span>. It is not intended for storing large data
objects like documents or images. No standard limits are placed on the
size of data objects which can be stored, but implementations are
expected to be optimized for the handling of small objects.
</p>
<p>A hierarchical naming model is supported, in contrast to the flat
model of the <code class="code">Properties</code> class. A hierarchical model maps
naturally to many computing problems. For example, maintaining
information about the positions of adjustable seats in a car requires
information for each seat. In a hierarchy, this information can be
modeled as a node per seat.
</p>
<p>A potential benefit of the Preferences Service is that it allows
user specific preferences data to be kept in a well defined place, so
that a user management system could locate it. This benefit could be
useful for such operations as cleaning up files when a user is removed
from the system, or to allow a user's preferences to be cloned for a new
user.
</p>
<p>The Preferences Service does <span class="emphasis"><em>not</em></span> provide a
mechanism to allow one bundle to access the preferences data of another.
If a bundle wishes to allow another bundle to access its preferences
data, it can pass a <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences" title="106.6.3 public interface Preferences">Preferences</a> or <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.PreferencesService" title="106.6.4 public interface PreferencesService">PreferencesService</a> object to that bundle.
</p>
<p>The Preferences Service is not intended to provide configuration
management functionality. For information regarding Configuration
Management, refer to the <a xmlns="" class="xref" href="service.cm.html" title="104 Configuration Admin Service Specification"><em xmlns="http://www.w3.org/1999/xhtml">Configuration Admin Service Specification</em></a>.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20432"></a><span xmlns="" class="number">106.1.2</span> Entities
</h3>
</div>
</div>
</div>
<p>The <code class="code">PreferencesService</code> is a relatively simple
service. It provides access to the different roots of Preferences trees.
A single system root node and any number of user root nodes are
supported. Each <span class="emphasis"><em>node</em></span> of such a tree is an object
that implements the <code class="code">Preferences</code> interface.
</p>
<p>This <code class="code">Preferences</code> interface provides methods for
traversing the tree, as well as methods for accessing the properties of
the node. This interface also contains the methods to flush data into
persistent storage, and to synchronize the in-memory data cache with the
persistent storage.
</p>
<p>All nodes except root nodes have a parent. Nodes can have multiple
children.
</p>
<div class="figure"><a xmlns="" class="anchor" id="i1423659"></a><p class="title"><strong>Figure <span xmlns="" class="number">106</span>.1 Preferences Class Diagram</strong></p>
<div class="figure-contents">
<div class="mediaobject" align="center"><img src="images/106-prefs-classes.png" align="middle" width="630" height="310" alt="Preferences Class Diagram" /></div>
</div>
</div><br class="figure-break" /></div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20459"></a><span xmlns="" class="number">106.1.3</span> Operation
</h3>
</div>
</div>
</div>
<p>The purpose of the Preferences Service specification is to allow
bundles to store and retrieve properties stored in a tree of nodes,
where each node implements the <code class="code">Preferences</code> interface. The
<code class="code">PreferencesService</code> interface allows a bundle to create or
obtain a Preferences tree for system properties, as well as a
Preferences tree for each user of the bundle.
</p>
<p>This specification allows for implementations where the data is
stored locally on the Framework or remotely on a back-end system.
</p>
</div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a xmlns="" class="anchor" id="d0e20472"></a><span xmlns="" class="number">106.2</span> Preferences Interface
</h2>
</div>
</div>
</div>
<p><code class="code">Preferences</code> is an interface that defines the methods to
manipulate a node and the tree to which it belongs. A
<code class="code">Preferences</code> object contains:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>A set of properties in the form of key/value pairs.</p>
</li>
<li class="listitem">
<p>A parent node.</p>
</li>
<li class="listitem">
<p>A number of child nodes.</p>
</li>
</ul>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20492"></a><span xmlns="" class="number">106.2.1</span> Hierarchies
</h3>
</div>
</div>
</div>
<p>A valid <code class="code">Preferences</code> object always belongs to a
<span class="emphasis"><em>tree</em></span>. A tree is identified by its root node. In
such a tree, a <code class="code">Preferences</code> object always has a single
parent, except for a root node which has a <code class="code">null</code>
parent.
</p>
<p>The root node of a tree can be found by recursively calling the
<a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.parent--" title="106.6.3.16 public Preferences parent()">parent()</a> method of a node until <code class="code">null</code> is
returned. The nodes that are traversed this way are called the
<span class="emphasis"><em>ancestors</em></span> of a node.
</p>
<p>Each Preferences object has a private name-space for child nodes.
Each child node has a name that must be unique among its siblings. Child
nodes are created by getting a child node with the <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.node-String-" title="106.6.3.14 public Preferences node(String pathName)">node(String)</a> method. The <code class="code">String</code> argument of this
call contains a path name. Path names are explained in the next
section.
</p>
<p>Child nodes can have child nodes recursively. These objects are
called the <span class="emphasis"><em>descendants</em></span> of a node.
</p>
<p>Descendants are automatically created when they are obtained from
a <code class="code">Preferences</code> object, including any intermediate nodes that
are necessary for the given path. If this automatic creation is not
desired, the <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.nodeExists-String-" title="106.6.3.15 public boolean nodeExists(String pathName) throws BackingStoreException">nodeExists(String)</a> method can be used to determine if a node
already exists.
</p>
<div class="figure"><a xmlns="" class="anchor" id="d0e20538"></a><p class="title"><strong>Figure <span xmlns="" class="number">106</span>.2 Categorization of nodes in a tree</strong></p>
<div class="figure-contents">
<div class="mediaobject" align="center"><img src="images/106-node-categorization.png" align="middle" width="585" height="135" alt="Categorization of nodes in a tree" /></div>
</div>
</div><br class="figure-break" /></div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20544"></a><span xmlns="" class="number">106.2.2</span> Naming
</h3>
</div>
</div>
</div>
<p>Each node has a name relative to its parent. A name may consist of
Unicode characters except for the solidus (<code class="code">'/' \u002F</code>).
There are no special names, like <code class="code">".."</code> or
<code class="code">"."</code>.
</p>
<p>Empty names are reserved for root nodes. Node names that are
directly created by a bundle must <span class="emphasis"><em>always</em></span> contain at
least one character.
</p>
<p>Preferences node names and property keys are <span class="emphasis"><em>case
sensitive</em></span>: for example, "<code class="code">org.osgi"</code> and
"<code class="code">oRg.oSgI</code>" are two distinct names.
</p>
<p>The Preferences Service supports different roots, so there is no
absolute root for the Preferences Service. This concept is similar to
the Windows Registry that also supports a number of roots.
</p>
<p>A path consists of one or more node names, separated by a solidus
(<code class="code">'/' \u002F</code>). Paths beginning with a solidus (<code class="code">'/'
\u002F</code>) are called <span class="emphasis"><em>absolute paths</em></span> while
other paths are called <span class="emphasis"><em>relative paths</em></span>. Paths cannot
end with a solidus (<code class="code">'/' \u002F</code>) except for the special case
of the root node which has absolute path <code class="code">"/"</code>.
</p>
<p>Path names are always associated with a specific node; this node
is called the current node in the following descriptions. Paths identify
nodes as follows.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><span class="emphasis"><em>Absolute path</em></span> - The first
<code class="code">"/"</code> is removed from the path, and the remainder of the
path is interpreted as a relative path from the tree's root
node.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Relative path</em></span> -
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
<p>If the path is the empty string, it identifies the current
node.
</p>
</li>
<li class="listitem">
<p>If the path is a name (does not contain a
<code class="code">"/"</code>), then it identifies the child node with that
name.
</p>
</li>
<li class="listitem">
<p>Otherwise, the first name from the path identifies a child
of the current node. The name and solidus (<code class="code">'/'
\u002F</code>) are then removed from the path, and the remainder
of the path is interpreted as a relative path from the child
node.
</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20628"></a><span xmlns="" class="number">106.2.3</span> Tree Traversal Methods
</h3>
</div>
</div>
</div>
<p>A tree can be traversed and modified with the following
methods:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.childrenNames--" title="106.6.3.2 public String[] childrenNames() throws BackingStoreException">childrenNames()</a> - Returns the names of the child
nodes.
</p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.parent--" title="106.6.3.16 public Preferences parent()">parent()</a> - Returns the parent node.
</p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.removeNode--" title="106.6.3.25 public void removeNode() throws BackingStoreException">removeNode()</a> - Removes this node and all its
descendants.
</p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.node-String-" title="106.6.3.14 public Preferences node(String pathName)">node(String)</a> - Returns a Preferences object, which is
created if it does not already exist. The parameter is an absolute
or relative path.
</p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.nodeExists-String-" title="106.6.3.15 public boolean nodeExists(String pathName) throws BackingStoreException">nodeExists(String)</a> - Returns true if the Preferences object
identified by the path parameter exists.
</p>
</li>
</ul>
</div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20654"></a><span xmlns="" class="number">106.2.4</span> Properties
</h3>
</div>
</div>
</div>
<p>Each Preferences node has a set of key/value pairs called
properties. These properties consist of:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><span class="emphasis"><em>Key</em></span> - A key is a <code class="code">String</code>
object and <span class="emphasis"><em>case sensitive.</em></span></p>
</li>
<li class="listitem">
<p>The name-space of these keys is separate from that of the
child nodes. A Preferences node could have both a child node named
<code class="code">fudd</code> and a property named <code class="code">fudd</code>.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Value</em></span> - A value can always be stored and
retrieved as a <code class="code">String</code> object. Therefore, it must be
possible to encode/decode all values into/from <code class="code">String</code>
objects (though it is not required to store them as such, an
implementation is free to store and retrieve the value in any
possible way as long as the <code class="code">String</code> semantics are
maintained). A number of methods are available to store and retrieve
values as primitive types. These methods are provided both for the
convenience of the user of the <code class="code">Preferences</code> interface,
and to allow an implementation the option of storing the values in a
more compact form.
</p>
</li>
</ul>
</div>
<p>All the keys that are defined in a <code class="code">Preferences</code> object
can be obtained with the <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.keys--" title="106.6.3.12 public String[] keys() throws BackingStoreException">keys()</a> method. The <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.clear--" title="106.6.3.3 public void clear() throws BackingStoreException">clear()</a> method can be used to clear all properties from
a <code class="code">Preferences</code> object. A single property can be removed with
the <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.remove-String-" title="106.6.3.24 public void remove(String key)">remove(String)</a> method.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20710"></a><span xmlns="" class="number">106.2.5</span> Storing and Retrieving Properties
</h3>
</div>
</div>
</div>
<p>The <code class="code">Preferences</code> interface has a number of methods for
storing and retrieving property values based on their key. All the
<code class="code">put*</code> methods take as parameters a key and a value. All the
<code class="code">get*</code> methods take as parameters a key and a default
value.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.put-String-String-" title="106.6.3.17 public void put(String key, String value)">put(String,String)</a>, <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.get-String-String-" title="106.6.3.5 public String get(String key, String def)">get(String,String)</a></p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.putBoolean-String-boolean-" title="106.6.3.18 public void putBoolean(String key, boolean value)">putBoolean(String,boolean)</a>, <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.getBoolean-String-boolean-" title="106.6.3.6 public boolean getBoolean(String key, boolean def)">getBoolean(String,boolean)</a></p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.putInt-String-int-" title="106.6.3.22 public void putInt(String key, int value)">putInt(String,int)</a>, <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.getInt-String-int-" title="106.6.3.10 public int getInt(String key, int def)">getInt(String,int)</a></p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.putLong-String-long-" title="106.6.3.23 public void putLong(String key, long value)">putLong(String,long)</a>, <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.getLong-String-long-" title="106.6.3.11 public long getLong(String key, long def)">getLong(String,long)</a></p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.putFloat-String-float-" title="106.6.3.21 public void putFloat(String key, float value)">putFloat(String,float)</a>, <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.getFloat-String-float-" title="106.6.3.9 public float getFloat(String key, float def)">getFloat(String,float)</a></p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.putDouble-String-double-" title="106.6.3.20 public void putDouble(String key, double value)">putDouble(String,double)</a>, <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.getDouble-String-double-" title="106.6.3.8 public double getDouble(String key, double def)">getDouble(String,double)</a></p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.putByteArray-String-byte---" title="106.6.3.19 public void putByteArray(String key, byte[] value)">putByteArray(String,byte[])</a>, <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.getByteArray-String-byte---" title="106.6.3.7 public byte[] getByteArray(String key, byte[] def)">getByteArray(String,byte[])</a></p>
</li>
</ul>
</div>
<p>The methods act as if all the values are stored as
<code class="code">String</code> objects, even though implementations may use
different representations for the different types. For example, a
property can be written as a <code class="code">String</code> object and read back as
a <code class="code">float</code>, providing that the string can be parsed as a valid
Java <code class="code">float</code> object. In the event of a parsing error, the
<code class="code">get*</code> methods do not raise exceptions, but instead return
their default parameters.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20777"></a><span xmlns="" class="number">106.2.6</span> Defaults
</h3>
</div>
</div>
</div>
<p>All <code class="code">get*</code> methods take a default value as a parameter.
The reasons for having such a default are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>When a property for a <code class="code">Preferences</code> object has not
been set, the default is returned instead. In most cases, the bundle
developer does not have to distinguish whether or not a property
exists.
</p>
</li>
<li class="listitem">
<p>A <span class="emphasis"><em>best effort</em></span> strategy has been a
specific design choice for this specification. The bundle developer
should not have to react when the back-end store is not available.
In those cases, the default value is returned without further
notice.
</p>
<p>Bundle developers who want to assure that the back-end store
is available should call the <code class="code">flush</code> or <code class="code">sync</code>
method. Either of these methods will throw a
<code class="code">BackingStoreException</code> if the back-end store is not
available.
</p>
</li>
</ul>
</div>
</div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a xmlns="" class="anchor" id="d0e20809"></a><span xmlns="" class="number">106.3</span> Concurrency
</h2>
</div>
</div>
</div>
<p>This specification specifically allows an implementation to modify
<code class="code">Preferences</code> objects in a back-end store. If the back-end
store is shared by multiple processes, concurrent updates may cause
differences between the back-end store and the in-memory
<code class="code">Preferences</code> objects.
</p>
<p>Bundle developers can partly control this concurrency with the <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.flush--" title="106.6.3.4 public void flush() throws BackingStoreException">flush()</a> and <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.Preferences.sync--" title="106.6.3.26 public void sync() throws BackingStoreException">sync()</a> method. Both methods operate on a
<code class="code">Preferences</code> object.
</p>
<p>The <code class="code">flush</code> method performs the following actions:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>Stores (makes persistent) any ancestors (including the current
node) that do not exist in the persistent store.
</p>
</li>
<li class="listitem">
<p>Stores any properties which have been modified in this node
since the last time it was flushed.
</p>
</li>
<li class="listitem">
<p>Removes from the persistent store any child nodes that were
removed from this object since the last time it was flushed.
</p>
</li>
<li class="listitem">
<p>Flushes all existing child nodes.</p>
</li>
</ul>
</div>
<p>The <code class="code">sync</code> method will first flush, and then ensure that
any changes that have been made to the current node and its descendants in
the back-end store (by some other process) take effect. For example, it
could fetch all the descendants into a local cache, or it could clear all
the descendants from the cache so that they will be read from the back-end
store as required.
</p>
<p>If either method fails, a <code class="code">BackingStoreException</code> is
thrown.
</p>
<p>The <code class="code">flush</code> or <code class="code">sync</code> methods provide no
atomicity guarantee. When updates to the same back-end store are done
concurrently by two different processes, the result may be that changes
made by different processes are intermingled. To avoid this problem,
implementations may simply provide a dedicated section (or name-space) in
the back-end store for each OSGi environment, so that clashes do not
arise, in which case there is no reason for bundle programmers to ever
call <code class="code">sync</code>.
</p>
<p>In cases where <code class="code">sync</code> is used, the bundle programmer
needs to take into account that changes from different processes may
become intermingled, and the level of granularity that can be assumed is
the individual property level. Hence, for example, if two properties need
to be kept in lockstep, so that one should not be changed without a
corresponding change to the other, consider combining them into a single
property, which would then need to be parsed into its two constituent
parts.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a xmlns="" class="anchor" id="d0e20873"></a><span xmlns="" class="number">106.4</span> PreferencesService Interface
</h2>
</div>
</div>
</div>
<p>The <code class="code">PreferencesService</code> is obtained from the Framework's
service registry in the normal way. Its purpose is to provide access to
Preferences root nodes.
</p>
<p>A Preferences Service maintains a system root and a number of user
roots. User roots are automatically created, if necessary, when they are
requested. Roots are maintained on a per bundle basis. For example, a user
root called <code class="code">elmer</code> in one bundle is distinct from a user root
with the same name in another bundle. Also, each bundle has its own system
root. Implementations should use a <code class="code">ServiceFactory</code> service
object to create a separate <code class="code">PreferencesService</code> object for
each bundle.
</p>
<p>The precise description of <span class="emphasis"><em>user</em></span> and
<span class="emphasis"><em>system</em></span> will vary from one bundle to another. The
Preference Service only provides a mechanism, the bundle may use this
mechanism in any desired way.
</p>
<p>The <a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.PreferencesService" title="106.6.4 public interface PreferencesService">PreferencesService</a> interface has the following methods to access the
system root and user roots:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.PreferencesService.getSystemPreferences--" title="106.6.4.1 public Preferences getSystemPreferences()">getSystemPreferences()</a> - Return a <code class="code">Preferences</code> object
that is the root of the system preferences tree.
</p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.PreferencesService.getUserPreferences-String-" title="106.6.4.2 public Preferences getUserPreferences(String name)">getUserPreferences(String)</a> - Return a <code class="code">Preferences</code> object
associated with the user name that is given as argument. If the user
does not exist, a new root is created atomically.
</p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.prefs.html#org.osgi.service.prefs.PreferencesService.getUsers--" title="106.6.4.3 public String[] getUsers()">getUsers()</a> - Return an array of the names of all the
users for whom a Preferences tree exists.
</p>
</li>
</ul>
</div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a xmlns="" class="anchor" id="i1423660"></a><span xmlns="" class="number">106.5</span> Cleanup
</h2>
</div>
</div>
</div>
<p>The Preferences Service must listen for bundle uninstall events, and
remove all the preferences data for the bundle that is being uninstalled.
The Preferences Service must use the bundle id for the association and not
the location.
</p>
<p>It also must handle the possibility of a bundle getting uninstalled
while the Preferences Service is stopped. Therefore, it must check on
startup whether preferences data exists for any bundle which is not
currently installed. If it does, that data must be removed.
</p>
</div>
<div class="section package">
<div xmlns="" class="titlepage">
<div>
<div>
<h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a xmlns="" class="anchor" id="org.osgi.service.prefs"></a><span xmlns="" class="number">106.6</span> org.osgi.service.prefs
</h2>
</div>
<div>
<p xmlns="http://www.w3.org/1999/xhtml" class="releaseinfo">Version 1.1</p>
</div>
</div>
</div>
<p>
Preferences Service Package Version 1.1.
</p>
<p>
Bundles wishing to use this package must list the package in the
Import-Package header of the bundle's manifest. This package has two types of
users: the consumers that use the API in this package and the providers that
implement the API in this package.
</p>
<p>
Example import for consumers using the API in this package:
</p>
<p>
<code class="code">Import-Package: org.osgi.service.prefs; version="[1.1,2.0)"</code>
</p>
<p>
Example import for providers implementing the API in this package:
</p>
<p>
<code class="code">Import-Package: org.osgi.service.prefs; version="[1.1,1.2)"</code>
</p>
<div class="section summary">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e20956"></a><span xmlns="" class="number">106.6.1</span> Summary
</h3>
</div>
</div>
</div>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>
<a xmlns="" class="link" href="service.prefs.html#org.osgi.service.prefs.BackingStoreException" title="106.6.2 public class BackingStoreException extends Exception">
<code xmlns="http://www.w3.org/1999/xhtml" class="code">BackingStoreException</code>
</a> -
Thrown to indicate that a preferences operation could not complete because of
a failure in the backing store, or a failure to contact the backing store.
</p>
</li>
<li class="listitem">
<p>
<a xmlns="" class="link" href="service.prefs.html#org.osgi.service.prefs.Preferences" title="106.6.3 public interface Preferences">
<code xmlns="http://www.w3.org/1999/xhtml" class="code">Preferences</code>
</a> -
A node in a hierarchical collection of preference data.
</p>
</li>
<li class="listitem">
<p>
<a xmlns="" class="link" href="service.prefs.html#org.osgi.service.prefs.PreferencesService" title="106.6.4 public interface PreferencesService">
<code xmlns="http://www.w3.org/1999/xhtml" class="code">PreferencesService</code>
</a> -
The Preferences Service.
</p>
</li>
</ul>
</div>
</div>
<div class="section class">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="org.osgi.service.prefs.BackingStoreException"></a><span xmlns="" class="number">106.6.2</span> public class BackingStoreException<br xmlns="" /> extends Exception
</h3>
</div>
</div>
</div>
<p>
Thrown to indicate that a preferences operation could not complete because of
a failure in the backing store, or a failure to contact the backing store.
</p>
<div class="section method">
<div xmlns="" class="titlepage">
<div>
<div>
<h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="org.osgi.service.prefs.BackingStoreException.BackingStoreException-String-"></a><span xmlns="" class="number">106.6.2.1</span> public BackingStoreException(String message)
</h4>
</div>
</div>
</div>
<p xmlns="" class="parameter"><label>message</label><span>The detail message.</span></p>
<p xmlns="" class="description"><label>□</label><span>
Constructs a <code xmlns="http://www.w3.org/1999/xhtml" class="code">BackingStoreException</code> with the specified detail
message.
</span></p>
</div>
<div class="section method">
<div xmlns="" class="titlepage">
<div>
<div>
<h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="org.osgi.service.prefs.BackingStoreException.BackingStoreException-String-Throwable-"></a><span xmlns="" class="number">106.6.2.2</span> public BackingStoreException(String message, Throwable cause)
</h4>
</div>
</div>
</div>
<p xmlns="" class="parameter"><label>message</label><span>The detail message.</span></p>
<p xmlns="" class="parameter"><label>cause</label><span>The cause of the exception. May be <code xmlns="http://www.w3.org/1999/xhtml" class="code">null</code>.</span></p>
<p xmlns="" class="description"><label>□</label><span>
Constructs a <code xmlns="http://www.w3.org/1999/xhtml" class="code">BackingStoreException</code> with the specified detail
message.
</span></p>
<p xmlns="" class="parameter"><label>Since</label><span>1.1</span></p>
</div>
<div class="section method">
<div xmlns="" class="titlepage">
<div>
<div>
<h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="org.osgi.service.prefs.BackingStoreException.getCause--"></a><span xmlns="" class="number">106.6.2.3</span> public Throwable getCause()
</h4>
</div>
</div>
</div>
<p xmlns="" class="description"><label>□</label><span>
Returns the cause of this exception or <code xmlns="http://www.w3.org/1999/xhtml" class="code">null</code> if no cause was set.
</span></p>
<p xmlns="" class="parameter"><label>Returns</label><span>The cause of this exception or <code xmlns="http://www.w3.org/1999/xhtml" class="code">null</code> if no cause was set.</span></p>
<p xmlns="" class="parameter"><label>Since</label><span>1.1</span></p>
<p></p>
</div>
<div class="section method">
<div xmlns="" class="titlepage">
<div>
<div>
<h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="org.osgi.service.prefs.BackingStoreException.initCause-Throwable-"></a><span xmlns="" class="number">106.6.2.4</span> public Throwable initCause(Throwable cause)
</h4>
</div>
</div>
</div>
<p xmlns="" class="parameter"><label>cause</label><span>The cause of this exception.</span></p>
<p xmlns="" class="description"><label>□</label><span>
Initializes the cause of this exception to the specified value.
</span></p>
<p xmlns="" class="parameter"><label>Returns</label><span>This exception.</span></p>
<p xmlns="" class="parameter"><label>Throws</label><span>
<code xmlns="http://www.w3.org/1999/xhtml" class="code">IllegalArgumentException</code>– If the specified cause is this
exception.</span></p>
<p xmlns="" class="parameter"><label></label><span>
<code xmlns="http://www.w3.org/1999/xhtml" class="code">IllegalStateException</code>– If the cause of this exception has already
been set.</span></p>
<p xmlns="" class="parameter"><label>Since</label><span>1.1</span></p>
<p></p>
</div>
</div>
<div class="section class">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="org.osgi.service.prefs.Preferences"></a><span xmlns="" class="number">106.6.3</span> public interface Preferences
</h3>
</div>
</div>
</div>
<p>
A node in a hierarchical collection of preference data.
</p>
<p>
This interface allows applications to store and retrieve user and system
preference data. This data is stored persistently in an
implementation-dependent backing store. Typical implementations include flat
files, OS-specific registries, directory servers and SQL databases.
</p>
<p>
For each bundle, there is a separate tree of nodes for each user, and one for
system preferences. The precise description of "user" and "system" will vary
from one bundle to another. Typical information stored in the user preference
tree might include font choice, and color choice for a bundle which interacts
with the user via a servlet. Typical information stored in the system
preference tree might include installation data, or things like high score
information for a game program.
</p>
<p>
Nodes in a preference tree are named in a similar fashion to directories in a
hierarchical file system. Every node in a preference tree has a <span class="emphasis"><em>node name
</em></span> (which is not necessarily unique), a unique <span class="emphasis"><em>absolute path name </em></span>,
and a path name <span class="emphasis"><em>relative </em></span> to each ancestor including itself.
</p>
<p>
The root node has a node name of the empty <code class="code">String</code> object (""). Every
other node has an arbitrary node name, specified at the time it is created.
The only restrictions on this name are that it cannot be the empty string,
and it cannot contain the slash character ('/').
</p>
<p>
The root node has an absolute path name of <code class="code">"/"</code>. Children of the root
node have absolute path names of <code class="code">"/" +</code>
<span class="emphasis"><em><node name> </em></span>.
All other nodes have absolute path names of <span class="emphasis"><em><parent's absolute path
name> </em></span>
<code class="code">+ "/" +</code>
<span class="emphasis"><em><node name> </em></span>. Note that all
absolute path names begin with the slash character.
</p>
<p>
A node <span class="emphasis"><em>n </em></span>'s path name relative to its ancestor <span class="emphasis"><em>a </em></span> is simply the
string that must be appended to <span class="emphasis"><em>a </em></span>'s absolute path name in order to
form <span class="emphasis"><em>n </em></span>'s absolute path name, with the initial slash character (if
present) removed. Note that:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>No relative path names begin with the slash character.</p>
</li>
<li class="listitem">
<p>Every node's path name relative to itself is the empty string.</p>
</li>
<li class="listitem">
<p>Every node's path name relative to its parent is its node name (except
for the root node, which does not have a parent).
</p>
</li>
<li class="listitem">
<p>Every node's path name relative to the root is its absolute path name
with the initial slash character removed.
</p>
</li>
</ul>
</div>
<p>
Note finally that:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>No path name contains multiple consecutive slash characters.</p>
</li>
<li class="listitem">
<p>No path name with the exception of the root's absolute path name end in
the slash character.
</p>
</li>
<li class="listitem">
<p>Any string that conforms to these two rules is a valid path name.</p>
</li>
</ul>
</div>
<p>
Each <code class="code">Preference</code> node has zero or more properties associated with it,
where a property consists of a name and a value. The bundle writer is free to
choose any appropriate names for properties. Their values can be of type
<code class="code">String</code>,<code class="code">long</code>,<code class="code">int</code>,<code class="code">boolean</code>, <code class="code">byte[]</code>,
<code class="code">float</code>, or <code class="code">double</code> but they can always be accessed as if they
were <code class="code">String</code> objects.
</p>
<p>
All node name and property name comparisons are case-sensitive.
</p>
<p>
All of the methods that modify preference data are permitted to operate
asynchronously; they may return immediately, and changes will eventually
propagate to the persistent backing store, with an implementation-dependent
delay. The <code class="code">flush</code> method may be used to synchronously force updates to
the backing store.
</p>
<p>
Implementations must automatically attempt to flush to the backing store any
pending updates for a bundle's preferences when the bundle is stopped or
otherwise ungets the Preferences Service.
</p>
<p>
The methods in this class may be invoked concurrently by multiple threads in
a single Java Virtual Machine (JVM) without the need for external
synchronization, and the results will be equivalent to some serial execution.
If this class is used concurrently <span class="emphasis"><em>by multiple JVMs </em></span> that store their
preference data in the same backing store, the data store will not be
corrupted, but no other guarantees are made concerning the consistency of the
preference data.
</p>
<p xmlns="" class="parameter"><label>No Implement</label><span>Consumers of this API must not implement this interface</span></p>
<div class="section method">
<div xmlns="" class="titlepage">
<div>
<div>
<h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="org.osgi.service.prefs.Preferences.absolutePath--"></a><span xmlns="" class="number">106.6.3.1</span> public String absolutePath()
</h4>
</div>
</div>