Ejemplo n.º 1
0
def _comparator_eq(filter_value, tested_value):
    """
    Tests if the filter value is equal to the tested value
    """
    if isinstance(tested_value, ITERABLES):
        # Convert the list items to strings
        for value in tested_value:
            # Try with the string conversion
            if not is_string(value):
                value = repr(value)

            if filter_value == value:
                # Match !
                return True

    # Standard comparison
    elif not is_string(tested_value):
        # String vs string representation
        return filter_value == repr(tested_value)

    else:
        # String vs string
        return filter_value == tested_value

    return False
Ejemplo n.º 2
0
def _comparator_approximate_star(filter_value, tested_value):
    """
    Tests if the filter value, which contains a joker, is nearly equal to the
    tested value.

    If the tested value is a string or an array of string, it compares their
    lower case forms
    """
    lower_filter_value = filter_value.lower()

    if is_string(tested_value):
        # Lower case comparison
        return _comparator_star(lower_filter_value, tested_value.lower())

    elif hasattr(tested_value, "__iter__"):
        # Extract a list of strings
        new_tested = [
            value.lower() for value in tested_value if is_string(value)
        ]

        if _comparator_star(lower_filter_value, new_tested):
            # Value found in the strings
            return True

    # Compare the raw values
    return _comparator_star(filter_value, tested_value) or _comparator_star(
        lower_filter_value, tested_value
    )
Ejemplo n.º 3
0
    def __init__(self, field=None, name=None, value=None):
        """
        Sets up the property

        :param field: The property field in the class (can't be None nor empty)
        :param name: The property name (if None, this will be the field name)
        :param value: The property value
        :raise TypeError: Invalid argument type
        :raise ValueError: If the name or the name is None or empty
        """
        # Field validity test
        if not is_string(field):
            raise TypeError("Field name must be a string")

        field = field.strip()
        if not field or ' ' in field:
            raise ValueError("Empty or invalid property field name '{0}'"
                             .format(field))

        # Name validity test
        if name is not None:
            if not is_string(name):
                raise TypeError("Property name must be a string")

            name = name.strip()

        if not name:
            # No name given: use the field name
            name = field

        self.__field = field
        self.__name = name
        self.__value = value
Ejemplo n.º 4
0
def _comparator_approximate_star(filter_value, tested_value):
    """
    Tests if the filter value, which contains a joker, is nearly equal to the
    tested value.

    If the tested value is a string or an array of string, it compares their
    lower case forms
    """
    lower_filter_value = filter_value.lower()

    if is_string(tested_value):
        # Lower case comparison
        return _comparator_star(lower_filter_value, tested_value.lower())

    elif hasattr(tested_value, '__iter__'):
        # Extract a list of strings
        new_tested = [value.lower() for value in tested_value
                      if is_string(value)]

        if _comparator_star(lower_filter_value, new_tested):
            # Value found in the strings
            return True

    # Compare the raw values
    return _comparator_star(filter_value, tested_value) \
           or _comparator_star(lower_filter_value, tested_value)
Ejemplo n.º 5
0
    def instantiate(self, factory_name, name, properties=None):
        """
        Instantiates a component from the given factory, with the given name

        :param factory_name: Name of the component factory
        :param name: Name of the instance to be started
        :return: The component instance
        :raise TypeError: The given factory is unknown
        :raise ValueError: The given name or factory name is invalid, or an
                           instance with the given name already exists
        :raise Exception: Something wrong occurred in the factory
        """
        # Test parameters
        if not factory_name or not is_string(factory_name):
            raise ValueError("Invalid factory name")

        if not name or not is_string(name):
            raise ValueError("Invalid component name")

        if not self.running:
            # Stop working if the framework is stopping
            raise ValueError("Framework is stopping")

        with self.__instances_lock:
            if name in self.__instances or name in self.__waiting_handlers:
                raise ValueError(
                    "'{0}' is an already running instance name".format(name))

            with self.__factories_lock:
                # Can raise a TypeError exception
                factory, factory_context = \
                    self.__get_factory_with_context(factory_name)

            # Create component instance
            try:
                instance = factory()
            except:
                _logger.exception(
                    "Error creating the instance '%s' "
                    "from factory '%s'", name, factory_name)
                raise TypeError("Factory '{0}' failed to create '{1}'".format(
                    factory_name, name))

            # Normalize the given properties
            properties = \
                self._prepare_instance_properties(properties,
                                                  factory_context.properties)

            # Set up the component instance context
            component_context = ComponentContext(factory_context, name,
                                                 properties)

        # Try to instantiate the component immediately
        if not self.__try_instantiate(component_context, instance):
            # A handler is missing, put the component in the queue
            self.__waiting_handlers[name] = (component_context, instance)

        return instance
Ejemplo n.º 6
0
    def instantiate(self, factory_name, name, properties=None):
        """
        Instantiates a component from the given factory, with the given name

        :param factory_name: Name of the component factory
        :param name: Name of the instance to be started
        :return: The component instance
        :raise TypeError: The given factory is unknown
        :raise ValueError: The given name or factory name is invalid, or an
                           instance with the given name already exists
        :raise Exception: Something wrong occurred in the factory
        """
        # Test parameters
        if not factory_name or not is_string(factory_name):
            raise ValueError("Invalid factory name")

        if not name or not is_string(name):
            raise ValueError("Invalid component name")

        if not self.running:
            # Stop working if the framework is stopping
            raise ValueError("Framework is stopping")

        with self.__instances_lock:
            if name in self.__instances or name in self.__waiting_handlers:
                raise ValueError("'{0}' is an already running instance name"
                                 .format(name))

            with self.__factories_lock:
                # Can raise a TypeError exception
                factory, factory_context = \
                    self.__get_factory_with_context(factory_name)

            # Create component instance
            try:
                instance = factory()
            except:
                _logger.exception("Error creating the instance '%s' "
                                  "from factory '%s'", name, factory_name)
                raise TypeError("Factory '{0}' failed to create '{1}'"
                                .format(factory_name, name))

            # Normalize the given properties
            properties = \
                self._prepare_instance_properties(properties,
                                                  factory_context.properties)

            # Set up the component instance context
            component_context = ComponentContext(factory_context, name,
                                                 properties)

        # Try to instantiate the component immediately
        if not self.__try_instantiate(component_context, instance):
            # A handler is missing, put the component in the queue
            self.__waiting_handlers[name] = (component_context, instance)

        return instance
Ejemplo n.º 7
0
    def __init__(self, specification, aggregate=False, optional=False,
                 spec_filter=None):
        """
        Sets up the requirement

        :param specification: The requirement specification, which must be
                              unique and can't be None
        :param aggregate: If true, this requirement represents a list
        :param optional: If true, this requirement is optional
        :param spec_filter: A filter to select dependencies

        :raise TypeError: A parameter has an invalid type
        :raise ValueError: An error occurred while parsing the filter
        """
        if not is_string(specification):
            raise TypeError("A Requirement specification must be a string")

        if not specification:
            raise ValueError("No specification given")

        self.specification = specification
        self.aggregate = aggregate
        self.optional = optional

        # Original filter keeper
        self.__original_filter = None

        # Full filter (with the specification test)
        self.__full_filter = None

        # Set up the requirement filter (after setting up self.specification)
        self.filter = None
        self.set_filter(spec_filter)
Ejemplo n.º 8
0
def get_ldap_filter(ldap_filter):
    # type: (Any) -> Optional[Union[LDAPFilter, LDAPCriteria]]
    """
    Retrieves the LDAP filter object corresponding to the given filter.
    Parses it the argument if it is an LDAPFilter instance

    :param ldap_filter: An LDAP filter (LDAPFilter or string)
    :return: The corresponding filter, can be None
    :raise ValueError: Invalid filter string found
    :raise TypeError: Unknown filter type
    """
    if ldap_filter is None:
        return None

    if isinstance(ldap_filter, (LDAPFilter, LDAPCriteria)):
        # No conversion needed
        return ldap_filter
    elif is_string(ldap_filter):
        # Parse the filter
        return _parse_ldap(ldap_filter)

    # Unknown type
    raise TypeError(
        "Unhandled filter type {0}".format(type(ldap_filter).__name__)
    )
Ejemplo n.º 9
0
    def get_widget(self, parent):
        """
        Returns the widget to be shown in the framework information panel

        :param parent: The parent UI container
        :return: A Qt widget
        """
        # Make the table
        self._table = QtGui.QTableWidget(0, 3, parent)
        self._table.setHorizontalHeaderLabels(('ID', 'Name', 'Status'))
        self._table.verticalHeader().hide()

        # Fill it
        for bid, name in self._probe.get_bundles().items():
            # JSON-RPC converts integer keys into strings
            if is_string(bid):
                bid = int(bid)

            # Get the state
            state = self._probe.get_bundle_state(bid)

            # Append the line
            self.__append_line(bid, name, state)

        # Sort the lines
        self._table.sortItems(0)

        return self._table
Ejemplo n.º 10
0
    def _deserialize_properties(props):
        """
        Converts properties values into their type
        """
        new_props = {}
        for key, value in props.items():
            key = to_str(key)

            if is_bytes(value):
                # Convert value to string if necessary
                value = to_str(value)

            try:
                try:
                    new_props[key] = json.loads(value)
                except (TypeError, ValueError):
                    if is_string(value) and value.startswith("pelix-type:"):
                        # Pseudo-serialized
                        value_type, value = value.split(":", 3)[2:]
                        if '.' in value_type and value_type not in value:
                            # Not a builtin type...
                            _logger.warning("Won't work: %s (%s)", value,
                                            value_type)

                        new_props[key] = eval(value)
                    else:
                        # String
                        new_props[key] = value
            except Exception as ex:
                _logger.error("Can't deserialize %s: %s", value, ex)

        return new_props
Ejemplo n.º 11
0
    def __init__(self, specifications, controller=None):
        """
        Sets up a provided service.
        A service controller can be defined to enable or disable the service.

        :param specifications: A list of provided interface(s) name(s)
                               (can't be empty)
        :param controller: Name of the service controller class field
                           (optional)
        :raise ValueError: If the specifications are invalid
        """
        if controller is not None:
            if not is_string(controller):
                raise ValueError("Controller name must be a string")

            controller = controller.strip()
            if not controller:
                # Empty controller name
                _logger.warning("Empty controller name given")
                controller = None

            elif ' ' in controller:
                raise ValueError("Controller name contains spaces")

        self.__specifications = _get_specifications(specifications)
        self.__controller = controller
Ejemplo n.º 12
0
    def _register_factory(self, factory_name, factory, override):
        # type: (str, type, bool) -> None
        """
        Registers a component factory

        :param factory_name: The name of the factory
        :param factory: The factory class object
        :param override: If true, previous factory is overridden, else an
                         exception is risen if a previous factory with that
                         name already exists
        :raise ValueError: The factory name already exists or is invalid
        :raise TypeError: Invalid factory type
        """
        if not factory_name or not is_string(factory_name):
            raise ValueError("A factory name must be a non-empty string")

        if not inspect.isclass(factory):
            raise TypeError("Invalid factory class '{0}'".format(
                type(factory).__name__))

        with self.__factories_lock:
            if factory_name in self.__factories:
                if override:
                    _logger.info("Overriding factory '%s'", factory_name)
                else:
                    raise ValueError(
                        "'{0}' factory already exist".format(factory_name))

            self.__factories[factory_name] = factory

            # Trigger an event
            self._fire_ipopo_event(constants.IPopoEvent.REGISTERED,
                                   factory_name)
Ejemplo n.º 13
0
    def __init__(self, uid, framework, configurations, name, specifications,
                 properties):
        # type: (str, str, Any[str, List[str]], Optional[str], List[str], dict) -> None
        """
        :param uid: Unique identified of the end point
        :param framework: UID of the framework exporting the end point
                          (can be None)
        :param configurations: Kinds of end point (xmlrpc, ...)
        :param name: Name of the end point
        :param specifications: Specifications of the exported service
        :param properties: Properties of the service
        """
        self.__uid = uid
        self.__fw_uid = framework or None
        self.__name = name
        self.__properties = properties.copy() if properties else {}

        # Normalize list of configurations
        if is_string(configurations):
            tuple_conf = (configurations,)  # type: Tuple[str, ...]
        else:
            tuple_conf = tuple(configurations)

        self.__configurations = tuple_conf

        # Extract the language prefix in specifications
        self.__specifications = extract_specifications(
            specifications, self.__properties)

        # Public variable: the source server,
        # set up by a Pelix discovery service
        self.server = None  # type: str
Ejemplo n.º 14
0
    def _register_factory(self, factory_name, factory, override):
        """
        Registers a component factory

        :param factory_name: The name of the factory
        :param factory: The factory class object
        :param override: If true, previous factory is overridden, else an
                         exception is risen if a previous factory with that
                         name already exists
        :raise ValueError: The factory name already exists or is invalid
        :raise TypeError: Invalid factory type
        """
        if not factory_name or not is_string(factory_name):
            raise ValueError("A factory name must be a non-empty string")

        if not inspect.isclass(factory):
            raise TypeError("Invalid factory class '{0}'"
                            .format(type(factory).__name__))

        with self.__factories_lock:
            if factory_name in self.__factories:
                if override:
                    _logger.info("Overriding factory '%s'", factory_name)

                else:
                    raise ValueError("'{0}' factory already exist"
                                     .format(factory_name))

            self.__factories[factory_name] = factory

            # Trigger an event
            self._fire_ipopo_event(constants.IPopoEvent.REGISTERED,
                                   factory_name)
Ejemplo n.º 15
0
    def set_filter(self, props_filter):
        """
        Changes the current filter for the given one

        :param props_filter: The new requirement filter on service properties
        :raise TypeError: Unknown filter type
        """
        if props_filter is not None and \
                not (is_string(props_filter) or
                     isinstance(props_filter, (ldapfilter.LDAPFilter,
                                               ldapfilter.LDAPCriteria))):
            # Unknown type
            raise TypeError("Invalid filter type {0}"
                            .format(type(props_filter).__name__))

        if props_filter is not None:
            # Filter given, keep its string form
            self.__original_filter = str(props_filter)
        else:
            # No filter
            self.__original_filter = None

        # Parse the filter
        self.filter = ldapfilter.get_ldap_filter(props_filter)

        # Prepare the full filter
        spec_filter = "({0}={1})".format(OBJECTCLASS, self.specification)
        self.__full_filter = ldapfilter.combine_filters(
            (spec_filter, self.filter))
Ejemplo n.º 16
0
    def _serialize_properties(self, props):
        """
        Converts properties values into strings
        """
        new_props = {}

        for key, value in props.items():
            if is_string(value):
                new_props[key] = value

            else:
                try:
                    new_props[key] = json.dumps(value)

                except ValueError:
                    new_props[key] = "pelix-type:{0}:{1}" \
                                     .format(type(value).__name__, repr(value))

        # FIXME: for use with ECF
        try:
            new_props[pelix.constants.OBJECTCLASS] = props[pelix.constants.OBJECTCLASS][0]
            new_props[pelix.remote.PROP_IMPORTED_CONFIGS] = props[pelix.remote.PROP_IMPORTED_CONFIGS][0]
        except KeyError:
            pass

        return new_props
Ejemplo n.º 17
0
    def set_filter(self, props_filter):
        """
        Changes the current filter for the given one

        :param props_filter: The new requirement filter on service properties
        :raise TypeError: Unknown filter type
        """
        if props_filter is not None and \
                not (is_string(props_filter) or
                     isinstance(props_filter, (ldapfilter.LDAPFilter,
                                               ldapfilter.LDAPCriteria))):
            # Unknown type
            raise TypeError("Invalid filter type {0}"
                            .format(type(props_filter).__name__))

        if props_filter is not None:
            # Filter given, keep its string form
            self.__original_filter = str(props_filter)
        else:
            # No filter
            self.__original_filter = None

        # Parse the filter
        self.filter = ldapfilter.get_ldap_filter(props_filter)

        # Prepare the full filter
        spec_filter = "({0}={1})".format(OBJECTCLASS, self.specification)
        self.__full_filter = ldapfilter.combine_filters((spec_filter,
                                                         self.filter))
Ejemplo n.º 18
0
def unescape_LDAP(ldap_string):
    """
    Unespaces an LDAP string

    :param ldap_string: The string to unescape
    :return: The unprotected string
    """
    if ldap_string is None:
        return None

    assert is_string(ldap_string)

    if ESCAPE_CHARACTER not in ldap_string:
        # No need to loop
        return ldap_string

    escaped = False
    result = ""

    for character in ldap_string:
        if not escaped and character == ESCAPE_CHARACTER:
            # Escape character found
            escaped = True

        else:
            # Copy the character
            escaped = False
            result += character

    return result
Ejemplo n.º 19
0
def _get_specifications(specifications):
    """
    Computes the list of strings corresponding to the given specifications

    :param specifications: A string, a class or a list of specifications
    :return: A list of strings
    :raise ValueError: Invalid specification found
    """
    if not specifications:
        raise ValueError("No specifications given")

    if inspect.isclass(specifications):
        # Get the name of the class
        return [specifications.__name__]

    elif is_string(specifications):
        # Specification name
        specifications = specifications.strip()
        if not specifications:
            raise ValueError("Empty specification given")

        return [specifications]

    elif isinstance(specifications, (list, tuple)):
        # List given: normalize its content
        results = []
        for specification in specifications:
            results.extend(_get_specifications(specification))

        return results

    else:
        raise ValueError("Unhandled specifications type : {0}".format(
            type(specifications).__name__))
Ejemplo n.º 20
0
    def __make_local_peer(self, context):
        """
        Prepares a Peer bean with local configuration

        :param context: Bundle context
        """
        # Get local peer UID, node UID and application ID
        peer_uid = context.get_property(herald.FWPROP_PEER_UID) \
            or context.get_property(pelix.constants.FRAMEWORK_UID)
        node_uid = context.get_property(herald.FWPROP_NODE_UID)
        app_id = context.get_property(herald.FWPROP_APPLICATION_ID) \
            or herald.DEFAULT_APPLICATION_ID

        # Find configured groups
        groups = context.get_property(herald.FWPROP_PEER_GROUPS)
        if not groups:
            groups = []
        elif is_string(groups):
            groups = (group.strip() for group in groups.split(',')
                      if group.strip)
        groups = set(groups)

        # Add pre-configured group: node UID
        if node_uid:
            groups.add(node_uid)

        # Make the Peer bean
        peer = beans.Peer(peer_uid, node_uid, app_id, groups, self)

        # Setup node and name information
        peer.name = context.get_property(herald.FWPROP_PEER_NAME)
        peer.node_name = context.get_property(herald.FWPROP_NODE_NAME)
        return peer
Ejemplo n.º 21
0
    def __init__(self, specifications, controller=None):
        """
        Sets up a provided service.
        A service controller can be defined to enable or disable the service.

        :param specifications: A list of provided interface(s) name(s)
                               (can't be empty)
        :param controller: Name of the service controller class field
                           (optional)
        :raise ValueError: If the specifications are invalid
        """
        if controller is not None:
            if not is_string(controller):
                raise ValueError("Controller name must be a string")

            controller = controller.strip()
            if not controller:
                # Empty controller name
                _logger.warning("Empty controller name given")
                controller = None

            elif ' ' in controller:
                raise ValueError("Controller name contains spaces")

        self.__specifications = _get_specifications(specifications)
        self.__controller = controller
Ejemplo n.º 22
0
def _comparator_gt(filter_value, tested_value):
    """
    Tests if the filter value is strictly lesser than the tested value

    tested_value > filter_value
    """
    if is_string(filter_value):
        value_type = type(tested_value)
        try:
            # Try a conversion
            filter_value = value_type(filter_value)

        except (TypeError, ValueError):
            if value_type is int:
                # Integer/float comparison trick
                try:
                    filter_value = float(filter_value)
                except (TypeError, ValueError):
                    # None-float value
                    return False
            else:
                # Incompatible type
                return False
    try:
        return tested_value > filter_value
    except TypeError:
        # Incompatible type
        return False
Ejemplo n.º 23
0
    def _deserialize_properties(props):
        """
        Converts properties values into their type
        """
        new_props = {}
        for key, value in props.items():
            key = to_str(key)

            if is_bytes(value):
                # Convert value to string if necessary
                value = to_str(value)

            try:
                try:
                    new_props[key] = json.loads(value)
                except (TypeError, ValueError):
                    if is_string(value) and value.startswith("pelix-type:"):
                        # Pseudo-serialized
                        value_type, value = value.split(":", 3)[2:]
                        if "." in value_type and value_type not in value:
                            # Not a builtin type...
                            _logger.warning(
                                "Won't work: %s (%s)", value, value_type
                            )

                        new_props[key] = eval(value)
                    else:
                        # String
                        new_props[key] = value
            except Exception as ex:
                _logger.error("Can't deserialize %s: %s", value, ex)

        return new_props
Ejemplo n.º 24
0
    def get_widget(self, parent):
        """
        Returns the widget to be shown in the framework information panel

        :param parent: The parent UI container
        :return: A Qt widget
        """
        # Make the table
        self._table = QtWidgets.QTableWidget(0, 3, parent)
        self._table.setHorizontalHeaderLabels(('ID', 'Name', 'Status'))
        self._table.verticalHeader().hide()

        # Fill it
        for bid, name in self._probe.get_bundles().items():
            # JSON-RPC converts integer keys into strings
            if is_string(bid):
                bid = int(bid)

            # Get the state
            state = self._probe.get_bundle_state(bid)

            # Append the line
            self.__append_line(bid, name, state)

        # Sort the lines
        self._table.sortItems(0)

        return self._table
Ejemplo n.º 25
0
    def __init__(
        self, uid, framework, configurations, name, specifications, properties
    ):
        # type: (str, str, Any[str, List[str]], Optional[str], List[str], dict) -> None
        """
        :param uid: Unique identified of the end point
        :param framework: UID of the framework exporting the end point
                          (can be None)
        :param configurations: Kinds of end point (xmlrpc, ...)
        :param name: Name of the end point
        :param specifications: Specifications of the exported service
        :param properties: Properties of the service
        """
        self.__uid = uid
        self.__fw_uid = framework or None
        self.__name = name
        self.__properties = properties.copy() if properties else {}

        # Normalize list of configurations
        if is_string(configurations):
            tuple_conf = (configurations,)  # type: Tuple[str, ...]
        else:
            tuple_conf = tuple(configurations)

        self.__configurations = tuple_conf

        # Extract the language prefix in specifications
        self.__specifications = extract_specifications(
            specifications, self.__properties
        )

        # Public variable: the source server,
        # set up by a Pelix discovery service
        self.server = None  # type: str
Ejemplo n.º 26
0
def escape_LDAP(ldap_string):
    """
    Escape a string to let it go in an LDAP filter

    :param ldap_string: The string to escape
    :return: The protected string
    """
    if ldap_string is None:
        return None

    assert is_string(ldap_string)

    if len(ldap_string) == 0:
        # No content
        return ldap_string

    # Protect escape character previously in the string
    ldap_string = ldap_string.replace(ESCAPE_CHARACTER,
                                      ESCAPE_CHARACTER + ESCAPE_CHARACTER)

    # Leading space
    if ldap_string.startswith(" "):
        ldap_string = "\\ {0}".format(ldap_string[1:])

    # Trailing space
    if ldap_string.endswith(" "):
        ldap_string = "{0}\\ ".format(ldap_string[:-1])

    # Escape other characters
    for escaped in ESCAPED_CHARACTERS:
        ldap_string = ldap_string.replace(escaped, ESCAPE_CHARACTER + escaped)

    return ldap_string
Ejemplo n.º 27
0
    def find_service_references(self,
                                clazz=None,
                                ldap_filter=None,
                                only_one=False):
        """
        Finds all services references matching the given filter.

        :param clazz: Class implemented by the service
        :param ldap_filter: Service filter
        :param only_one: Return the first matching service reference only
        :return: A list of found references, or None
        :raise BundleException: An error occurred looking for service
                                references
        """
        with self.__svc_lock:
            if clazz is None and ldap_filter is None:
                # Return a sorted copy of the keys list
                # Do not return None, as the whole content was required
                return sorted(self.__svc_registry.keys())

            if hasattr(clazz, '__name__'):
                # Escape the type name
                clazz = ldapfilter.escape_LDAP(clazz.__name__)
            elif is_string(clazz):
                # Escape the class name
                clazz = ldapfilter.escape_LDAP(clazz)

            if clazz is None:
                # Directly use the given filter
                refs_set = sorted(self.__svc_registry.keys())
            else:
                try:
                    # Only for references with the given specification
                    refs_set = iter(self.__svc_specs[clazz])
                except KeyError:
                    # No matching specification
                    return None

            # Parse the filter
            try:
                new_filter = ldapfilter.get_ldap_filter(ldap_filter)
            except ValueError as ex:
                raise BundleException(ex)

            if new_filter is not None:
                # Prepare a generator, as we might not need a complete
                # walk-through
                refs_set = (ref for ref in refs_set
                            if new_filter.matches(ref.get_properties()))

            if only_one:
                # Return the first element in the list/generator
                try:
                    return next(refs_set)
                except StopIteration:
                    # No match
                    return None

            # Get all the matching references
            return list(refs_set) or None
Ejemplo n.º 28
0
def escape_LDAP(ldap_string):
    """
    Escape a string to let it go in an LDAP filter

    :param ldap_string: The string to escape
    :return: The protected string
    """
    if ldap_string is None:
        return None

    assert is_string(ldap_string)

    if len(ldap_string) == 0:
        # No content
        return ldap_string

    # Protect escape character previously in the string
    ldap_string = ldap_string.replace(ESCAPE_CHARACTER,
                                      ESCAPE_CHARACTER + ESCAPE_CHARACTER)

    # Leading space
    if ldap_string.startswith(" "):
        ldap_string = "\\ {0}".format(ldap_string[1:])

    # Trailing space
    if ldap_string.endswith(" "):
        ldap_string = "{0}\\ ".format(ldap_string[:-1])

    # Escape other characters
    for escaped in ESCAPED_CHARACTERS:
        ldap_string = ldap_string.replace(escaped, ESCAPE_CHARACTER + escaped)

    return ldap_string
Ejemplo n.º 29
0
    def __make_local_peer(self, context):
        """
        Prepares a Peer bean with local configuration

        :param context: Bundle context
        """
        # Get local peer UID, node UID and application ID
        peer_uid = context.get_property(herald.FWPROP_PEER_UID) \
            or context.get_property(pelix.constants.FRAMEWORK_UID)
        node_uid = context.get_property(herald.FWPROP_NODE_UID)
        app_id = context.get_property(herald.FWPROP_APPLICATION_ID) \
            or herald.DEFAULT_APPLICATION_ID

        # Find configured groups
        groups = context.get_property(herald.FWPROP_PEER_GROUPS)
        if not groups:
            groups = []
        elif is_string(groups):
            groups = (group.strip() for group in groups.split(',')
                      if group.strip)
        groups = set(groups)

        # Add pre-configured group: node UID
        if node_uid:
            groups.add(node_uid)

        # Make the Peer bean
        peer = beans.Peer(peer_uid, node_uid, app_id, groups, self)

        # Setup node and name information
        peer.name = context.get_property(herald.FWPROP_PEER_NAME)
        peer.node_name = context.get_property(herald.FWPROP_NODE_NAME)
        return peer
Ejemplo n.º 30
0
    def __init__(self, uid, framework, configurations, name, specifications,
                 properties):
        """
        Sets up the members

        :param uid: Unique identified of the end point
        :param framework: UID of the framework exporting the end point
                          (can be None)
        :param configurations: Kinds of end point (xmlrpc, ...)
        :param name: Name of the end point
        :param specifications: Specifications of the exported service
        :param properties: Properties of the service
        """
        self.__uid = uid
        self.__fw_uid = framework or None
        self.__name = name
        self.__properties = properties.copy() if properties else {}

        # Normalize list of configurations
        if is_string(configurations):
            self.__configurations = (configurations, )
        else:
            self.__configurations = tuple(configurations)

        # Extract the language prefix in specifications
        self.__specifications = extract_specifications(specifications,
                                                       self.__properties)

        # Public variable: the source server,
        # set up by a Pelix discovery service
        self.server = None
Ejemplo n.º 31
0
def _comparator_gt(filter_value, tested_value):
    """
    Tests if the filter value is strictly lesser than the tested value

    tested_value > filter_value
    """
    if is_string(filter_value):
        value_type = type(tested_value)
        try:
            # Try a conversion
            filter_value = value_type(filter_value)

        except (TypeError, ValueError):
            if value_type is int:
                # Integer/float comparison trick
                try:
                    filter_value = float(filter_value)
                except (TypeError, ValueError):
                    # None-float value
                    return False
            else:
                # Incompatible type
                return False
    try:
        return tested_value > filter_value
    except TypeError:
        # Incompatible type
        return False
Ejemplo n.º 32
0
    def _serialize_properties(self, props):
        """
        Converts properties values into strings
        """
        new_props = {}

        for key, value in props.items():
            if is_string(value):
                new_props[key] = value
            else:
                try:
                    new_props[key] = json.dumps(value)
                except ValueError:
                    new_props[key] = "pelix-type:{0}:{1}" \
                                     .format(type(value).__name__, repr(value))

        # FIXME: to simplify the usage with ECF, send single strings instead of
        # arrays
        for key in (pelix.constants.OBJECTCLASS,
                    pelix.remote.PROP_IMPORTED_CONFIGS):
            try:
                new_props[key] = props[key][0]
            except KeyError:
                pass

        return new_props
Ejemplo n.º 33
0
    def __init__(self, field, specification, aggregate=False, optional=False,
                 spec_filter=None):
        """
        Sets up the requirement

        :param field: The injected field
        :param specification: The injected service specification
        :param aggregate: If true, injects a list
        :param optional: If true, this injection is optional
        :param spec_filter: An LDAP query to filter injected services upon
                            their properties
        :raise TypeError: A parameter has an invalid type
        :raise ValueError: An error occurred while parsing the filter or an
                           argument is incorrect
        """
        if not field:
            raise ValueError("Empty field name.")

        if not is_string(field):
            raise TypeError("The field name must be a string, not {0}"
                            .format(type(field).__name__))

        if ' ' in field:
            raise ValueError("Field name can't contain spaces.")

        self.__field = field

        # Be sure that there is only one required specification
        specifications = _get_specifications(specification)
        self.__multi_specs = len(specifications) > 1

        # Construct the requirement object
        self.__requirement = Requirement(specifications[0],
                                         aggregate, optional, spec_filter)
Ejemplo n.º 34
0
    def _serialize_properties(props):
        """
        Converts properties values into strings
        """
        new_props = {}

        for key, value in props.items():
            if is_string(value):
                new_props[key] = value
            else:
                try:
                    new_props[key] = json.dumps(value)
                except ValueError:
                    new_props[key] = "pelix-type:{0}:{1}" \
                                     .format(type(value).__name__, repr(value))

        # FIXME: to simplify the usage with ECF, send single strings instead of
        # arrays
        for key in (pelix.constants.OBJECTCLASS,
                    pelix.remote.PROP_IMPORTED_CONFIGS):
            try:
                new_props[key] = props[key][0]
            except KeyError:
                pass

        return new_props
Ejemplo n.º 35
0
def _get_specifications(specifications):
    """
    Computes the list of strings corresponding to the given specifications

    :param specifications: A string, a class or a list of specifications
    :return: A list of strings
    :raise ValueError: Invalid specification found
    """
    if not specifications:
        raise ValueError("No specifications given")

    if inspect.isclass(specifications):
        # Get the name of the class
        return [specifications.__name__]

    elif is_string(specifications):
        # Specification name
        specifications = specifications.strip()
        if not specifications:
            raise ValueError("Empty specification given")

        return [specifications]

    elif isinstance(specifications, (list, tuple)):
        # List given: normalize its content
        results = []
        for specification in specifications:
            results.extend(_get_specifications(specification))

        return results

    else:
        raise ValueError("Unhandled specifications type : {0}"
                         .format(type(specifications).__name__))
Ejemplo n.º 36
0
    def __init__(self, uid, framework, configurations, name, specifications,
                 properties):
        """
        Sets up the members

        :param uid: Unique identified of the end point
        :param framework: UID of the framework exporting the end point
                          (can be None)
        :param configurations: Kinds of end point (xmlrpc, ...)
        :param name: Name of the end point
        :param specifications: Specifications of the exported service
        :param properties: Properties of the service
        """
        self.__uid = uid
        self.__fw_uid = framework or None
        self.__name = name
        self.__properties = properties.copy() if properties else {}

        # Normalize list of configurations
        if is_string(configurations):
            self.__configurations = (configurations,)
        else:
            self.__configurations = tuple(configurations)

        # Extract the language prefix in specifications
        self.__specifications = extract_specifications(specifications,
                                                       self.__properties)

        # Public variable: the source server,
        # set up by a Pelix discovery service
        self.server = None
Ejemplo n.º 37
0
    def find_service_references(self, clazz=None, ldap_filter=None,
                                only_one=False):
        """
        Finds all services references matching the given filter.

        :param clazz: Class implemented by the service
        :param ldap_filter: Service filter
        :param only_one: Return the first matching service reference only
        :return: A list of found references, or None
        :raise BundleException: An error occurred looking for service
                                references
        """
        with self.__svc_lock:
            if clazz is None and ldap_filter is None:
                # Return a sorted copy of the keys list
                # Do not return None, as the whole content was required
                return sorted(self.__svc_registry.keys())

            if hasattr(clazz, '__name__'):
                # Escape the type name
                clazz = ldapfilter.escape_LDAP(clazz.__name__)
            elif is_string(clazz):
                # Escape the class name
                clazz = ldapfilter.escape_LDAP(clazz)

            if clazz is None:
                # Directly use the given filter
                refs_set = sorted(self.__svc_registry.keys())
            else:
                try:
                    # Only for references with the given specification
                    refs_set = iter(self.__svc_specs[clazz])
                except KeyError:
                    # No matching specification
                    return None

            # Parse the filter
            try:
                new_filter = ldapfilter.get_ldap_filter(ldap_filter)
            except ValueError as ex:
                raise BundleException(ex)

            if new_filter is not None:
                # Prepare a generator, as we might not need a complete
                # walk-through
                refs_set = (ref for ref in refs_set
                            if new_filter.matches(ref.get_properties()))

            if only_one:
                # Return the first element in the list/generator
                try:
                    return next(refs_set)
                except StopIteration:
                    # No match
                    return None

            # Get all the matching references
            return list(refs_set) or None
Ejemplo n.º 38
0
    def unregister_factory(self, factory_name):
        # type: (str) -> bool
        """
        Unregisters the given component factory

        :param factory_name: Name of the factory to unregister
        :return: True the factory has been removed, False if the factory is
                 unknown
        """
        if not factory_name or not is_string(factory_name):
            # Invalid name
            return False

        with self.__factories_lock:
            try:
                # Remove the factory from the registry
                factory_class = self.__factories.pop(factory_name)
            except KeyError:
                # Unknown factory
                return False

            # Trigger an event
            self._fire_ipopo_event(
                constants.IPopoEvent.UNREGISTERED, factory_name
            )

            # Invalidate and delete all components of this factory
            with self.__instances_lock:
                # Compute the list of __instances to remove
                to_remove = self.__get_stored_instances(factory_name)

                # Remove instances from the registry: avoids dependencies \
                # update to link against a component from this factory again.
                for instance in to_remove:
                    try:
                        # Kill the instance
                        self.kill(instance.name)
                    except ValueError:
                        # Unknown instance: already killed by the invalidation
                        # callback of a component killed in this loop
                        # => ignore
                        pass

                # Remove waiting component
                names = [
                    name
                    for name, (context, _) in self.__waiting_handlers.items()
                    if context.factory_context.name == factory_name
                ]
                for name in names:
                    del self.__waiting_handlers[name]

            # Clear the bundle context of the factory
            _set_factory_context(factory_class, None)

        return True
Ejemplo n.º 39
0
    def unregister_factory(self, factory_name):
        # type: (str) -> bool
        """
        Unregisters the given component factory

        :param factory_name: Name of the factory to unregister
        :return: True the factory has been removed, False if the factory is
                 unknown
        """
        if not factory_name or not is_string(factory_name):
            # Invalid name
            return False

        with self.__factories_lock:
            try:
                # Remove the factory from the registry
                factory_class = self.__factories.pop(factory_name)
            except KeyError:
                # Unknown factory
                return False

            # Trigger an event
            self._fire_ipopo_event(constants.IPopoEvent.UNREGISTERED,
                                   factory_name)

            # Invalidate and delete all components of this factory
            with self.__instances_lock:
                # Compute the list of __instances to remove
                to_remove = self.__get_stored_instances(factory_name)

                # Remove instances from the registry: avoids dependencies \
                # update to link against a component from this factory again.
                for instance in to_remove:
                    try:
                        # Kill the instance
                        self.kill(instance.name)
                    except ValueError:
                        # Unknown instance: already killed by the invalidation
                        # callback of a component killed in this loop
                        # => ignore
                        pass

                # Remove waiting component
                names = [
                    name
                    for name, (context, _) in self.__waiting_handlers.items()
                    if context.factory_context.name == factory_name
                ]
                for name in names:
                    del self.__waiting_handlers[name]

            # Clear the bundle context of the factory
            _set_factory_context(factory_class, None)

        return True
Ejemplo n.º 40
0
    def testIsString(self):
        """
        Tests the is_string() method
        """
        valid = ["", "aaa", str(42)]
        invalid = [42, None, [], {}, tuple()]

        if sys.version_info[0] >= 3:
            invalid.extend((b"", b"aaa"))

        else:
            valid.extend((unicode(""), unicode("aaa"), unicode(42)))
            invalid.extend((42, None, [], {}))

        for value in valid:
            self.assertTrue(utilities.is_string(value),
                            "'{0}' is a string".format(value))

        for value in invalid:
            self.assertFalse(utilities.is_string(value),
                             "'{0}' is not a string".format(value))
Ejemplo n.º 41
0
    def testIsString(self):
        """
        Tests the is_string() method
        """
        valid = ["", "aaa", str(42)]
        invalid = [42, None, [], {}, tuple()]

        if sys.version_info[0] >= 3:
            # Python 3: test bytes
            invalid.extend((b"", b"aaa"))
        else:
            # Python 2: test unicode
            valid.extend((unicode(""), unicode("aaa"), unicode(42)))

        for value in valid:
            self.assertTrue(utilities.is_string(value),
                            "'{0}' is a string".format(value))

        for value in invalid:
            self.assertFalse(utilities.is_string(value),
                             "'{0}' is not a string".format(value))
Ejemplo n.º 42
0
    def matches(self, other):
        """
        Tests if this version matches the given one
        """
        if other is None:
            # None matches everything
            return True

        if self.version is None:
            # No version matches any version
            return True

        if is_string(other):
            # The given string can be either a version or a range
            other = other.strip()
            if other[0] == '[':
                # Range comparison
                inclusive = (other[-1] == ']')
                versions = other[1:-1].split(',')

                # Convert boundaries
                minimum = Version(versions[0])
                maximum = Version(versions[1])
            else:
                minimum = Version(other)
                # Allow binding up to the next major version (excluded)
                maximum = Version(other) + (1,)
                inclusive = False

        if isinstance(other, Version):
            # Compared to another version
            if other.version is None:
                # Other matches any version
                return True
            else:
                # Allow binding up to the next major version (excluded)
                minimum = other
                maximum = other + (1,)
                inclusive = False

        if minimum is not None and self < minimum:
            # We're under the minimal version
            return False
        elif maximum is not None and self > maximum:
            # We're above the maximal version
            return False
        elif not inclusive and self == maximum:
            # We're at the upper boundary
            return False
        else:
            # Range tests passed
            return True
Ejemplo n.º 43
0
    def matches(self, other):
        """
        Tests if this version matches the given one
        """
        if other is None:
            # None matches everything
            return True

        if self.version is None:
            # No version matches any version
            return True

        if is_string(other):
            # The given string can be either a version or a range
            other = other.strip()
            if other[0] == '[':
                # Range comparison
                inclusive = (other[-1] == ']')
                versions = other[1:-1].split(',')

                # Convert boundaries
                minimum = Version(versions[0])
                maximum = Version(versions[1])
            else:
                minimum = Version(other)
                # Allow binding up to the next major version (excluded)
                maximum = Version(other) + (1, )
                inclusive = False

        if isinstance(other, Version):
            # Compared to another version
            if other.version is None:
                # Other matches any version
                return True
            else:
                # Allow binding up to the next major version (excluded)
                minimum = other
                maximum = other + (1, )
                inclusive = False

        if minimum is not None and self < minimum:
            # We're under the minimal version
            return False
        elif maximum is not None and self > maximum:
            # We're above the maximal version
            return False
        elif not inclusive and self == maximum:
            # We're at the upper boundary
            return False
        else:
            # Range tests passed
            return True
Ejemplo n.º 44
0
 def visit_Assign(self, node):
     """
     Found an assignment
     """
     field = getattr(node.targets[0], 'id', None)
     if field:
         try:
             value = ast.literal_eval(node.value)
             if is_string(value):
                 self.values[field] = value
         except (ValueError, SyntaxError):
             # Ignore errors
             pass
Ejemplo n.º 45
0
 def visit_Assign(self, node):
     """
     Found an assignment
     """
     field = getattr(node.targets[0], 'id', None)
     if field:
         try:
             value = ast.literal_eval(node.value)
             if is_string(value):
                 self.values[field] = value
         except (ValueError, SyntaxError):
             # Ignore errors
             pass
Ejemplo n.º 46
0
    def __init__(self,
                 field,
                 specification,
                 key,
                 allow_none=False,
                 aggregate=False,
                 optional=False,
                 spec_filter=None):
        """
        Sets up the requirement

        :param field: The injected field
        :param specification: The injected service specification
        :param key: Name of the service property to use as a dictionary key
        :param allow_none: If True, inject services with a None property value
        :param aggregate: If true, injects a list
        :param optional: If true, this injection is optional
        :param spec_filter: An LDAP query to filter injected services upon
                            their properties
        :raise TypeError: A parameter has an invalid type
        :raise ValueError: An error occurred while parsing the filter or an
                           argument is incorrect
        """
        # Check if field is valid
        if not field:
            raise ValueError("Empty field name.")

        if not is_string(field):
            raise TypeError("The field name must be a string, not {0}".format(
                type(field).__name__))

        if ' ' in field:
            raise ValueError("Field name can't contain spaces.")

        self.__field = field

        # Be sure that there is only one required specification
        specifications = _get_specifications(specification)
        self.__multi_specs = len(specifications) > 1

        # Check if key is valid
        if not key:
            raise ValueError("No property key given")

        # Store the flags
        self.__key = key
        self.__allow_none = allow_none

        # Construct the requirement object
        self.__requirement = Requirement(specifications[0], aggregate,
                                         optional, spec_filter)
Ejemplo n.º 47
0
    def __init__(
        self, uid, fw_uid, configurations, name, svc_ref, service, properties
    ):
        # type: (str, str, Any[str, List[str]], str, pelix.framework.ServiceReference, object, dict) -> None
        """
        :param uid: Unique identified of the end point
        :param fw_uid: The framework UID
        :param configurations: Kinds of end point (xmlrpc, ...)
        :param name: Name of the end point
        :param svc_ref: ServiceReference of the exported service
        :param service: Instance of the exported service
        :param properties: Extra properties
        :raise ValueError: Invalid UID or the end point exports nothing
                           (all specifications have been filtered)
        """
        if not uid:
            raise ValueError("Invalid UID")

        # Given information
        self.__uid = uid
        self.__fw_uid = fw_uid
        self.__instance = service
        self.__reference = svc_ref
        self.__configurations = configurations
        self.__name = name

        # Normalize extra properties
        if isinstance(properties, dict):
            self.__properties = properties
        else:
            self.__properties = {}

        # Normalize the list of configurations
        if is_string(configurations):
            self.__configurations = (configurations,)
        else:
            self.__configurations = tuple(configurations)

        # Exported specifications
        self.__exported_specs = []  # type: List[str]
        exported_specs = compute_exported_specifications(svc_ref)
        if exported_specs:
            # Transform the specifications for export (add the language prefix)
            self.__exported_specs = format_specifications(exported_specs)
        else:
            raise ValueError(
                "Endpoint {0}, {1}, exports nothing".format(
                    self.__uid, self.__name
                )
            )
Ejemplo n.º 48
0
def _comparator_eq(filter_value, tested_value):
    """
    Tests if the filter value is equal to the tested value
    """
    if isinstance(tested_value, ITERABLES):
        # Convert the list items to strings
        for value in tested_value:
            # Try with the string conversion
            if not is_string(value):
                value = repr(value)

            if filter_value == value:
                # Match !
                return True
    # Standard comparison
    elif not is_string(tested_value):
        # String vs string representation
        return filter_value == repr(tested_value)
    else:
        # String vs string
        return filter_value == tested_value

    return False
Ejemplo n.º 49
0
    def __init__(
        self, uid, fw_uid, configurations, name, svc_ref, service, properties
    ):
        # type: (str, str, Any[str, List[str]], str, pelix.framework.ServiceReference, object, dict) -> None
        """
        :param uid: Unique identified of the end point
        :param fw_uid: The framework UID
        :param configurations: Kinds of end point (xmlrpc, ...)
        :param name: Name of the end point
        :param svc_ref: ServiceReference of the exported service
        :param service: Instance of the exported service
        :param properties: Extra properties
        :raise ValueError: Invalid UID or the end point exports nothing
                           (all specifications have been filtered)
        """
        if not uid:
            raise ValueError("Invalid UID")

        # Given information
        self.__uid = uid
        self.__fw_uid = fw_uid
        self.__instance = service
        self.__reference = svc_ref
        self.__configurations = configurations
        self.__name = name

        # Normalize extra properties
        if isinstance(properties, dict):
            self.__properties = properties
        else:
            self.__properties = {}

        # Normalize the list of configurations
        if is_string(configurations):
            self.__configurations = (configurations,)
        else:
            self.__configurations = tuple(configurations)

        # Exported specifications
        self.__exported_specs = []  # type: List[str]
        exported_specs = compute_exported_specifications(svc_ref)
        if exported_specs:
            # Transform the specifications for export (add the language prefix)
            self.__exported_specs = format_specifications(exported_specs)
        else:
            raise ValueError(
                "Endpoint {0}, {1}, exports nothing".format(
                    self.__uid, self.__name
                )
            )
Ejemplo n.º 50
0
    def __register_servlet_service(self, service, service_reference):
        """
        Registers a servlet according to its service properties

        :param service: A servlet service
        :param service_reference: The associated ServiceReference
        """
        # Servlet bound
        paths = service_reference.get_property(http.HTTP_SERVLET_PATH)
        if utilities.is_string(paths):
            # Register the servlet to a single path
            self.register_servlet(paths, service)
        elif isinstance(paths, (list, tuple)):
            # Register the servlet to multiple paths
            for path in paths:
                self.register_servlet(path, service)
Ejemplo n.º 51
0
    def __register_servlet_service(self, service, service_reference):
        """
        Registers a servlet according to its service properties

        :param service: A servlet service
        :param service_reference: The associated ServiceReference
        """
        # Servlet bound
        paths = service_reference.get_property(http.HTTP_SERVLET_PATH)
        if utilities.is_string(paths):
            # Register the servlet to a single path
            self.register_servlet(paths, service)
        elif isinstance(paths, (list, tuple)):
            # Register the servlet to multiple paths
            for path in paths:
                self.register_servlet(path, service)
Ejemplo n.º 52
0
    def __init__(self, field, specification, key, allow_none=False,
                 aggregate=False, optional=False, spec_filter=None):
        """
        Sets up the requirement

        :param field: The injected field
        :param specification: The injected service specification
        :param key: Name of the service property to use as a dictionary key
        :param allow_none: If True, inject services with a None property value
        :param aggregate: If true, injects a list
        :param optional: If true, this injection is optional
        :param spec_filter: An LDAP query to filter injected services upon
                            their properties
        :raise TypeError: A parameter has an invalid type
        :raise ValueError: An error occurred while parsing the filter or an
                           argument is incorrect
        """
        # Check if field is valid
        if not field:
            raise ValueError("Empty field name.")

        if not is_string(field):
            raise TypeError("The field name must be a string, not {0}"
                            .format(type(field).__name__))

        if ' ' in field:
            raise ValueError("Field name can't contain spaces.")

        self.__field = field

        # Be sure that there is only one required specification
        specifications = _get_specifications(specification)
        self.__multi_specs = len(specifications) > 1

        # Check if key is valid
        if not key:
            raise ValueError("No property key given")

        # Store the flags
        self.__key = key
        self.__allow_none = allow_none

        # Construct the requirement object
        self.__requirement = Requirement(specifications[0],
                                         aggregate, optional, spec_filter)
Ejemplo n.º 53
0
    def __init__(self,
                 field,
                 specification,
                 aggregate=False,
                 optional=False,
                 spec_filter=None,
                 immediate_rebind=False):
        """
        Sets up the requirement

        :param field: The injected field
        :param specification: The injected service specification
        :param aggregate: If true, injects a list
        :param optional: If true, this injection is optional
        :param spec_filter: An LDAP query to filter injected services upon
                            their properties
        :param immediate_rebind: If True, the component won't be invalidated
                                 then re-validated if a matching service is
                                 available when the injected dependency is
                                 unbound
        :raise TypeError: A parameter has an invalid type
        :raise ValueError: An error occurred while parsing the filter or an
                           argument is incorrect
        """
        if not field:
            raise ValueError("Empty field name.")

        if not is_string(field):
            raise TypeError("The field name must be a string, not {0}".format(
                type(field).__name__))

        if ' ' in field:
            raise ValueError("Field name can't contain spaces.")

        self.__field = field

        # Be sure that there is only one required specification
        specifications = _get_specifications(specification)
        self.__multi_specs = len(specifications) > 1

        # Construct the requirement object
        self.__requirement = Requirement(specifications[0], aggregate,
                                         optional, spec_filter,
                                         immediate_rebind)
Ejemplo n.º 54
0
    def __init__(
        self,
        specification,
        aggregate=False,
        optional=False,
        spec_filter=None,
        immediate_rebind=False,
    ):
        # type: (str, bool, bool, Any, bool) -> None
        """
        Sets up the requirement

        :param specification: The requirement specification, which must be
                              unique and can't be None
        :param aggregate: If true, this requirement represents a list
        :param optional: If true, this requirement is optional
        :param spec_filter: A filter to select dependencies
        :param immediate_rebind: If True, the component won't be invalidated
                                 then re-validated if a matching service is
                                 available when the injected dependency is
                                 unbound
        :raise TypeError: A parameter has an invalid type
        :raise ValueError: An error occurred while parsing the filter
        """
        if not is_string(specification):
            raise TypeError("A Requirement specification must be a string")

        if not specification:
            raise ValueError("No specification given")

        self.specification = specification
        self.aggregate = aggregate
        self.optional = optional
        self.immediate_rebind = immediate_rebind

        # Original filter keeper
        self.__original_filter = None  # type: str

        # Full filter (with the specification ycappuccino_core)
        self.__full_filter = None  # type: ldapfilter.LDAPFilter

        # Set up the requirement filter (after setting up self.specification)
        self.filter = None  # type: ldapfilter.LDAPFilter
        self.set_filter(spec_filter)
Ejemplo n.º 55
0
    def __init__(
        self,
        specification,
        aggregate=False,
        optional=False,
        spec_filter=None,
        immediate_rebind=False,
    ):
        # type: (str, bool, bool, Any, bool) -> None
        """
        Sets up the requirement

        :param specification: The requirement specification, which must be
                              unique and can't be None
        :param aggregate: If true, this requirement represents a list
        :param optional: If true, this requirement is optional
        :param spec_filter: A filter to select dependencies
        :param immediate_rebind: If True, the component won't be invalidated
                                 then re-validated if a matching service is
                                 available when the injected dependency is
                                 unbound
        :raise TypeError: A parameter has an invalid type
        :raise ValueError: An error occurred while parsing the filter
        """
        if not is_string(specification):
            raise TypeError("A Requirement specification must be a string")

        if not specification:
            raise ValueError("No specification given")

        self.specification = specification
        self.aggregate = aggregate
        self.optional = optional
        self.immediate_rebind = immediate_rebind

        # Original filter keeper
        self.__original_filter = None  # type: str

        # Full filter (with the specification test)
        self.__full_filter = None  # type: ldapfilter.LDAPFilter

        # Set up the requirement filter (after setting up self.specification)
        self.filter = None  # type: ldapfilter.LDAPFilter
        self.set_filter(spec_filter)
Ejemplo n.º 56
0
    def __init__(self, name, properties=None):
        """
        Sets up the decorator

        :param name: Instance name
        :param properties: Instance properties
        """
        if not is_string(name):
            raise TypeError("Instance name must be a string")

        if properties is not None and not isinstance(properties, dict):
            raise TypeError("Instance properties must be a dictionary or None")

        name = name.strip()
        if not name:
            raise ValueError("Invalid instance name '{0}'".format(name))

        self.__name = name
        self.__properties = properties
Ejemplo n.º 57
0
def combine_filters(filters, operator=AND):
    """
    Combines two LDAP filters, which can be strings or LDAPFilter objects

    :param filters: Filters to combine
    :param operator: The operator for combination
    :return: The combined filter, can be None if all filters are None
    :raise ValueError: Invalid filter string found
    :raise TypeError: Unknown filter type
    """
    if not filters:
        return None

    if not hasattr(filters, '__iter__') or is_string(filters):
        raise TypeError("Filters argument must be iterable")

    # Remove None filters and convert others
    ldap_filters = []
    for sub_filter in filters:
        if sub_filter is None:
            # Ignore None filters
            continue

        ldap_filter = get_ldap_filter(sub_filter)
        if ldap_filter is not None:
            # Valid filter
            ldap_filters.append(ldap_filter)

    if len(ldap_filters) == 0:
        # Do nothing
        return None

    elif len(ldap_filters) == 1:
        # Only one filter, return it
        return ldap_filters[0]

    new_filter = LDAPFilter(operator)

    for sub_filter in ldap_filters:
        # Direct combination
        new_filter.append(sub_filter)

    return new_filter.normalize()
Ejemplo n.º 58
0
    def __eq__(self, other):
        """
        Tests the equality with another artifact
        """
        if isinstance(other, Artifact):
            # Compare the other artifact
            if self.__file == other.__file:
                # Same file, same artifact
                return True

            # All other attributes must be equal
            return self.__language == other.__language \
                and self.__name == other.__name \
                and self.__version == other.__version
        elif is_string(other):
            # Compare by name
            return self.__name == other
        else:
            # Unknown type
            return NotImplemented
Ejemplo n.º 59
0
def _star_comparison(filter_value, tested_value):
    """
    Tests a filter containing a joker
    """
    if not is_string(tested_value):
        # Unhandled value type...
        return False

    parts = filter_value.split("*")

    i = 0
    last_part = len(parts) - 1

    idx = 0
    for part in parts:
        # Find the part in the tested value
        idx = tested_value.find(part, idx)
        if idx == -1:
            # Part not found
            return False

        len_part = len(part)
        if i == 0 and len_part != 0 and idx != 0:
            # First part is not a star, but the tested value is not at
            # position 0 => Doesn't match
            return False

        if (
            i == last_part
            and len_part != 0
            and idx != len(tested_value) - len_part
        ):
            # Last tested part is not at the end of the sequence
            return False

        # Be sure to test the next part
        idx += len_part
        i += 1

    # Whole test passed
    return True