コード例 #1
0
ファイル: test_types.py プロジェクト: pombredanne/pymfony
    def testUniq(self):
        in_lst = ["B", "A", "B", "a", "1", "b", "/", "", "2"]
        expected = ["B", "A", "a", "1", "b", "/", "", "2"]
        result = Array.uniq(in_lst)
        self.assertEqual(result, expected)

        in_lst = {
            "B": 0,
            "A": 1,
            "B": 0,
            "a": 2,
            "1": 3,
            "b": 4,
            "/": 5,
            "": "d",
            "2": 6
        }
        expected = {
            "B": 0,
            "A": 1,
            "a": 2,
            "1": 3,
            "b": 4,
            "/": 5,
            "": "d",
            "2": 6
        }
        result = Array.uniq(in_lst)
        self.assertEqual(result, expected)
コード例 #2
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def _mergeValues(self, leftSide, rightSide):
        """Merges values together.

        @param leftSide:  mixed The left side to merge.
        @param rightSide: mixed The right side to merge.

        @return mixed The merged values

        @raise InvalidConfigurationException:
        @raise RuntimeException:

        """
        if rightSide is False:
            # if this is still false after the last config has been merged the
            # finalization pass will take care of removing this key entirely
            return False;

        if not leftSide or not self._performDeepMerging:
            return rightSide;

        if isinstance(leftSide, list):
            leftSide = Array.toDict(leftSide);

        if isinstance(rightSide, list):
            rightSide = Array.toDict(rightSide);

        i = -1;
        for k, v in rightSide.items():
            i += 1;
            # prototype, and key is irrelevant, so simply append the element
            if self._keyAttribute is None:
                # dict: append
                index = 0;
                while index in leftSide:
                    index += 1;
                leftSide[index] = v;
                continue;

            # no conflict
            if k not in leftSide:
                if not self._allowNewKeys:
                    ex = InvalidConfigurationException(
                        'You are not allowed to define new elements for path '
                        '"{0}". Please define all elements for this path in '
                        'one config file. If you are trying to overwrite an '
                        'element, make sure you redefine it with the same '
                        'name.'.format(self.getPath())
                    );
                    ex.setPath(self.getPath());
                    raise ex;

                leftSide[k] = v;
                continue;

            self._prototype.setName(k);
            leftSide[k] = self._prototype.merge(leftSide[k], v);

        return leftSide;
コード例 #3
0
ファイル: __init__.py プロジェクト: pombredanne/pymfony
    def _mergeValues(self, leftSide, rightSide):
        """Merges values together.

        @param leftSide:  mixed The left side to merge.
        @param rightSide: mixed The right side to merge.

        @return mixed The merged values

        @raise InvalidConfigurationException:
        @raise RuntimeException:

        """
        if rightSide is False:
            # if this is still false after the last config has been merged the
            # finalization pass will take care of removing this key entirely
            return False

        if not leftSide or not self._performDeepMerging:
            return rightSide

        if isinstance(leftSide, list):
            leftSide = Array.toDict(leftSide)

        if isinstance(rightSide, list):
            rightSide = Array.toDict(rightSide)

        i = -1
        for k, v in rightSide.items():
            i += 1
            # prototype, and key is irrelevant, so simply append the element
            if self._keyAttribute is None:
                # dict: append
                index = 0
                while index in leftSide:
                    index += 1
                leftSide[index] = v
                continue

            # no conflict
            if k not in leftSide:
                if not self._allowNewKeys:
                    ex = InvalidConfigurationException(
                        'You are not allowed to define new elements for path '
                        '"{0}". Please define all elements for this path in '
                        'one config file. If you are trying to overwrite an '
                        'element, make sure you redefine it with the same '
                        'name.'.format(self.getPath()))
                    ex.setPath(self.getPath())
                    raise ex

                leftSide[k] = v
                continue

            self._prototype.setName(k)
            leftSide[k] = self._prototype.merge(leftSide[k], v)

        return leftSide
コード例 #4
0
ファイル: test_types.py プロジェクト: visonforcoding/pymfony
    def testUniq(self):
        in_lst = ["B", "A", "B", "a", "1", "b", "/", "", "2"];
        expected = ["B", "A", "a", "1", "b", "/", "", "2"];
        result = Array.uniq(in_lst);
        self.assertEqual(result, expected);

        in_lst = {"B":0, "A":1, "B":0, "a":2, "1":3, "b":4, "/":5, "":"d", "2":6};
        expected = {"B":0, "A":1, "a":2, "1":3, "b":4, "/":5, "":"d", "2":6};
        result = Array.uniq(in_lst);
        self.assertEqual(result, expected);
コード例 #5
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def __init__(self, definition=None):
        if definition is None:
            definition = InputDefinition()
        assert isinstance(definition, InputDefinition)

        self.__routes = Array()
        # @var: Route[]

        self.__resources = list()
        # @var: list

        self.__definition = definition
コード例 #6
0
ファイル: __init__.py プロジェクト: pombredanne/pymfony
    def __writeArray(self, array, depth):
        assert isinstance(array, (list, dict))

        isIndexed = False
        if isinstance(array, dict):
            for key in array.keys():
                if not isinstance(key, int):
                    isIndexed = False
                    break
        else:
            isIndexed = True
            array = Array.toDict(array)

        for key, value in array.items():
            if isinstance(value, (list, dict)):
                val = ''
            else:
                val = value

            if (isIndexed):
                self.__writeLine('- ' + val, depth * 4)
            else:
                self.__writeLine('{0:20} {1}'.format(key + ':', val),
                                 depth * 4)

            if isinstance(value, (list, dict)):
                self.__writeArray(value, depth + 1)
コード例 #7
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def __writeArray(self, array, depth):
        assert isinstance(array, (list, dict));

        isIndexed = False;
        if isinstance(array, dict):
            for key in array.keys():
                if not isinstance(key, int):
                    isIndexed = False;
                    break;
        else:
            isIndexed = True;
            array = Array.toDict(array);

        for key, value in array.items():
            if isinstance(value, (list, dict)) :
                val = '';
            else :
                val = value;


            if (isIndexed) :
                self.__writeLine('- '+val, depth * 4);
            else :
                self.__writeLine('{0:20} {1}'.format( key+':', val), depth * 4);


            if isinstance(value, (list, dict)) :
                self.__writeArray(value, depth + 1);
コード例 #8
0
    def __isInlineableDefinition(self, container, identifier, definition):
        """Checks if the definition is inlineable.:

        @param ContainerBuilder container
        @param string           identifier
        @param Definition       definition

        @return Boolean If the definition is inlineable

        """
        assert isinstance(definition, Definition);
        assert isinstance(container, ContainerBuilder);

        if (ContainerInterface.SCOPE_PROTOTYPE == definition.getScope()) :
            return True;


        if (definition.isPublic()) :
            return False;


        if ( not self.__graph.hasNode(identifier)) :
            return True;


        ids = list();
        for edge in self.__graph.getNode(identifier).getInEdges():
            ids.append(edge.getSourceNode().getId());


        if (len(Array.uniq(ids)) > 1) :
            return False;


        return container.getDefinition(ids[0]).getScope() == definition.getScope();
コード例 #9
0
    def __isInlineableDefinition(self, container, identifier, definition):
        """Checks if the definition is inlineable.:

        @param ContainerBuilder container
        @param string           identifier
        @param Definition       definition

        @return Boolean If the definition is inlineable

        """
        assert isinstance(definition, Definition)
        assert isinstance(container, ContainerBuilder)

        if (ContainerInterface.SCOPE_PROTOTYPE == definition.getScope()):
            return True

        if (definition.isPublic()):
            return False

        if (not self.__graph.hasNode(identifier)):
            return True

        ids = list()
        for edge in self.__graph.getNode(identifier).getInEdges():
            ids.append(edge.getSourceNode().getId())

        if (len(Array.uniq(ids)) > 1):
            return False

        return container.getDefinition(
            ids[0]).getScope() == definition.getScope()
コード例 #10
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def getResources(self):
        """Returns an array of resources loaded to build this collection.

        @return: ResourceInterface[] An array of resources

        """

        return Array.uniq(self.__resources, str)
コード例 #11
0
    def ifNotInArray(self, target):
        """Tests if the value is not in an array

        @param target: dict

        @return: ExprBuilder
        """
        self.ifPart = lambda v: v not in Array.toDict(target).values();
        return self;
コード例 #12
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def getServiceIds(self):
        """Gets all service ids.

        @return: list A list of all defined service ids

        """
        return Array.uniq(
            list(self.getDefinitions().keys()) +\
            list(self.getAliases().keys()) +\
            Container.getServiceIds(self)
        )
コード例 #13
0
    def values(self, values):
        assert isinstance(values, list);

        values = Array.uniq(values);

        if (len(values) <= 1) :
            raise InvalidArgumentException('.values() must be called with at least two distinct values.');


        self.__values = values;

        return self;
コード例 #14
0
    def process(self, container):
        """Processes the ContainerBuilder to remove unused definitions.

        @param ContainerBuilder container

        """
        assert isinstance(container, ContainerBuilder);

        compiler = container.getCompiler();
        formatter = compiler.getLoggingFormatter();
        graph = compiler.getServiceReferenceGraph();

        hasChanged = False;
        definitions = container.getDefinitions().copy();
        for identifier, definition in definitions.items():
            if (definition.isPublic()) :
                continue;


            if (graph.hasNode(identifier)) :
                edges = graph.getNode(identifier).getInEdges();
                referencingAliases = list();
                sourceIds = list();
                for edge in edges:
                    node = edge.getSourceNode();
                    sourceIds.append(node.getId());

                    if (node.isAlias()) :
                        referencingAliases.append(node.getValue());


                isReferenced = (len(Array.uniq(sourceIds)) - len(referencingAliases)) > 0;
            else :
                referencingAliases = list();
                isReferenced = False;


            if (1 == len(referencingAliases) and False is isReferenced) :
                container.setDefinition(str(referencingAliases[0]), definition);
                definition.setPublic(True);
                container.removeDefinition(identifier);
                compiler.addLogMessage(formatter.formatRemoveService(self, identifier, 'replaces alias '+referencingAliases[0]));
            elif (0 == len(referencingAliases) and False is isReferenced) :
                container.removeDefinition(identifier);
                compiler.addLogMessage(formatter.formatRemoveService(self, identifier, 'unused'));
                hasChanged = True;



        if (hasChanged) :
            self.__repeatedPass.setRepeat();
コード例 #15
0
    def process(self, container):
        """Processes the ContainerBuilder to remove unused definitions.

        @param ContainerBuilder container

        """
        assert isinstance(container, ContainerBuilder)

        compiler = container.getCompiler()
        formatter = compiler.getLoggingFormatter()
        graph = compiler.getServiceReferenceGraph()

        hasChanged = False
        definitions = container.getDefinitions().copy()
        for identifier, definition in definitions.items():
            if (definition.isPublic()):
                continue

            if (graph.hasNode(identifier)):
                edges = graph.getNode(identifier).getInEdges()
                referencingAliases = list()
                sourceIds = list()
                for edge in edges:
                    node = edge.getSourceNode()
                    sourceIds.append(node.getId())

                    if (node.isAlias()):
                        referencingAliases.append(node.getValue())

                isReferenced = (len(Array.uniq(sourceIds)) -
                                len(referencingAliases)) > 0
            else:
                referencingAliases = list()
                isReferenced = False

            if (1 == len(referencingAliases) and False is isReferenced):
                container.setDefinition(str(referencingAliases[0]), definition)
                definition.setPublic(True)
                container.removeDefinition(identifier)
                compiler.addLogMessage(
                    formatter.formatRemoveService(
                        self, identifier,
                        'replaces alias ' + referencingAliases[0]))
            elif (0 == len(referencingAliases) and False is isReferenced):
                container.removeDefinition(identifier)
                compiler.addLogMessage(
                    formatter.formatRemoveService(self, identifier, 'unused'))
                hasChanged = True

        if (hasChanged):
            self.__repeatedPass.setRepeat()
コード例 #16
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def getServiceIds(self):
        """Gets all service ids.

        @return: list An array of all defined service ids

        """

        ids = list()
        r = ReflectionObject(self)
        for method in r.getMethods():
            match = re.search('^get(.+)Service$', method.getName())
            if match:
                ids.append(self.underscore(match.group(1)))

        return Array.uniq(ids + list(self._services.keys()))
コード例 #17
0
ファイル: __init__.py プロジェクト: pombredanne/pymfony
    def setDefaultValue(self, value):
        """Sets the default value of this node.

        @param value: dict

        @raise InvalidArgumentException: if the default value is not an array
        """
        if isinstance(value, list):
            value = Array.toDict(value)
        if not isinstance(value, dict):
            raise InvalidArgumentException(
                '{0}: the default value of an array node has to be an array.'
                ''.format(self.getPath()))

        self._defaultValue = value
コード例 #18
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def _mergeValues(self, leftSide, rightSide):
        """Merges values together.

        @param leftSide:  mixed The left side to merge.
        @param rightSide: mixed The right side to merge.

        @return: mixed The merged values

        @rasie InvalidConfigurationException:
        @rasie RuntimeException:

        """
        if rightSide is False:
            # if this is still false after the last config has been merged the
            # finalization pass will take care of removing this key entirely
            return False;

        if not leftSide or not self._performDeepMerging:
            return rightSide;

        if isinstance(rightSide, list):
            rightSide = Array.toDict(rightSide);

        for k, v in rightSide.items():
            # no conflict
            if k not in leftSide:
                if not self._allowNewKeys:
                    ex = InvalidConfigurationException(
                        'You are not allowed to define new elements for path '
                        '"{0}". Please define all elements for this path in '
                        'one config file. If you are trying to overwrite an '
                        'element, make sure you redefine it with the same '
                        'name.'.format(self.getPath())
                    );
                    ex.setPath(self.getPath());
                    raise ex;

                leftSide[k] = v;
                continue;

            if k not in self._children:
                raise RuntimeException(
                    'merge() expects a normalized config array.'
                );

            leftSide[k] = self._children[k].merge(leftSide[k], v);

        return leftSide;
コード例 #19
0
ファイル: __init__.py プロジェクト: pombredanne/pymfony
    def __init__(self, name, parent=None, values=None):
        if values is None:
            values = list()
        assert isinstance(values, list)
        if parent:
            assert isinstance(parent, NodeInterface)

        self.__values = None

        values = Array.uniq(values)
        if (len(values) <= 1):
            raise InvalidArgumentException(
                'values must contain at least two distinct elements.')

        ScalarNode.__init__(self, name, parent)
        self.__values = values
コード例 #20
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def __init__(self, name, parent = None, values = None):
        if values is None:
            values = list();
        assert isinstance(values, list);
        if parent:
            assert isinstance(parent, NodeInterface);

        self.__values = None;

        values = Array.uniq(values);
        if (len(values) <= 1) :
            raise InvalidArgumentException('values must contain at least two distinct elements.');


        ScalarNode.__init__(self, name, parent);
        self.__values = values;
コード例 #21
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def setDefaultValue(self, value):
        """Sets the default value of this node.

        @param value: dict

        @raise InvalidArgumentException: if the default value is not an array
        """
        if isinstance(value, list):
            value = Array.toDict(value);
        if not isinstance(value, dict):
            raise InvalidArgumentException(
                '{0}: the default value of an array node has to be an array.'
                ''.format(self.getPath())
            );

        self._defaultValue = value;
コード例 #22
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()
コード例 #23
0
ファイル: test_types.py プロジェクト: pombredanne/pymfony
 def testDiffKeyBasic(self):
     array1 = {
         'blue': 1,
         'red': 2,
         'green': 3,
         'purple': 4
     }
     array2 = {
         'green': 5,
         'blue': 6,
         'yellow': 7,
         'cyan': 8
     }
     self.assertEqual({
         "red": 2,
         "purple": 4
     }, Array.diffKey(array1, array2))
コード例 #24
0
ファイル: test_types.py プロジェクト: pombredanne/pymfony
 def testDiffKeyName(self):
     input_array = {
         0: '0',
         1: '1',
         -10: '-10',
         'True': 1,
         'False': 0
     }
     boolean_indx_array = {
         True: 'boolt',
         False: 'boolf',
         True: 'boolT',
         False: 'boolF'
     }
     expected = {-10: "-10", "True": 1, "False": 0}
     self.assertEqual(expected,
                      Array.diffKey(input_array, boolean_indx_array))
コード例 #25
0
ファイル: __init__.py プロジェクト: pombredanne/pymfony
    def _mergeValues(self, leftSide, rightSide):
        """Merges values together.

        @param leftSide:  mixed The left side to merge.
        @param rightSide: mixed The right side to merge.

        @return: mixed The merged values

        @rasie InvalidConfigurationException:
        @rasie RuntimeException:

        """
        if rightSide is False:
            # if this is still false after the last config has been merged the
            # finalization pass will take care of removing this key entirely
            return False

        if not leftSide or not self._performDeepMerging:
            return rightSide

        if isinstance(rightSide, list):
            rightSide = Array.toDict(rightSide)

        for k, v in rightSide.items():
            # no conflict
            if k not in leftSide:
                if not self._allowNewKeys:
                    ex = InvalidConfigurationException(
                        'You are not allowed to define new elements for path '
                        '"{0}". Please define all elements for this path in '
                        'one config file. If you are trying to overwrite an '
                        'element, make sure you redefine it with the same '
                        'name.'.format(self.getPath()))
                    ex.setPath(self.getPath())
                    raise ex

                leftSide[k] = v
                continue

            if k not in self._children:
                raise RuntimeException(
                    'merge() expects a normalized config array.')

            leftSide[k] = self._children[k].merge(leftSide[k], v)

        return leftSide
コード例 #26
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def setAddChildrenIfNoneSet(self, children=None):
        """Adds default children when none are set.

        @param children: integer|string|dict|null The number of
            children|The child name|The children names to be added
        """
        if children is None:
            children = ['defaults'];
        elif isinstance(children, int) and children > 0:
            children = list(range(1, children+1));
        elif isinstance(children, String):
            children = [children];

        if isinstance(children, list):
            children = Array.toDict(children);

        assert isinstance(children, dict);
        self._defaultChildren = children;
コード例 #27
0
ファイル: __init__.py プロジェクト: pombredanne/pymfony
    def setAddChildrenIfNoneSet(self, children=None):
        """Adds default children when none are set.

        @param children: integer|string|dict|null The number of
            children|The child name|The children names to be added
        """
        if children is None:
            children = ['defaults']
        elif isinstance(children, int) and children > 0:
            children = list(range(1, children + 1))
        elif isinstance(children, String):
            children = [children]

        if isinstance(children, list):
            children = Array.toDict(children)

        assert isinstance(children, dict)
        self._defaultChildren = children
コード例 #28
0
ファイル: __init__.py プロジェクト: pombredanne/dependency-2
    def getServiceConditionals(cls, value):
        """Returns the Service Conditionals.

        @param: mixed value An array of conditionals to return.

        @return array An array of Service conditionals

        """
        services = list()

        if isinstance(value, list):
            for v in value:
                iterable = cls.getServiceConditionals(v)
                services.extend(iterable)
                services = Array.uniq(services)
        elif isinstance(value, Reference):
            services.append(str(value))

        return services
コード例 #29
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def locate(self, name, currentPath = None, first = True):
        """Returns a full path for a given file name.

        @param name: mixed The file name to locate
        @param currentPath: string The current path
        @param first: boolean Whether to return the first occurrence 
                      or an array of filenames

        @return: string|list The full path to the file|A list of file paths

        @raise InvalidArgumentException: When file is not found

        """
        if self.__isAbsolutePath(name):
            if not os.path.exists(name):
                raise InvalidArgumentException(
                    'The file "{0}" does not exist.'.format(name)
                );
            return name;

        filepaths = list();

        paths = [];
        if currentPath:
            paths.append(currentPath);
        paths.extend(self._paths);

        for path in paths:
            filename = os.path.join(path, name);
            if os.path.exists(filename):
                if first:
                    return filename;
                filepaths.append(filename);

        if not filepaths:
            raise InvalidArgumentException(
                'The file "{0}" does not exist (in: {1}).'
                ''.format(name, ", ".join(paths))
            );

        return Array.uniq(filepaths);
コード例 #30
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def _normalizeValue(self, value):
        """Normalizes the value.

        @param value: mixed The value to normalize

        @return: mixed The normalized value

        @raise InvalidConfigurationException:

        """
        if value is False:
            return value;

        if isinstance(value, list):
            value = Array.toDict(value);

        assert isinstance(value, dict);

        value = self._remapXml(value);
        normalized = dict();

        valueCopy = value.copy();

        for name, child in self._children.items():
            assert isinstance(child, NodeInterface)
            if name in valueCopy:
                normalized[name] = child.normalize(value[name]);
                valueCopy.pop(name);

        # if extra fields are present, throw exception
        if valueCopy and not self._ignoreExtraKeys:
            ex = InvalidConfigurationException(
                'Unrecognized options "{0}" under "{1}"'
                ''.format(", ".join(value.keys()), self.getPath())
            );
            ex.setPath(self.getPath());
            raise ex;

        return normalized;
コード例 #31
0
ファイル: __init__.py プロジェクト: pombredanne/pymfony
    def locate(self, name, currentPath=None, first=True):
        """Returns a full path for a given file name.

        @param name: mixed The file name to locate
        @param currentPath: string The current path
        @param first: boolean Whether to return the first occurrence 
                      or an array of filenames

        @return: string|list The full path to the file|A list of file paths

        @raise InvalidArgumentException: When file is not found

        """
        if self.__isAbsolutePath(name):
            if not os.path.exists(name):
                raise InvalidArgumentException(
                    'The file "{0}" does not exist.'.format(name))
            return name

        filepaths = list()

        paths = []
        if currentPath:
            paths.append(currentPath)
        paths.extend(self._paths)

        for path in paths:
            filename = os.path.join(path, name)
            if os.path.exists(filename):
                if first:
                    return filename
                filepaths.append(filename)

        if not filepaths:
            raise InvalidArgumentException(
                'The file "{0}" does not exist (in: {1}).'
                ''.format(name, ", ".join(paths)))

        return Array.uniq(filepaths)
コード例 #32
0
ファイル: __init__.py プロジェクト: pombredanne/pymfony
    def _normalizeValue(self, value):
        """Normalizes the value.

        @param value: mixed The value to normalize

        @return: mixed The normalized value

        @raise InvalidConfigurationException:

        """
        if value is False:
            return value

        if isinstance(value, list):
            value = Array.toDict(value)

        assert isinstance(value, dict)

        value = self._remapXml(value)
        normalized = dict()

        valueCopy = value.copy()

        for name, child in self._children.items():
            assert isinstance(child, NodeInterface)
            if name in valueCopy:
                normalized[name] = child.normalize(value[name])
                valueCopy.pop(name)

        # if extra fields are present, throw exception
        if valueCopy and not self._ignoreExtraKeys:
            ex = InvalidConfigurationException(
                'Unrecognized options "{0}" under "{1}"'
                ''.format(", ".join(value.keys()), self.getPath()))
            ex.setPath(self.getPath())
            raise ex

        return normalized
コード例 #33
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)
コード例 #34
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def _initializeBundles(self):
        """Initializes the data structures related to the bundle management.

         - the bundles property maps a bundle name to the bundle instance,
         - the bundleMap property maps a bundle name to the bundle inheritance
           hierarchy (most derived bundle first).

        @raise LogicException: if two bundles share a common name
        @raise LogicException: if a bundle tries to extend a non-registered
                               bundle
        @raise LogicException: if a bundle tries to extend itself
        @raise LogicException: if two bundles extend the same ancestor
        """
        #  init bundle
        self._bundles = dict();
        topMostBundles = dict();
        directChildren = dict();

        for bundle in self.registerBundles():
            assert isinstance(bundle, BundleInterface);

            name = bundle.getName();
            if name in self._bundles.keys():
                raise LogicException(
                    'Trying to register two bundles with the same name "{0}"'
                    ''.format(name)
                );

            self._bundles[name] = bundle;

            parentName = bundle.getParent();
            if parentName:
                if parentName in directChildren.keys():
                    raise LogicException(
                        'Bundle "{0}" is directly extended by two bundles '
                        '"{1}" and "{2}".'
                        ''.format(parentName, name, directChildren[parentName])
                    );
                if parentName == name:
                    raise LogicException(
                        'Bundle "{0}" can not extend itself.'.format(name)
                    );
                directChildren[parentName] = name;
            else:
                topMostBundles[name] = bundle;

            # look for orphans
            diff = Array.diff(
                list(directChildren.keys()),
                list(self._bundles.keys()),
            );
            if diff:
                raise LogicException(
                    'Bundle "{0}" extends bundle "{1}", which is not registered.'
                    ''.format(directChildren[diff[0]], diff[0])
                );

            # inheritance
            self._bundleMap = dict();
            for name, bundle in topMostBundles.items():
                bundleMap = [bundle];
                hierarchy = [name];

                while name in directChildren.keys():
                    name = directChildren[name];
                    bundleMap.insert(0, self._bundles[name]);
                    hierarchy.append(name);

                for name in hierarchy:
                    self._bundleMap[name] = list(bundleMap);
                    bundleMap.pop();
コード例 #35
0
ファイル: loader.py プロジェクト: visonforcoding/pymfony
    def _validate(self, config, name, path):
        """Validates the route configuration.

        @param: dict  config A resource config
        @param string name   The config key
        @param string path   The loaded file path

        @raise InvalidArgumentException If one of the provided config keys is not supported,
                                          something is missing or the combination is nonsense

        """

        if not isinstance(config, dict) :
            raise InvalidArgumentException(
                'The definition of "{0}" in "{1}" must be a Json object.'
                ''.format(name, path)
            );

        extraKeys = Array.diff(config.keys(), self.__availableKeys);
        if (extraKeys) :
            raise InvalidArgumentException(
                'The routing file "{0}" contains unsupported keys for "{1}": '
                '"{2}". Expected one of: "{3}".'.format(
                path,
                name,
                '", "'.join(extraKeys),
                '", "'.join(self.__availableKeys),
            ));

        if 'resource' in config and 'path' in config :
            raise InvalidArgumentException(
                'The routing file "{0}" must not specify both the "resource" '
                'key and the "path" key for "{1}". Choose between an import '
                'and a route definition.'.format(
                path, name
            ));

        if 'resource' in config and 'description' in config :
            raise InvalidArgumentException(
                'The routing file "{0}" must not specify both the "resource" '
                'key and the "description" key for "{1}". Choose between an '
                'import and a route definition.'.format(
                path, name
            ));

        if 'resource' not in config and 'type' in config :
            raise InvalidArgumentException(
                'The "type" key for the route definition "{0}" in "{1}" is '
                'unsupported. It is only available for imports in combination '
                'with the "resource" key.'.format(
                name, path
            ));

        if 'resource' not in config and 'path' not in config :
            raise InvalidArgumentException(
                'You must define a "path" for the route "{0}" in file "{1}".'
                ''.format(name, path)
            );

        if 'path' in config and not config['path']:
            raise InvalidArgumentException(
                'The "path" for the route "{0}" in file "{1}" cannot be empty.'
                ''.format(name, path)
            );

        if 'definition' in config:
            if 'arguments' in config['definition']:
                if not isinstance(config['definition']['arguments'], OrderedDict):
                    raise InvalidArgumentException(
                        'The definition.arguments key should be a JSON object '
                        'in route "{0}" in file "{1}".'
                        ''.format(name, path)
                    );
            if 'options' in config['definition']:
                if not isinstance(config['definition']['options'], dict):
                    raise InvalidArgumentException(
                        'The definition.options key should be a JSON object '
                        'in route "{0}" in file "{1}".'
                        ''.format(name, path)
                    );
コード例 #36
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
class RouteCollection(IteratorAggregateInterface, CountableInterface):
    """A RouteCollection represents a set of Route instances.

    When adding a route at the end of the collection, an existing route
    with the same name is removed first. So there can only be one route
    with a given name.

    @author: Fabien Potencier <*****@*****.**>
    @author Tobias Schultze <http://tobion.de>

    @api

    """
    def __init__(self, definition=None):
        if definition is None:
            definition = InputDefinition()
        assert isinstance(definition, InputDefinition)

        self.__routes = Array()
        # @var: Route[]

        self.__resources = list()
        # @var: list

        self.__definition = definition
        # @var: InputDefinition

    def __clone__(self):

        for name, route in self.__routes.items():
            self.__routes[name] = clone(route)

    def __iter__(self):
        """Gets the current RouteCollection as an Iterator that includes all routes.

        It implements IteratorAggregate.

        @see: all()

        @return ArrayIterator An ArrayIterator object for iterating over routes

        """

        return self.__routes.__iter__()

    def __len__(self):
        """Gets the number of Routes in this collection.

        @return: int The number of routes

        """

        return len(self.__routes)

    def add(self, name, route):
        """Adds a route.

        @param: string name  The route name
        @param Route  route A Route instance

        @return: RouteCollection The current instance

        @api

        """
        assert isinstance(route, Route)

        self.__routes.pop(name, None)

        # Force the creation of the synopsis before the merge with
        # the collection definition
        route.getSynopsis()

        self.__mergeDefinition(route, self.__definition)

        self.__routes[name] = route

        return self

    def all(self):
        """Returns all routes in this collection.

        @return: Route[] An array of routes

        """

        return self.__routes

    def get(self, name):
        """Gets a route by name.

        @param: string name The route name

        @return Route|None A Route instance or None when not found

        """

        return self.__routes[name] if name in self.__routes else None

    def remove(self, name):
        """Removes a route or an array of routes by name from the collection

        @param: string|list name The route name or an array of route names

        @return: RouteCollection The current instance
        """

        if not isinstance(name, list):
            name = [name]

        for n in name:
            self.__routes.pop(n, None)

        return self

    def addCollection(self, collection):
        """Adds a route collection at the end of the current set by appending all
        routes of the added collection.

        @param: RouteCollection collection      A RouteCollection instance

        @return: RouteCollection The current instance

        @api

        """
        assert isinstance(collection, RouteCollection)

        for name, route in collection.all().items():
            self.add(name, route)

        self.__resources = self.__resources + collection.getResources()

        return self

    def getResources(self):
        """Returns an array of resources loaded to build this collection.

        @return: ResourceInterface[] An array of resources

        """

        return Array.uniq(self.__resources, str)

    def addResource(self, resource):
        """Adds a resource for this collection.

        @param: ResourceInterface resource A resource instance

        @return: RouteCollection The current instance
        """
        assert isinstance(resource, ResourceInterface)

        self.__resources.append(resource)

        return self

    def addObjectResource(self, objectResource):
        """Adds the object class hierarchy as resources.

        @param: object object An object instance

        @return RouteCollection The current instance

        """
        assert isinstance(objectResource, Object)

        parent = ReflectionObject(objectResource)
        while parent:
            self.addResource(FileResource(parent.getFileName()))
            parent = parent.getParentClass()

        return self

    def getDefinition(self):
        """Returns the definition of this collection.

        @return: InputDefinition The InputDefinition of this collection

        """

        return self.__definition

    def setDefinition(self, definition):
        """Sets the definition of this collection.

        @param: InputDefinition definition A resource instance

        @return: RouteCollection The current instance
        """
        assert isinstance(definition, InputDefinition)

        self.__definition = definition

        return self

    def prependDefinition(self, definition):
        """Prepends a definition to the definition of all child routes.

        @param: InputDefinition  definition   A definition to prepend

        @return: RouteCollection The current instance
        """
        assert isinstance(definition, InputDefinition)

        self.__mergeDefinition(self.__definition, definition)

        for route in self.__routes.values():
            self.__mergeDefinition(route, definition)

        return self

    def addPrefix(self, prefix):
        """Adds a prefix to the path of all child routes.

        @param: string prefix       An optional prefix to add before each pattern of the route collection

        @return: RouteCollection The current instance

        @api

        """

        prefix = prefix.strip().strip(':')

        if not prefix:
            return

        for route in self.__routes.values():
            route.setPath(prefix + ':' + route.getPath())

        return self

    def addDefaults(self, defaults):
        """Adds defaults to all routes.

        An existing default value under the same name in a route will be overridden.

        @param: dict defaults An array of default values

        @return: RouteCollection The current instance
        """
        assert isinstance(defaults, dict)

        if defaults:
            for route in self.__routes.values():
                route.addDefaults(defaults)

        return self

    def addRequirements(self, requirements):
        """Adds requirements to all routes.

        An existing requirement under the same name in a route will be overridden.

        @param: dict requirements An array of requirements

        @return: RouteCollection The current instance
        """
        assert isinstance(requirements, dict)

        if requirements:
            for route in self.__routes.values():
                route.addRequirements(requirements)

        return self

    def __mergeDefinition(self, definition, parentDefinition):
        """Merges the definition with the parentDefinition.

        @param: InputDefinition  definition        Initial definition to merge
        @param: InputDefinition  parentDefinition  A definition from merge

        @return: RouteCollection The current instance
        """
        assert isinstance(definition, InputDefinition)
        assert isinstance(parentDefinition, InputDefinition)

        currentArguments = definition.getArguments()
        definition.setArguments(parentDefinition.getArguments())
        definition.addArguments(currentArguments)

        definition.addOptions(parentDefinition.getOptions())

        return self
コード例 #37
0
ファイル: __init__.py プロジェクト: pombredanne/pymfony
    def _normalizeValue(self, value):
        """Normalizes the value.

        @param value: mixed The value to normalize

        @return mixed The normalized value

        @raise InvalidConfigurationException:
        @raise DuplicateKeyException:

        """
        if value is False:
            return value

        if isinstance(value, list):
            value = Array.toDict(value)

        assert isinstance(value, dict)

        value = self._remapXml(value)

        isAssoc = list(value.keys()) != list(range(len(value)))
        normalized = dict()

        i = -1
        for k, v in value.items():
            i += 1

            if self._keyAttribute is not None and isinstance(v, (dict, list)):
                if isinstance(v, list):
                    v = Array.toDict(v)

                if self._keyAttribute not in v \
                    and isinstance(k, int) \
                    and not isAssoc:
                    ex = InvalidConfigurationException(
                        'The attribute "{0}" must be set for path "{1}".'
                        ''.format(self._keyAttribute, self.getPath()))
                    ex.setPath(self.getPath())
                    raise ex
                elif self._keyAttribute in v:
                    k = v[self._keyAttribute]

                    # remove the key attribute when required
                    if self._removeKeyAttribute:
                        del v[self._keyAttribute]

                    # if only "value" is left
                    if 1 == len(v) and 'value' in v:
                        v = v['value']

                if k in normalized:
                    ex = DuplicateKeyException(
                        'Duplicate key "{0}" for path "{1}".'
                        ''.format(k, self.getPath()))
                    ex.setPath(self.getPath())
                    raise ex

            self._prototype.setName(k)
            if not self._keyAttribute is None or isAssoc:
                normalized[k] = self._prototype.normalize(v)
            else:
                normalized[i] = self._prototype.normalize(v)

        return normalized
コード例 #38
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def _normalizeValue(self, value):
        """Normalizes the value.

        @param value: mixed The value to normalize

        @return mixed The normalized value

        @raise InvalidConfigurationException:
        @raise DuplicateKeyException:

        """
        if value is False:
            return value;

        if isinstance(value, list):
            value = Array.toDict(value);

        assert isinstance(value, dict);

        value = self._remapXml(value);

        isAssoc = list(value.keys()) != list(range(len(value)));
        normalized = dict();

        i = -1;
        for k, v in value.items():
            i += 1;

            if self._keyAttribute is not None and isinstance(v, (dict, list)):
                if isinstance(v, list):
                    v = Array.toDict(v);

                if self._keyAttribute not in v \
                    and isinstance(k, int) \
                    and not isAssoc:
                    ex = InvalidConfigurationException(
                        'The attribute "{0}" must be set for path "{1}".'
                        ''.format(self._keyAttribute, self.getPath())
                    );
                    ex.setPath(self.getPath());
                    raise ex;
                elif self._keyAttribute in v:
                    k = v[self._keyAttribute];

                    # remove the key attribute when required
                    if self._removeKeyAttribute:
                        del v[self._keyAttribute];

                    # if only "value" is left
                    if 1 == len(v) and 'value' in v:
                        v = v['value'];

                if k in normalized:
                    ex = DuplicateKeyException(
                        'Duplicate key "{0}" for path "{1}".'
                        ''.format(k, self.getPath())
                    );
                    ex.setPath(self.getPath());
                    raise ex;

            self._prototype.setName(k);
            if not self._keyAttribute is None or isAssoc:
                normalized[k] = self._prototype.normalize(v);
            else:
                normalized[i] = self._prototype.normalize(v);

        return normalized;
コード例 #39
0
    def _validate(self, config, name, path):
        """Validates the route configuration.

        @param: dict  config A resource config
        @param string name   The config key
        @param string path   The loaded file path

        @raise InvalidArgumentException If one of the provided config keys is not supported,
                                          something is missing or the combination is nonsense

        """

        if not isinstance(config, dict):
            raise InvalidArgumentException(
                'The definition of "{0}" in "{1}" must be a Json object.'
                ''.format(name, path))

        extraKeys = Array.diff(config.keys(), self.__availableKeys)
        if (extraKeys):
            raise InvalidArgumentException(
                'The routing file "{0}" contains unsupported keys for "{1}": '
                '"{2}". Expected one of: "{3}".'.format(
                    path,
                    name,
                    '", "'.join(extraKeys),
                    '", "'.join(self.__availableKeys),
                ))

        if 'resource' in config and 'path' in config:
            raise InvalidArgumentException(
                'The routing file "{0}" must not specify both the "resource" '
                'key and the "path" key for "{1}". Choose between an import '
                'and a route definition.'.format(path, name))

        if 'resource' in config and 'description' in config:
            raise InvalidArgumentException(
                'The routing file "{0}" must not specify both the "resource" '
                'key and the "description" key for "{1}". Choose between an '
                'import and a route definition.'.format(path, name))

        if 'resource' not in config and 'type' in config:
            raise InvalidArgumentException(
                'The "type" key for the route definition "{0}" in "{1}" is '
                'unsupported. It is only available for imports in combination '
                'with the "resource" key.'.format(name, path))

        if 'resource' not in config and 'path' not in config:
            raise InvalidArgumentException(
                'You must define a "path" for the route "{0}" in file "{1}".'
                ''.format(name, path))

        if 'path' in config and not config['path']:
            raise InvalidArgumentException(
                'The "path" for the route "{0}" in file "{1}" cannot be empty.'
                ''.format(name, path))

        if 'definition' in config:
            if 'arguments' in config['definition']:
                if not isinstance(config['definition']['arguments'],
                                  OrderedDict):
                    raise InvalidArgumentException(
                        'The definition.arguments key should be a JSON object '
                        'in route "{0}" in file "{1}".'
                        ''.format(name, path))
            if 'options' in config['definition']:
                if not isinstance(config['definition']['options'], dict):
                    raise InvalidArgumentException(
                        'The definition.options key should be a JSON object '
                        'in route "{0}" in file "{1}".'
                        ''.format(name, path))
コード例 #40
0
    def _initializeBundles(self):
        """Initializes the data structures related to the bundle management.

         - the bundles property maps a bundle name to the bundle instance,
         - the bundleMap property maps a bundle name to the bundle inheritance
           hierarchy (most derived bundle first).

        @raise LogicException: if two bundles share a common name
        @raise LogicException: if a bundle tries to extend a non-registered
                               bundle
        @raise LogicException: if a bundle tries to extend itself
        @raise LogicException: if two bundles extend the same ancestor
        """
        #  init bundle
        self._bundles = dict()
        topMostBundles = dict()
        directChildren = dict()

        for bundle in self.registerBundles():
            assert isinstance(bundle, BundleInterface)

            name = bundle.getName()
            if name in self._bundles.keys():
                raise LogicException(
                    'Trying to register two bundles with the same name "{0}"'
                    ''.format(name))

            self._bundles[name] = bundle

            parentName = bundle.getParent()
            if parentName:
                if parentName in directChildren.keys():
                    raise LogicException(
                        'Bundle "{0}" is directly extended by two bundles '
                        '"{1}" and "{2}".'
                        ''.format(parentName, name,
                                  directChildren[parentName]))
                if parentName == name:
                    raise LogicException(
                        'Bundle "{0}" can not extend itself.'.format(name))
                directChildren[parentName] = name
            else:
                topMostBundles[name] = bundle

            # look for orphans
            diff = Array.diff(
                list(directChildren.keys()),
                list(self._bundles.keys()),
            )
            if diff:
                raise LogicException(
                    'Bundle "{0}" extends bundle "{1}", which is not registered.'
                    ''.format(directChildren[diff[0]], diff[0]))

            # inheritance
            self._bundleMap = dict()
            for name, bundle in topMostBundles.items():
                bundleMap = [bundle]
                hierarchy = [name]

                while name in directChildren.keys():
                    name = directChildren[name]
                    bundleMap.insert(0, self._bundles[name])
                    hierarchy.append(name)

                for name in hierarchy:
                    self._bundleMap[name] = list(bundleMap)
                    bundleMap.pop()
コード例 #41
0
ファイル: __init__.py プロジェクト: visonforcoding/pymfony
    def get(self, path, default = None, deep = False):
        """Returns a parameter by name.

        @param string  path    The key
        @param mixed   default The default value if the parameter key does not exist
        @param boolean deep    If True, a path like foo[bar] will find deeper items

        @return mixed

        @raise InvalidArgumentException

        @api

        """

        try:
            pos = str(path).index('[');
        except ValueError:
            pos = False;
        if ( not deep or False is pos) :
            if path in self._parameters:
                return self._parameters[path];
            else:
                return default;


        root = str(path)[0:pos];
        if not root in self._parameters :
            return default;


        value = self._parameters[root];
        currentKey = None;
        i = pos - 1;
        for char in range(len(path)):
            i += 1;
            if ('[' == char) :
                if (None is not currentKey) :
                    raise InvalidArgumentException(
                        'Malformed path. Unexpected "[" at position {0}.'
                        ''.format(str(i))
                    );


                currentKey = '';
            elif (']' == char) :
                if (None is currentKey) :
                    raise InvalidArgumentException(
                        'Malformed path. Unexpected "]" at position {0}.'
                        ''.format(str(i))
                    );

                if isinstance(value, list):
                    value = Array.toDict(value, True);
                if not isinstance(value, dict) or currentKey not in value :
                    return default;


                value = value[currentKey];
                currentKey = None;
            else :
                if (None is currentKey) :
                    raise InvalidArgumentException(
                        'Malformed path. Unexpected "{0}" at position {1}.'
                        ''.format(char, str(i))
                    );


                currentKey += char;



        if (None is not currentKey) :
            raise InvalidArgumentException(
                'Malformed path. Path must end with "]".'
            );


        return value;
コード例 #42
0
ファイル: test_types.py プロジェクト: visonforcoding/pymfony
 def testDiffKeyName(self):
     input_array = {0 : '0', 1 : '1', -10 : '-10', 'True' : 1, 'False' : 0};
     boolean_indx_array = {True : 'boolt', False : 'boolf', True : 'boolT', False : 'boolF'};
     expected = {-10 :"-10","True":1,"False":0}
     self.assertEqual(expected, Array.diffKey(input_array, boolean_indx_array));
コード例 #43
0
ファイル: test_types.py プロジェクト: visonforcoding/pymfony
 def testDiffKeyBasic(self):
     array1 = {'blue' : 1, 'red': 2, 'green' : 3, 'purple' : 4};
     array2 = {'green': 5, 'blue' : 6, 'yellow': 7, 'cyan' : 8};
     self.assertEqual({"red":2,"purple":4}, Array.diffKey(array1, array2));