<commit_before>/*
 * Copyright (C) 2008 Nokia Corporation.
 * Copyright (C) 2008 <NAME> (Khattak) <<EMAIL>>.
 * Copyright (C) 2010 Collabora Ltd.
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: <NAME> (Khattak) <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *
 * This file was originally part of Rygel.
 */

using Gee;
using GLib;

extern const string G_LOG_DOMAIN;

/**
 * Responsible for backend loading.
 *
 * The BackendStore manages the set of available Folks backends. The
 * {@link BackendStore.load_backends} function loads all compatible and enabled
 * backends and the {@link BackendStore.backend_available} signal notifies when
 * these backends are ready.
 */
public class Folks.BackendStore : Object {
  [CCode (has_target = false)]
  private delegate void ModuleInitFunc (BackendStore store);
  [CCode (has_target = false)]
  private delegate void ModuleFinalizeFunc (BackendStore store);

  /* this contains all backends, regardless of enabled or prepared state */
  private HashMap<string,Backend> _backend_hash;
  /* if null, all backends are allowed */
  private SmallSet<string>? _backends_allowed;
  /* if null, no backends are disabled */
  private SmallSet<string>? _backends_disabled;
  private HashMap<string, Backend> _prepared_backends;
  private Map<string, Backend> _prepared_backends_ro;
  private File _config_file;
  private GLib.KeyFile _backends_key_file;
  private HashMap<string,unowned Module> _modules;
  private static weak BackendStore? _instance = null;
  private bool _is_prepared = false;
  private Debug _debug;

  /**
   * This keyword in the keyfile acts as a wildcard for all backends not already
   * listed in the same file.
   *
   * This is particularly useful for tests which want to ensure they're only
   * operating with backends they were designed for (and thus may not be able to
   * enumerate entries for).
   *
   * To avoid conflicts, backends must not use this as a name.
   *
   * @since 0.4.0
   */
  public static string KEY_FILE_GROUP_ALL_OTHERS = "all-others";

  /**
   * Emitted when a backend has been added to the BackendStore.
   *
   * This will not be emitted until after {@link BackendStore.load_backends}
   * has been called.
   *
   * {@link Backend}s referenced in this signal are also included in
   * {@link BackendStore.enabled_backends}.
   *
   * @param backend the new {@link Backend}
   */
  public signal void backend_available (Backend backend);

  /**
   * The list of backends visible to this store which have not been explicitly
   * disabled.
   *
   * This list will be empty before {@link BackendStore.load_backends} has been
   * called.
   *
   * The backends in this list have been prepared and are ready to use.
   *
   * @since 0.5.1
   */
  public Map<string, Backend> enabled_backends
    {
      /* Return a read-only view of the map */
      get { return this._prepared_backends_ro; }

      private set {}
    }

  /**
   * Whether {@link BackendStore.prepare} has successfully completed for this
   * store.
   *
   * @since 0.3.0
   */
  public bool is_prepared
    {
      get { return this._is_prepared; }

      private set {}
    }

  /**
   * Create a new BackendStore.
   */
  public static BackendStore dup ()
    {
      if (BackendStore._instance == null)
        {
          /* use an intermediate variable to force a strong reference */
          var new_instance = new BackendStore ();
          BackendStore._instance = new_instance;

          return new_instance;
        }

      return (!) BackendStore._instance;
    }

  private BackendStore ()
    {
      Object ();
    }

  construct
    {
      /* Treat this as a library init function */
      var debug_no_colour = Environment.get_variable ("FOLKS_DEBUG_NO_COLOUR");
      this._debug =
          Debug.dup_with_flags (Environment.get_variable ("G_MESSAGES_DEBUG"),
              (debug_no_colour == null || debug_no_colour == "0"));

      /* register the core debug messages */
      this._debug._register_domain (G_LOG_DOMAIN);

      this._debug.print_status.connect (this._debug_print_status);

      this._modules = new HashMap<string,unowned Module> ();
      this._backend_hash = new HashMap<string,Backend> ();
      this._prepared_backends = new HashMap<string,Backend> ();
      this._prepared_backends_ro = this._prepared_backends.read_only_view;
    }

  ~BackendStore ()
    {
      /* Unprepare all existing backends. */
      var iter = this._prepared_backends.map_iterator ();
      while (iter.next () == true)
        {
          var backend = iter.get_value ();
          backend.unprepare.begin ();
        }

      this._prepared_backends.clear ();

      /* Finalize all the loaded modules that have finalize functions */<commit_msg>core: Accept FOLKS_DEBUG_NO_COLOR as an alternative to the UK spelling<commit_after>/*
 * Copyright (C) 2008 Nokia Corporation.
 * Copyright (C) 2008 <NAME>) <<EMAIL>>.
 * Copyright (C) 2010 Collabora Ltd.
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: <NAME> (Khattak) <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *
 * This file was originally part of Rygel.
 */

using Gee;
using GLib;

extern const string G_LOG_DOMAIN;

/**
 * Responsible for backend loading.
 *
 * The BackendStore manages the set of available Folks backends. The
 * {@link BackendStore.load_backends} function loads all compatible and enabled
 * backends and the {@link BackendStore.backend_available} signal notifies when
 * these backends are ready.
 */
public class Folks.BackendStore : Object {
  [CCode (has_target = false)]
  private delegate void ModuleInitFunc (BackendStore store);
  [CCode (has_target = false)]
  private delegate void ModuleFinalizeFunc (BackendStore store);

  /* this contains all backends, regardless of enabled or prepared state */
  private HashMap<string,Backend> _backend_hash;
  /* if null, all backends are allowed */
  private SmallSet<string>? _backends_allowed;
  /* if null, no backends are disabled */
  private SmallSet<string>? _backends_disabled;
  private HashMap<string, Backend> _prepared_backends;
  private Map<string, Backend> _prepared_backends_ro;
  private File _config_file;
  private GLib.KeyFile _backends_key_file;
  private HashMap<string,unowned Module> _modules;
  private static weak BackendStore? _instance = null;
  private bool _is_prepared = false;
  private Debug _debug;

  /**
   * This keyword in the keyfile acts as a wildcard for all backends not already
   * listed in the same file.
   *
   * This is particularly useful for tests which want to ensure they're only
   * operating with backends they were designed for (and thus may not be able to
   * enumerate entries for).
   *
   * To avoid conflicts, backends must not use this as a name.
   *
   * @since 0.4.0
   */
  public static string KEY_FILE_GROUP_ALL_OTHERS = "all-others";

  /**
   * Emitted when a backend has been added to the BackendStore.
   *
   * This will not be emitted until after {@link BackendStore.load_backends}
   * has been called.
   *
   * {@link Backend}s referenced in this signal are also included in
   * {@link BackendStore.enabled_backends}.
   *
   * @param backend the new {@link Backend}
   */
  public signal void backend_available (Backend backend);

  /**
   * The list of backends visible to this store which have not been explicitly
   * disabled.
   *
   * This list will be empty before {@link BackendStore.load_backends} has been
   * called.
   *
   * The backends in this list have been prepared and are ready to use.
   *
   * @since 0.5.1
   */
  public Map<string, Backend> enabled_backends
    {
      /* Return a read-only view of the map */
      get { return this._prepared_backends_ro; }

      private set {}
    }

  /**
   * Whether {@link BackendStore.prepare} has successfully completed for this
   * store.
   *
   * @since 0.3.0
   */
  public bool is_prepared
    {
      get { return this._is_prepared; }

      private set {}
    }

  /**
   * Create a new BackendStore.
   */
  public static BackendStore dup ()
    {
      if (BackendStore._instance == null)
        {
          /* use an intermediate variable to force a strong reference */
          var new_instance = new BackendStore ();
          BackendStore._instance = new_instance;

          return new_instance;
        }

      return (!) BackendStore._instance;
    }

  private BackendStore ()
    {
      Object ();
    }

  construct
    {
      /* Treat this as a library init function */
      var debug_no_colour = Environment.get_variable ("FOLKS_DEBUG_NO_COLOUR");
      var debug_no_color = Environment.get_variable ("FOLKS_DEBUG_NO_COLOR");
      this._debug =
          Debug.dup_with_flags (Environment.get_variable ("G_MESSAGES_DEBUG"),
              (debug_no_colour == null || debug_no_colour == "0") &&
              (debug_no_color == null || debug_no_color == "0"));

      /* register the core debug messages */
      this._debug._register_domain (G_LOG_DOMAIN);

      this._debug.print_status.connect (this._debug_print_status);

      this._modules = new HashMap<string,unowned Module> ();
      this._backend_hash = new HashMap<string,Backend> ();
      this._prepared_backends = new HashMap<string,Backend> ();
      this._prepared_backends_ro = this._prepared_backends.read_only_view;
    }

  ~BackendStore ()
    {
      /* Unprepare all existing backends. */
      var iter = this._prepared_backends.map_iterator ();
      while (iter.next () == true)
        {
          var backend = iter.get_value ();
          backend.unprepare.begin ();
        }

      this._prepared_backends.clear ();

      /* Finalize all the loaded modules that have finalize functions */
{'fraction_non_alphanumeric': 0.0881141916003294, 'fraction_numerical': 0.004483484307804922, 'mean_word_length': 3.028750460744563, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6780718', 'n_tokens_mistral': 3186, 'n_tokens_neox': 3082, 'n_words': 1104}