<commit_before>-----------------------------------------------------------------------
--  asf-factory -- Component and tag factory
--  Copyright (C) 2009, 2010 <NAME>
--  Written by <NAME> (<EMAIL>)
--
--  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 Util.Log.Loggers;
package body ASF.Factory is

   use Util.Log;

   --  The logger
   Log : constant Loggers.Logger := Loggers.Create ("ASF.Factory");

   --  ------------------------------
   --  Find the create function associated with the name.
   --  Returns null if there is no binding associated with the name.
   --  ------------------------------
   function Find (Factory : Factory_Bindings;
                  Name    : String) return Binding is
      Left  : Natural := Factory.Bindings'First;
      Right : Natural := Factory.Bindings'Last;
   begin
      while Left <= Right loop
         declare
            Pos  : constant Natural := (Left + Right + 1) / 2;
            Item : constant Name_Access := Factory.Bindings (Pos).Name;
         begin
            if Name = Item.all then
               return Factory.Bindings (Pos);
            elsif Name < Item.all then
               Right := Pos - 1;
            else
               Left := Pos + 1;
            end if;
         end;
      end loop;
      raise Unknown_Name;
   end Find;

   --  ------------------------------
   --  Check the definition of the component factory.
   --  ------------------------------
   procedure Check (Factory : in Factory_Bindings) is
      P : Name_Access := null;
   begin
      Log.Debug ("Check binding for {0}", Factory.URI.all);


      for I in Factory.Bindings'Range loop
         declare
            B : constant Binding := Factory.Bindings (I);
         begin
            if P /= null then
               if B.Name.all = P.all then
                  Log.Error ("In factory {0}, binding {1} registered twice",
                             Factory.URI.all, P.all);
                  raise Program_Error
                    with Factory.URI.all & ": binding '" & P.all & "' registered twice";
               end if;
               if B.Name.all < P.all then
                  Log.Error ("In factory {0}, binding {1} at position {2} "
                             & "is not at the good place", Factory.URI.all, P.all,
                             Natural'Image (I));
                  raise Program_Error
                    with Factory.URI.all & ": binding '" & B.Name.all
                      & "' at position " & Natural'Image (I) & " not at the good place";
               end if;
            end if;
            P := B.Name;
         end;
      end loop;
   end Check;

   --  ------------------------------
   --  Find the create function in bound to the name in the given URI namespace.
   --  Returns null if no such binding exist.
   --  ------------------------------
   function Find (Factory : Component_Factory;
                  URI     : String;
                  Name    : String) return Binding is
      NS  : aliased constant String := URI;
      Pos : constant Factory_Maps.Cursor := Factory.Map.Find (NS'Unchecked_Access);
   begin
      if not Factory_Maps.Has_Element (Pos) then
         raise Unknown_Name;
      end if;
      return Find (Factory => Factory_Maps.Element (Pos).all, Name => Name);
   end Find;

   --  ------------------------------
   --  Register a binding library in the factory
   --  ------------------------------
   procedure Register (Factory  : in out Component_Factory;
                       Bindings : in Factory_Bindings_Access) is
   begin
      Log.Info ("Register bindings: {0}", Bindings.URI.all);

      Check (Bindings.all);
      Factory.Map.Include (Bindings.URI, Bindings);
   end Register;

   --  ------------------------------
   --  Register the converter instance under the given name.
   --  ------------------------------
   procedure Register (Factory   : in out Component_Factory;
                       Name      : in String;
                       Converter : in ASF.Converters.Converter_Access) is
   begin
      Log.Info ("Register converter: {0}", Name);

      Factory.Converters.Include (EL.Objects.To_Object (Name), Converter);
   end Register;

   --  ------------------------------
   --  Find the converter instance that was registered under the given name.
   --  Returns null if no such converter exist.
   --  ------------------------------
   function Find (Factory : in Component_Factory;
                  Name    : in EL.Objects.Object) return ASF.Converters.Converter_Access is
      Pos : constant Converter_Maps.Cursor := Factory.Converters.Find (Name);
   begin
      if Converter_Maps.Has_Element (Pos) then
         return Converter_Maps.Element (Pos);
      else
         return null;
      end if;
   end Find;

   --  ------------------------------
   --  Register the validator instance under the given name.<commit_msg>- New hash operation to hash on the namespace and the name (ie, Tag_Name) - Find the component factory using a single search in the hash map - Remove the Check and Find operation<commit_after>-----------------------------------------------------------------------
--  asf-factory -- Component and tag factory
--  Copyright (C) 2009, 2010, 2011, 2012, 2013 <NAME>
--  Written by <NAME> (<EMAIL>)
--
--  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 Util.Log.Loggers;
with Ada.Strings.Hash;
package body ASF.Factory is

   --  The logger
   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("ASF.Factory");

   --  ------------------------------
   --  Compute a hash for the tag name.
   --  ------------------------------
   function Hash (Key : in Tag_Name) return Ada.Containers.Hash_Type is
      use type Ada.Containers.Hash_Type;

      H1 : constant Ada.Containers.Hash_Type := Ada.Strings.Hash (Key.URI.all);
      H2 : constant Ada.Containers.Hash_Type := Ada.Strings.Hash (Key.Name.all);
   begin
      return H1 xor H2;
   end Hash;

   --  ------------------------------
   --  Returns true if both tag names are identical.
   --  ------------------------------
   function "=" (Left, Right : in Tag_Name) return Boolean is
   begin
      return Left.URI.all = Right.URI.all and Left.Name.all = Right.Name.all;
   end "=";

   --  ------------------------------
   --  Find the create function in bound to the name in the given URI namespace.
   --  Returns null if no such binding exist.
   --  ------------------------------
   function Find (Factory : in Component_Factory;
                  URI     : in String;
                  Name    : in String) return Binding_Access is
      Key : constant Tag_Name := Tag_Name '(URI  => URI'Unrestricted_Access,
                                            Name => Name'Unrestricted_Access);
      Pos : constant Factory_Maps.Cursor := Factory.Map.Find (Key);
   begin
      if Factory_Maps.Has_Element (Pos) then
         return Factory_Maps.Element (Pos);
      else
         return null;
      end if;
   end Find;

   --  ------------------------------
   --  Register a binding library in the factory
   --  ------------------------------
   procedure Register (Factory  : in out Component_Factory;
                       Bindings : in Factory_Bindings_Access) is
   begin
      Log.Info ("Register bindings: {0}", Bindings.URI.all);

      for I in Bindings.Bindings'Range loop
         declare
            Key : constant Tag_Name := Tag_Name '(URI  => Bindings.URI,
                                                  Name => Bindings.Bindings (I).Name);
         begin
            Factory.Map.Include (Key, Bindings.Bindings (I)'Access);
         end;
      end loop;
   end Register;

   --  ------------------------------
   --  Register the converter instance under the given name.
   --  ------------------------------
   procedure Register (Factory   : in out Component_Factory;
                       Name      : in String;
                       Converter : in ASF.Converters.Converter_Access) is
   begin
      Log.Info ("Register converter: {0}", Name);

      Factory.Converters.Include (EL.Objects.To_Object (Name), Converter);
   end Register;

   --  ------------------------------
   --  Find the converter instance that was registered under the given name.
   --  Returns null if no such converter exist.
   --  ------------------------------
   function Find (Factory : in Component_Factory;
                  Name    : in EL.Objects.Object) return ASF.Converters.Converter_Access is
      Pos : constant Converter_Maps.Cursor := Factory.Converters.Find (Name);
   begin
      if Converter_Maps.Has_Element (Pos) then
         return Converter_Maps.Element (Pos);
      else
         return null;
      end if;
   end Find;

   --  ------------------------------
   --  Register the validator instance under the given name.
{'fraction_non_alphanumeric': 0.187875751503006, 'fraction_numerical': 0.005410821643286573, 'mean_word_length': 1.4172923225962704, 'pattern_counts': {'":': 2, '<': 12, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '191554', 'n_tokens_mistral': 2540, 'n_tokens_neox': 2429, 'n_words': 882}