コード例 #1
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def setAlias(self, alias, identifier):
        """Sets an alias for an existing service.

        @param: string        alias The alias to create
        @param string|Alias  identifier    The service to alias

        @raise InvalidArgumentException if the id is not a string or an Alias:
        @raise InvalidArgumentException if the alias is for itself:

        @api

        """
        alias = self.__formatAlias(alias)

        if isinstance(identifier, str):
            identifier = Alias(identifier)
        elif not isinstance(identifier, Alias):
            raise InvalidArgumentException(
                '$id must be a string, or an Alias object.')

        if alias == str(identifier).lower():
            raise InvalidArgumentException(
                'An alias can not reference itself, got a circular reference '
                'on "{0}".'.format(alias))

        self.__definitions.pop(alias, None)

        self.__aliases[alias] = identifier
コード例 #2
0
    def __validate(self, content, resource):
        """Validates a YAML file.

        @param content:  mixed
        @param resource: string

        @return: dict

        @raise InvalidArgumentException: When service file is not valid

        """
        if content is None:
            return

        if not isinstance(content, dict):
            raise InvalidArgumentException(
                'The "{0}" file is not valid.'.format(resource))

        for namespace in content.keys():
            if namespace in ['imports', 'parameters', 'services']:
                continue

            if not self._container.hasExtension(namespace):
                extensionNamespaces = filter(
                    None,
                    map(lambda e: e.getAlias(),
                        self._container.getExtensions()))
                raise InvalidArgumentException(
                    'There is no extension able to load the configuration '
                    'for "{0}" (in {1}). Looked for namespace "{0}", found "{2}"'
                    ''.format(namespace, resource,
                              '", "'.join(extensionNamespaces)))

        return content
コード例 #3
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def addScope(self, scope):
        """Adds a scope to the container.

        @param: ScopeInterface scope

        @raise InvalidArgumentException

        @api

        """
        assert isinstance(scope, ScopeInterface)

        name = scope.getName()
        parentScope = scope.getParentName()

        if (self.SCOPE_CONTAINER == name or self.SCOPE_PROTOTYPE == name):
            raise InvalidArgumentException(
                'The scope "{0}" is reserved.'.format(name))

        if name in self._scopes:
            raise InvalidArgumentException(
                'A scope with name "{0}" already exists.'.format(name))

        if self.SCOPE_CONTAINER != parentScope and parentScope not in self._scopes:
            raise InvalidArgumentException(
                'The parent scope "{0}" does not exist, or is invalid.'
                ''.format(parentScope))

        self._scopes[name] = parentScope
        self._scopeChildren[name] = list()

        # normalize the child relations
        while (parentScope != self.SCOPE_CONTAINER):
            self._scopeChildren[parentScope].append(name)
            parentScope = self._scopes[parentScope]
コード例 #4
0
    def replaceArgument(self, index, value):
        """You should always use this method when overwriting existing arguments
        of the parent definition.

        If you directly call setArguments() keep in mind that you must follow
        certain conventions when you want to overwrite the arguments of the
        parent definition, otherwise your arguments will only be appended.

        @param integer index
        @param mixed   value

        @return DefinitionDecorator the current instance
        @raise InvalidArgumentException when index isn't an integer

        @api

        """

        if not isinstance(index, int) or isinstance(index, bool):
            raise InvalidArgumentException('index must be an integer.')

        # UPDATED
        self.__overwriteArguments[index] = value

        return self
コード例 #5
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def set(self,
            identifier,
            service,
            scope=ContainerInterface.SCOPE_CONTAINER):
        """Sets a service.

        @param: string identifier  The service identifier:
        @param object service      The service instance
        @param string scope        The scope of the service

        @raise RuntimeException When trying to set a service in an inactive scope
        @raise InvalidArgumentException When trying to set a service in the prototype scope

        @api

        """
        if (self.SCOPE_PROTOTYPE == scope):
            raise InvalidArgumentException(
                'You cannot set service "{0}" of scope "prototype".'
                ''.format(identifier))

        identifier = self._formatIdentifier(identifier)

        if (self.SCOPE_CONTAINER != scope):
            if not scope in self._scopedServices:
                raise RuntimeException(
                    'You cannot set service "{0}" of inactive scope.'
                    ''.format(identifier))

            self._scopedServices[scope][identifier] = service

        self._services[identifier] = service
コード例 #6
0
ファイル: compiler.py プロジェクト: pombredanne/dependency-2
    def getNode(self, identifier):
        """Gets a node by identifier.:

        @param: string id The id to retrieve

        @return ServiceReferenceGraphNode The node matching the supplied identifier:

        @raise InvalidArgumentException if no node matches the supplied identifier:

        """

        if identifier not in self.__nodes:
            raise InvalidArgumentException(
                'There is no node with id "{0}".'.format(identifier))

        return self.__nodes[identifier]
コード例 #7
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def enterScope(self, name):
        """This is called when you enter a scope

        @param: string name

        @raise RuntimeException         When the parent scope is inactive
        @raise InvalidArgumentException When the scope does not exist

        @api

        """

        if name not in self._scopes:
            raise InvalidArgumentException(
                'The scope "{0}" does not exist.'.format(name))

        if self.SCOPE_CONTAINER != self._scopes[name] and self._scopes[
                name] not in self._scopedServices:
            raise RuntimeException(
                'The parent scope "{0}" must be active when entering this '
                'scope.'.format(self._scopes[name]))

        # check if a scope of this name is already active, if so we need to
        # remove all services of this scope, and those of any of its child
        # scopes from the global services map
        if name in self._scopedServices:
            services = OrderedDict()
            services[0] = self._services
            services[name] = self._scopedServices[name]
            self._scopedServices.pop(name, None)

            for child in self._scopeChildren[name]:
                if child in self._scopedServices:
                    services[child] = self._scopedServices[child]
                    self._scopedServices.pop(child, None)

            # update global map
            self._services = Array.diffKey(*services.values())
            services.pop(0)

            # add stack entry for this scope so we can restore the removed services later
            if name not in self._scopeStacks:
                self._scopeStacks[name] = list()

            self._scopeStacks[name].append(services)

        self._scopedServices[name] = dict()
コード例 #8
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def getAlias(self, identifier):
        """Gets an alias.

        @param: string id The service identifier:

        @return Alias An Alias instance

        @raise InvalidArgumentException if the alias does not exist:

        @api

        """
        identifier = self.__formatAlias(identifier)

        if not self.hasAlias(identifier):
            raise InvalidArgumentException(
                'The service alias "{0}" does not exist.'
                ''.format(identifier))

        return self.__aliases[identifier]
コード例 #9
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def getDefinition(self, identifier):
        """Gets a service definition.

        @param: string id The service identifier:

        @return Definition A Definition instance

        @raise InvalidArgumentException if the service definition does not exist:

        @api

        """
        identifier = self._formatIdentifier(identifier)

        if not self.hasDefinition(identifier):
            raise InvalidArgumentException(
                'The service definition "{0}" does not exist.'
                ''.format(identifier))

        return self.__definitions[identifier]
コード例 #10
0
    def _parseFile(self, filename):
        """Parses a INI file.

        @param filename: string The path file

        @return: dict The file content

        @raise InvalidArgumentException: When INI file is not valid
        """
        content = dict()
        cfgParser = ConfigParser()
        result = cfgParser.read(filename)
        if not result:
            raise InvalidArgumentException(
                'The "{0]" file is not valid.'.format(filename))

        for section in cfgParser.sections():
            content[section] = dict()
            for key, value in cfgParser.items(section):
                content[section][key] = value
        return content
コード例 #11
0
ファイル: compiler.py プロジェクト: pombredanne/dependency-2
    def addPass(self, cPass, cType=TYPE_BEFORE_OPTIMIZATION):
        """Adds a pass.

        @param: CompilerPassInterface pass A Compiler pass
        @param string                type The pass type

        @raise InvalidArgumentException when a pass type doesn't exist

        @api

        """
        assert isinstance(cPass, CompilerPassInterface)

        getPropertyName = "get{0}Passes".format(cType)
        setPropertyName = "set{0}Passes".format(cType)

        if not hasattr(self, getPropertyName):
            raise InvalidArgumentException('Invalid type "{0}".'.format(cType))

        passes = getattr(self, getPropertyName)()
        passes.append(cPass)
        getattr(self, setPropertyName)(passes)
コード例 #12
0
    def addMethodCall(self, method, arguments=None):
        """Adds a method to call after service initialization.

        @param: string method    The method name to call
        @param array  arguments An array of arguments to pass to the method call

        @return Definition The current instance

        @raise InvalidArgumentException on empty method param

        @api

        """
        if arguments is None:
            arguments = list()

        arguments = list(arguments)
        method = str(method)
        if not method:
            raise InvalidArgumentException('Method name cannot be empty.')
        self.__calls.append([method, arguments])
        return self
コード例 #13
0
    def _parseFile(self, filename):
        """Parses a JSON file.

        @param filename: string The path file

        @return: dict The file content

        @raise InvalidArgumentException: When JSON file is not valid
        """
        f = open(filename)
        s = f.read().strip()
        f.close()
        del f

        if not s:
            return None

        try:
            result = json.loads(s)
        except ValueError as e:
            raise InvalidArgumentException(e)

        return self.__validate(result, filename)
コード例 #14
0
    def process(self, container):
        """Process the Container to replace aliases with service definitions.

        @param ContainerBuilder container

        @raise InvalidArgumentException if the service definition does not exist:

        """
        assert isinstance(container, ContainerBuilder)

        self.__compiler = container.getCompiler()
        self.__formatter = self.__compiler.getLoggingFormatter()

        for identifier, alias in container.getAliases().items():
            aliasId = str(alias)

            try:
                definition = container.getDefinition(aliasId)
            except InvalidArgumentException as e:
                raise InvalidArgumentException(
                    'Unable to replace alias "{0}" with "{1}".'.format(
                        alias, identifier), None, e)

            if (definition.isPublic()):
                continue

            definition.setPublic(True)
            container.setDefinition(identifier, definition)
            container.removeDefinition(aliasId)

            self.__updateReferences(container, aliasId, identifier)

            # we have to restart the process due to concurrent modification of:
            # the container
            self.process(container)

            break
コード例 #15
0
    def __init__(self, passes):
        """Constructor.

        @param RepeatablePassInterface[] passes An array of RepeatablePassInterface objects

        @raise InvalidArgumentException when the passes don't implement RepeatablePassInterface

        """
        assert isinstance(passes, list)

        self.__repeat = False
        # @var Boolean

        self.__passes = None
        # @var RepeatablePassInterface[]

        for cPass in passes:
            if (not isinstance(cPass, RepeatablePassInterface)):
                raise InvalidArgumentException(
                    'passes must be an array of RepeatablePassInterface.')

            cPass.setRepeatedPass(self)

        self.__passes = passes
コード例 #16
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def leaveScope(self, name):
        """This is called to leave the current scope, and move back to the parent
        scope.

        @param: string name The name of the scope to leave

        @raise InvalidArgumentException if the scope is not active:

        @api

        """

        if name not in self._scopedServices:
            raise InvalidArgumentException(
                'The scope "{0}" is not active.'.format(name))

        # remove all services of this scope, or any of its child scopes from
        # the global service map
        services = [self._services, self._scopedServices[name]]
        self._scopedServices.pop(name, None)
        for child in self._scopeChildren[name]:
            if child not in self._scopedServices:
                continue

            services.append(self._scopedServices[child])
            self._scopedServices.pop(child, None)

        self._services = Array.diffKey(*services)

        # check if we need to restore services of a previous scope of this type:
        if name in self._scopeStacks and self._scopeStacks[name]:
            services = self._scopeStacks[name].pop()
            self._scopedServices.update(services)

            for scopeServices in services.values():
                self._services.update(scopeServices)
コード例 #17
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def __createService(self, definition, identifier):
        """Creates a service for a service definition.

        @param: Definition definition A service definition instance
        @param string     id         The service identifier:

        @return object The service described by the service definition

        @raise RuntimeException When the scope is inactive
        @raise RuntimeException When the factory definition is incomplete
        @raise RuntimeException When the service is a synthetic service
        @raise InvalidArgumentException When configure callable is not callable

        """
        assert isinstance(definition, Definition)

        if definition.isSynthetic():
            raise RuntimeException(
                'You have requested a synthetic service ("{0}"). '
                'The DIC does not know how to construct this service.'
                ''.format(identifier))

        parameterBag = self.getParameterBag()

        if None is not definition.getFile():
            path = parameterBag.resolveValue(definition.getFile())
            module = SourceFileLoader.load(path)
        else:
            module = None

        value = parameterBag.resolveValue(definition.getArguments())
        value = parameterBag.unescapeValue(value)
        arguments = self.resolveServices(value)

        if not definition.getFactoryMethod() is None:
            if not definition.getFactoryClass() is None:
                factory = parameterBag.resolveValue(
                    definition.getFactoryClass())
                if module is not None:
                    factory = getattr(module, factory)
                else:
                    factory = ClassLoader.load(factory)
            elif not definition.getFactoryService() is None:
                factory = self.get(
                    parameterBag.resolveValue(definition.getFactoryService()))
            else:
                raise RuntimeException(
                    'Cannot create service "{0}" from factory method without '
                    'a factory service or factory class.'
                    ''.format(identifier))

            service = getattr(factory,
                              definition.getFactoryMethod())(*arguments)
        else:
            className = parameterBag.resolveValue(definition.getClass())
            if module is not None:
                service = getattr(module, className)(*arguments)
            else:
                service = ClassLoader.load(className)(*arguments)

        scope = definition.getScope()
        if self.SCOPE_PROTOTYPE != scope:
            if self.SCOPE_CONTAINER != scope and scope not in self._scopedServices:
                raise RuntimeException(
                    'You tried to create the "{0}" service of an inactive '
                    'scope.'.format(identifier))

            lowerId = self._formatIdentifier(identifier)
            self._services[lowerId] = service

            if (self.SCOPE_CONTAINER != scope):
                self._scopedServices[scope][lowerId] = service

        for call in definition.getMethodCalls():
            services = self.getServiceConditionals(call[1])
            ok = True
            for s in services:
                if not self.has(s):
                    ok = False
                    break
            if ok:
                args = self.resolveServices(parameterBag.resolveValue(call[1]))
                getattr(service, call[0])(*args)

        properties = self.resolveServices(
            parameterBag.resolveValue(definition.getProperties()))
        for name, value in properties.items():
            setattr(service, name, value)

        closure = definition.getConfigurator()
        if closure:
            if isinstance(closure, list):
                if isinstance(closure[0], Reference):
                    closure[0] = self.get(str(closure[0]))
                else:
                    closure[0] = parameterBag.resolveValue(closure[0])
                    closure[0] = ClassLoader.load(closure[0])

                closure = getattr(closure[0], closure[1])

            if not Tool.isCallable(closure):
                raise InvalidArgumentException(
                    'The configure callable for class "{0}" is not a callable.'
                    ''.format(type(service).__name__))

            closure(service)

        return service
コード例 #18
0
    def __parseDefinition(self, identifier, service, resource):
        """Parses a definition.

        @param identifier: string
        @param service:    dict
        @param resource:   string

        @raise InvalidArgumentException: When tags are invalid

        """

        if isinstance(service, String) and service.startswith('@'):
            self._container.setAlias(identifier, service[1:])

            return
        elif 'alias' in service:
            public = 'public' not in service or bool(service['public'])
            self._container.setAlias(identifier, Alias(service['alias'],
                                                       public))

            return

        if 'parent' in service:
            definition = DefinitionDecorator(service['parent'])
        else:
            definition = Definition()

        if 'class' in service:
            definition.setClass(service['class'])

        if 'scope' in service:
            definition.setScope(service['scope'])

        if 'synthetic' in service:
            definition.setSynthetic(service['synthetic'])

        if 'public' in service:
            definition.setPublic(service['public'])

        if 'abstract' in service:
            definition.setAbstract(service['abstract'])

        if 'factory_class' in service:
            definition.setFactoryClass(service['factory_class'])

        if 'factory_method' in service:
            definition.setFactoryMethod(service['factory_method'])

        if 'factory_service' in service:
            definition.setFactoryService(service['factory_service'])

        if 'file' in service:
            definition.setFile(service['file'])

        if 'arguments' in service:
            definition.setArguments(
                self.__resolveServices(service['arguments']))

        if 'properties' in service:
            definition.setProperties(
                self.__resolveServices(service['properties']))

        if 'configurator' in service:
            if isinstance(service['configurator'], String):
                definition.setConfigurator(service['configurator'])
            else:
                definition.setConfigurator([
                    self.__resolveServices(service['configurator'][0]),
                    service['configurator'][1]
                ])

        if 'calls' in service:
            for call in service['calls']:
                args = self.__resolveServices(
                    call[1]) if len(call) >= 2 else []
                definition.addMethodCall(call[0], args)

        if 'tags' in service:
            if not isinstance(service['tags'], list):
                raise InvalidArgumentException(
                    'Parameter "tags" must be a list for service '
                    '"{0}" in {1}.'.format(identifier, resource))

            for tag in service['tags']:
                if not isinstance(tag, dict) or 'name' not in tag:
                    raise InvalidArgumentException(
                        'A "tags" entry is missing a "name" key for service '
                        '"{0}" in {1}.'.format(identifier, resource))

                name = tag['name']
                del tag['name']

                for value in tag.values():
                    if not isinstance(value,
                                      (type(None), String, int, float, bool)):
                        raise InvalidArgumentException(
                            'A "tags" attribute must be of a scalar-type '
                            'for service "{0}", tag "{1}" in {2}.'
                            ''.format(identifier, name, resource))

                definition.addTag(name, tag)

        self._container.setDefinition(identifier, definition)