1--
2--  Copyright (c) 2008-2012,
3--  Reto Buerki, Adrian-Ken Rueegsegger
4--
5--  This file is part of Alog.
6--
7--  Alog is free software; you can redistribute it and/or modify
8--  it under the terms of the GNU Lesser General Public License as published
9--  by the Free Software Foundation; either version 2.1 of the License, or
10--  (at your option) any later version.
11--
12--  Alog is distributed in the hope that it will be useful,
13--  but WITHOUT ANY WARRANTY; without even the implied warranty of
14--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15--  GNU Lesser General Public License for more details.
16--
17--  You should have received a copy of the GNU Lesser General Public License
18--  along with Alog; if not, write to the Free Software
19--  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20--  MA  02110-1301  USA
21--
22
23with Alog.Log_Request;
24with Alog.Facilities.File_Descriptor;
25
26package body Alog.Logger is
27
28   -------------------------------------------------------------------------
29
30   procedure Attach_Default_Facility (Logger : in out Instance)
31   is
32   begin
33      if not Logger.Facilities.Contains
34        (Key => To_Unbounded_String (Default_Facility_Name))
35      then
36         declare
37            Default_Handle : Facilities.File_Descriptor.Handle;
38         begin
39            Default_Handle := new Facilities.File_Descriptor.Instance;
40            Default_Handle.Set_Name (Name => Default_Facility_Name);
41
42            Logger.Attach_Facility
43              (Facility => Facilities.Handle (Default_Handle));
44         end;
45      end if;
46   end Attach_Default_Facility;
47
48   -------------------------------------------------------------------------
49
50   procedure Attach_Facility
51     (Logger   : in out Instance;
52      Facility :        Facilities.Handle)
53   is
54      F_Name : constant Unbounded_String :=
55        To_Unbounded_String (Facility.Get_Name);
56   begin
57      if Logger.Facilities.Contains (Key => F_Name) then
58         raise Facility_Already_Present with "Facility '"
59           & To_String (F_Name)
60           & "' is already present.";
61      end if;
62
63      Logger.Facilities.Insert
64        (Key      => F_Name,
65         New_Item => Facility);
66   end Attach_Facility;
67
68   -------------------------------------------------------------------------
69
70   procedure Attach_Transform
71     (Logger    : in out Instance;
72      Transform :        Transforms.Handle)
73   is
74      T_Name : constant Unbounded_String :=
75        To_Unbounded_String (Transform.Get_Name);
76   begin
77      if Logger.Transforms.Contains (Key => T_Name) then
78         raise Transform_Already_Present with "Transform '"
79           & To_String (T_Name)
80           & "' is already present.";
81      end if;
82
83      Logger.Transforms.Insert
84        (Key      =>  T_Name,
85         New_Item => Transform);
86   end Attach_Transform;
87
88   -------------------------------------------------------------------------
89
90   procedure Clear (L : in out Instance) is
91
92      procedure Teardown_Facility (Handle : Facilities.Handle);
93      --  Teardown a facility.
94
95      procedure Teardown_Facility (Handle : Facilities.Handle) is
96      begin
97         Handle.Teardown;
98      end Teardown_Facility;
99
100      procedure Teardown_Transform (Handle : Transforms.Handle);
101      --  Teardown a transform.
102
103      procedure Teardown_Transform (Handle : Transforms.Handle) is
104      begin
105         Handle.Teardown;
106      end Teardown_Transform;
107
108   begin
109      L.Facilities.Iterate (Process => Teardown_Facility'Access);
110      L.Facilities.Clear;
111
112      L.Transforms.Iterate (Process => Teardown_Transform'Access);
113      L.Transforms.Clear;
114   end Clear;
115
116   -------------------------------------------------------------------------
117
118   procedure Detach_Default_Facility (Logger : in out Instance)
119   is
120   begin
121      if Logger.Facilities.Contains
122        (Key => To_Unbounded_String (Default_Facility_Name))
123      then
124         Logger.Detach_Facility (Name => Default_Facility_Name);
125      end if;
126   end Detach_Default_Facility;
127
128   -------------------------------------------------------------------------
129
130   procedure Detach_Facility
131     (Logger : in out Instance;
132      Name   :        String)
133   is
134      F_Name : constant Unbounded_String := To_Unbounded_String (Name);
135   begin
136      if not Logger.Facilities.Contains (Key => F_Name) then
137         raise Facility_Not_Found with "Facility '"
138           & Name & "' not found.";
139      end if;
140
141      Logger.Facilities.Delete (Key => F_Name);
142   end Detach_Facility;
143
144   -------------------------------------------------------------------------
145
146   procedure Detach_Transform
147     (Logger : in out Instance;
148      Name   :        String)
149   is
150      T_Name   : constant Unbounded_String := To_Unbounded_String (Name);
151   begin
152      if not Logger.Transforms.Contains (Key => T_Name) then
153         raise Transform_Not_Found with "Transform '"
154           & Name & "' not found.";
155      end if;
156
157      Logger.Transforms.Delete (Key => T_Name);
158   end Detach_Transform;
159
160   -------------------------------------------------------------------------
161
162   function Facility_Count (Logger : Instance) return Natural is
163   begin
164      return Logger.Facilities.Length;
165   end Facility_Count;
166
167   -------------------------------------------------------------------------
168
169   procedure Finalize (Logger : in out Instance) is
170   begin
171      Logger.Clear;
172   end Finalize;
173
174   -------------------------------------------------------------------------
175
176   procedure Initialize (Logger : in out Instance) is
177   begin
178      if Logger.Init then
179         Logger.Attach_Default_Facility;
180      end if;
181   end Initialize;
182
183   -------------------------------------------------------------------------
184
185   procedure Iterate
186     (Logger  : Instance;
187      Process : not null access
188        procedure (Facility_Handle : Facilities.Handle))
189   is
190   begin
191      Logger.Facilities.Iterate (Process => Process);
192   end Iterate;
193
194   -------------------------------------------------------------------------
195
196   procedure Iterate
197     (Logger  : Instance;
198      Process : not null access procedure
199        (Transform_Handle : Transforms.Handle))
200   is
201   begin
202      Logger.Transforms.Iterate (Process => Process);
203   end Iterate;
204
205   -------------------------------------------------------------------------
206
207   procedure Log_Message
208     (Logger : Instance;
209      Level  : Log_Level;
210      Msg    : String;
211      Source : String := "")
212   is
213      Out_Msg : String := Msg;
214
215      procedure Do_Log (Facility_Handle : Facilities.Handle);
216      --  Log message for each facility.
217
218      procedure Do_Log (Facility_Handle : Facilities.Handle)
219      is
220         New_Request : constant Log_Request.Instance :=
221           Log_Request.Create
222             (Source  => Source,
223              Level   => Level,
224              Message => Out_Msg);
225      begin
226         Facility_Handle.Process (Request => New_Request);
227      end Do_Log;
228
229      procedure Do_Transform (Transform_Handle : Transforms.Handle);
230      --  Call 'Transform_Message' for each transform.
231
232      procedure Do_Transform (Transform_Handle : Transforms.Handle) is
233      begin
234         Out_Msg := Transform_Handle.Transform_Message
235           (Level => Level,
236            Msg   => Out_Msg);
237      end Do_Transform;
238   begin
239      Logger.Iterate (Process => Do_Transform'Access);
240      Logger.Iterate (Process => Do_Log'Access);
241   end Log_Message;
242
243   -------------------------------------------------------------------------
244
245   function Transform_Count (Logger : Instance) return Natural is
246   begin
247      return Logger.Transforms.Length;
248   end Transform_Count;
249
250   -------------------------------------------------------------------------
251
252   procedure Update
253     (Logger  : Instance;
254      Name    : String;
255      Process : not null access
256        procedure (Facility_Handle : Facilities.Handle))
257   is
258      F_Name : constant Unbounded_String := To_Unbounded_String (Name);
259   begin
260      if not Logger.Facilities.Contains (Key => F_Name) then
261         raise Facility_Not_Found with "Facility '" & Name & "' not found";
262      end if;
263
264      declare
265         Handle : constant Facilities.Handle :=
266           Logger.Facilities.Element (Key => F_Name);
267      begin
268         Process (Facility_Handle => Handle);
269      end;
270   end Update;
271
272   -------------------------------------------------------------------------
273
274   procedure Update
275     (Logger  : Instance;
276      Name    : String;
277      Process : not null access
278        procedure (Transform_Handle : Transforms.Handle))
279   is
280      T_Name : constant Unbounded_String := To_Unbounded_String (Name);
281   begin
282      if not Logger.Transforms.Contains (Key => T_Name) then
283         raise Transform_Not_Found with "Transform '" & Name & "' not found";
284      end if;
285
286      declare
287         Handle : constant Transforms.Handle :=
288           Logger.Transforms.Element (Key => T_Name);
289      begin
290         Process (Transform_Handle => Handle);
291      end;
292   end Update;
293
294end Alog.Logger;
295