Example #1
0
    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;
Example #2
0
    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
Example #3
0
    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);
Example #4
0
    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)
Example #5
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;
Example #6
0
    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
Example #7
0
    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;
Example #8
0
    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;
Example #9
0
    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
Example #10
0
    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;
Example #11
0
    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
Example #12
0
    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;
Example #13
0
    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
Example #14
0
    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;
Example #15
0
    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;
Example #16
0
    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