are_1.2.0_16239a8b/ada-util/src/base/properties/util-properties-bundles.ads

  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
-----------------------------------------------------------------------
--  util-properties-bundles -- Generic name/value property management
--  Copyright (C) 2001, 2002, 2003, 2006, 2008, 2009, 2010, 2011, 2012, 2018 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Containers;
with Ada.Finalization;
with Ada.Containers.Hashed_Maps;
with Util.Strings;
with Util.Concurrent.Locks;

--  == Property bundles ==
--  Property bundles represent several property files that share some overriding rules and
--  capabilities.  Their introduction comes from Java resource bundles which allow to
--  localize easily some configuration files or some message.  When loading a property bundle
--  a locale is defined to specify the target language and locale.  If a specific property
--  file for that locale exists, it is used first.  Otherwise, the property bundle will use
--  the default property file.
--
--  A rule exists on the name of the specific property locale file: it must start with the
--  bundle name followed by `_` and the name of the locale.  The default property file must
--  be the bundle name.  For example, the bundle `dates` is associated with the following
--  property files:
--
--    dates.properties           Default values (English locale)
--    dates_fr.properties        French locale
--    dates_de.properties        German locale
--    dates_es.properties        Spain locale
--
--  Because a bundle can be associated with one or several property files, a specific loader is
--  used.  The loader instance must be declared and configured to indicate one or several search
--  directories that contain property files.
--
--    with Util.Properties.Bundles;
--    ...
--       Loader : Util.Properties.Bundles.Loader;
--       Bundle : Util.Properties.Bundles.Manager;
--       ...
--       Util.Properties.Bundles.Initialize (Loader,
--                                           "bundles;/usr/share/bundles");
--       Util.Properties.Bundles.Load_Bundle (Loader, "dates", "fr", Bundle);
--       Ada.Text_IO.Put_Line (Bundle.Get ("util.month1.long");
--
--  In this example, the `util.month1.long` key is first searched in the `dates_fr` French locale
--  and if it is not found it is searched in the default locale.
--
--  The restriction when using bundles is that they don't allow changing any value and the
--  `NOT_WRITEABLE` exception is raised when one of the `Set` operation is used.
--
--  When a bundle cannot be loaded, the `NO_BUNDLE` exception is raised by the `Load_Bundle`
--  operation.
package Util.Properties.Bundles is

   NO_BUNDLE : exception;

   NOT_WRITEABLE : exception;

   type Manager is new Util.Properties.Manager with private;

   --  ------------------------------
   --  Bundle loader
   --  ------------------------------
   --  The <b>Loader</b> provides facilities for loading property bundles
   --  and maintains a cache of bundles.  The cache is thread-safe but the returned
   --  bundles are not thread-safe.
   type Loader is limited private;
   type Loader_Access is access all Loader;

   --  Initialize the bundle factory and specify where the property files are stored.
   procedure Initialize (Factory : in out Loader;
                         Path    : in String);

   --  Load the bundle with the given name and for the given locale name.
   procedure Load_Bundle (Factory : in out Loader;
                          Name    : in String;
                          Locale  : in String;
                          Bundle  : out Manager'Class);
private

   procedure Add_Bundle (Self : in out Manager; Props : in Manager_Access);
   --  Add a bundle

   type Bundle_Manager_Access is access all Manager'Class;

   type Manager is new Util.Properties.Manager with null record;

   overriding
   procedure Initialize (Object : in out Manager);

   overriding
   procedure Adjust (Object : in out Manager);

   package Bundle_Map is
     new Ada.Containers.Hashed_Maps
       (Element_Type    => Bundle_Manager_Access,
        Key_Type        => Util.Strings.Name_Access,
        Hash            => Util.Strings.Hash,
        Equivalent_Keys => Util.Strings.Equivalent_Keys);

   type Loader is new Ada.Finalization.Limited_Controlled with record
      Lock    : Util.Concurrent.Locks.RW_Lock;
      Bundles : Bundle_Map.Map;
      Path    : Unbounded_String;
   end record;

   --  Finalize the bundle loader and clear the cache
   overriding
   procedure Finalize (Factory : in out Loader);

   --  Clear the cache bundle
   procedure Clear_Cache (Factory : in out Loader);

   --  Find the bundle with the given name and for the given locale name.
   procedure Find_Bundle (Factory : in out Loader;
                          Name    : in String;
                          Locale  : in String;
                          Bundle  : out Manager'Class;
                          Found   : out Boolean);

   --  Load the bundle with the given name and for the given locale name.
   procedure Load_Bundle (Factory : in out Loader;
                          Name    : in String;
                          Found   : out Boolean);

end Util.Properties.Bundles;