<commit_before># Copyright 2016 Red Hat, Inc.
#
# 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.

"""
Wrapper for GetManagedObjects() result.
"""

import types

from ._implementation import FilesystemSpec
from ._implementation import ObjectManager
from ._implementation import PoolSpec

_SERVICE_NAME = "org.storage.stratis1"
_POOL_INTERFACE_NAME = "%s.%s" % (_SERVICE_NAME, "pool")
_FILESYSTEM_INTERFACE_NAME = "%s.%s" % (_SERVICE_NAME, "filesystem")

_POOL_INTERFACE_PROPS = frozenset(("Name", "Uuid"))

class ManagedObjects(object):
    """
    Wraps the dict returned by GetManagedObjects() method with some
    methods.
    """
    # pylint: disable=too-few-public-methods


    def __init__(self, objects): # pragma: no cover
        """
        Initializer.

        :param dict objects: the GetManagedObjects result.
        """
        self._objects = objects

    def pools(self, spec=None): # pragma: no cover
        """
        Get the subset of data corresponding to pools and matching spec.

        :param spec: a specification of properties to restrict values returned
        :type spec: dict of str * object
        :returns: a list of pairs of object path/dict for pools only
        :rtype: list of tuple of ObjectPath * dict

        A match requires a conjunction of all specified properties.
        An empty spec results in all pool objects being returned.
        """
        spec = dict() if spec is None else spec
        interface_name = _POOL_INTERFACE_NAME
        return (
           (op, data) for (op, data) in self._objects.items() \
               if interface_name in data.keys() and \
               all(data[interface_name][key] == value \
                   for (key, value) in spec.items())
        )

    def filesystems(self): # pragma: no cover
        """
        Get the subset of data corresponding to filesystems.

        :returns: a list of dictionaries for pools
        :rtype: list of tuple of ObjectPath * dict
        """
        interface_name = _FILESYSTEM_INTERFACE_NAME
        return (
           (x, y) for (x, y) in self._objects.items() \
               if interface_name in y.keys()
        )


def _gmo_builder(spec):
    """
    Returns a function that builds a method interface based on 'spec'.
    This method interface is a simple one to return the values of
    properties from a table generated by a GetManagedObjects() method call.

    :param spec: the interface specification
    :type spec: type, a subtype of InterfaceSpec<commit_msg>Dynamically create ManagedObjects class from InterfaceSpecs.<commit_after># Copyright 2016 Red Hat, Inc.
#
# 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.

"""
Wrapper for GetManagedObjects() result.
"""

import types

from ._implementation import FilesystemSpec
from ._implementation import ObjectManager
from ._implementation import PoolSpec


def _managed_objects_builder(specs):
    """
    Returns a function that builds a ManagedObjects class.
    This class encapsulates the locating of various managed objects
    according to the given specifications.

    :param specs: a list of interface specs
    :type specs: iterable of InterfaceSpec
    """

    def builder(namespace):
        """
        Adds properties to the class's namespace.

        :param namespace: the class's namespace
        """

        def build_function(spec):
            """
            Build a function for ManagedObject class that gets the appropriate
            objects matching a list of property values.
            """

            def the_func(self, props=None): # pragma: no cover
                """
                Takes a list of key/value pairs representing properties
                and locates the corresponding objects which implement
                the designated interface for the spec.

                :param props: a specification of properties to restrict values
                :type props: dict of str * object or NoneType
                :returns: a list of pairs of object path/dict for the interface
                :rtype: list of tuple of ObjectPath * dict

                The function has conjunctive semantics, i.e., the object
                must match for every item in props to be returned.
                If props is None or an empty dict all objects that implement
                the designated interface are returned.

                :raises KeyError: if any of keys is not a property name
                """
                props = dict() if props is None else props
                interface_name = spec.INTERFACE_NAME

                # pylint: disable=protected-access
                return (
                   (op, data) for (op, data) in self._objects.items() \
                       if interface_name in data.keys() and \
                       all(data[interface_name][key] == value \
                           for (key, value) in props.items())
                )

            return the_func

        for spec in specs:
            (_, _, method_prefix) = spec.INTERFACE_NAME.rpartition(".")
            method_name = method_prefix + "s"
            namespace[method_name] = build_function(spec)

        def __init__(self, objects): # pragma: no cover
            """
            The ManagedObjects initializer.

            :param objects: the result returned by GetManagedObjects() call.
            """
            # pylint: disable=protected-access
            self._objects = objects

        namespace['__init__'] = __init__

    return builder

ManagedObjects = types.new_class(
   "ManagedObjects",
   bases=(object,),
   exec_body=_managed_objects_builder([FilesystemSpec, PoolSpec])
)

def _gmo_builder(spec):
    """
    Returns a function that builds a method interface based on 'spec'.
    This method interface is a simple one to return the values of
    properties from a table generated by a GetManagedObjects() method call.

    :param spec: the interface specification
    :type spec: type, a subtype of InterfaceSpec
{'fraction_non_alphanumeric': 0.07134670487106017, 'fraction_numerical': 0.0024355300859598855, 'mean_word_length': 2.428781925343811, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '1778641', 'n_tokens_mistral': 1789, 'n_tokens_neox': 1694, 'n_words': 737}