Beispiel #1
0
    def validate(self):
        super(TitledTreeNode, self).validate()

        if any((c in '-') for c in self.title_group.primary_title("en")):
            raise InputError("Primary English title may not contain hyphens.")

        if not self.default and not self.sharedTitle and not self.get_titles():
            raise IndexSchemaError(
                "Schema node {} must have titles, a shared title node, or be default"
                .format(self))

        if self.default and (self.get_titles() or self.sharedTitle):
            raise IndexSchemaError(
                "Schema node {} - default nodes can not have titles".format(
                    self))

        if not self.default and not self.primary_title("en"):
            raise IndexSchemaError(
                "Schema node {} missing primary English title".format(self))

        if self.has_children() and len([c for c in self.children if c.default
                                        ]) > 1:
            raise IndexSchemaError(
                "Schema Structure Node {} has more than one default child.".
                format(self.key))

        if self.sharedTitle and Term().load({
                "name": self.sharedTitle
        }).titles != self.get_titles():
            raise IndexSchemaError(
                "Schema node {} with sharedTitle can not have explicit titles".
                format(self))
Beispiel #2
0
def deserialize_tree(serial=None, **kwargs):
    """
    Build a :class:`TreeNode` tree from serialized form.  Called recursively.
    :param serial: The serialized form of the subtree
    :param kwargs: keyword argument 'struct_class' specifies the class to use as the default structure node class.
    Other keyword arguments are passed through to the node constructors.
    :return: :class:`TreeNode`
    """
    klass = None
    if serial.get("nodeType"):
        try:
            klass = globals()[serial.get("nodeType")]
        except KeyError:
            raise IndexSchemaError("No matching class for nodeType {}".format(
                serial.get("nodeType")))

    if serial.get("nodes"):
        #Structure class - use explicitly defined 'nodeType', code overide 'struct_class', or default SchemaNode
        struct_class = klass or kwargs.get("struct_class", SchemaNode)
        return struct_class(serial, **kwargs)
    elif klass:
        return klass(serial, **kwargs)
    else:
        raise IndexSchemaError(
            "Schema node has neither 'nodes' nor 'nodeType'")
Beispiel #3
0
    def validate(self):
        super(SchemaNode, self).validate()

        if not getattr(self, "key", None):
            raise IndexSchemaError("Schema node missing key")

        if self.default and self.key != "default":
            raise IndexSchemaError("'default' nodes need to have key name 'default'")
Beispiel #4
0
 def validate(self):
     if getattr(self, "depth", None) is None:
         raise IndexSchemaError("Missing Parameter 'depth' in {}".format(self.__class__.__name__))
     if self.depth == 0:
         TitledTreeNode.validate(self)  # Skip over NumberedTitledTreeNode validation, which requires fields we don't have
     elif self.depth > 0:
         for k in ["addressTypes", "sectionNames", "refs"]:
             if getattr(self, k, None) is None:
                 raise IndexSchemaError("Missing Parameter '{}' in {}".format(k, self.__class__.__name__))
         super(ArrayMapNode, self).validate()
Beispiel #5
0
 def validate(self):
     super(NumberedTitledTreeNode, self).validate()
     for p in ["addressTypes", "sectionNames"]:
         if len(getattr(self, p)) != self.depth:
             raise IndexSchemaError(
                 "Parameter {} in {} {} does not have depth {}".format(
                     p, self.__class__.__name__, self.key, self.depth))
Beispiel #6
0
 def validate(self):
     for k in self.required_param_keys:
         if getattr(self, k, None) is None:
             raise IndexSchemaError("Missing Parameter '{}' in {}".format(
                 k, self.__class__.__name__))
     for c in self.children:
         c.validate()
Beispiel #7
0
 def _process_terms(self):
     if self.sharedTitle:
         try:
             term = Term().load({"name": self.sharedTitle})
             self.title_group = term.title_group
         except Exception, e:
             raise IndexSchemaError("Failed to load term named {}. {}".format(self.sharedTitle, e))
Beispiel #8
0
    def _init_address_classes(self):
        self._addressTypes = []
        for i, atype in enumerate(getattr(self, "addressTypes", [])):
            try:
                klass = globals()["Address" + atype]
            except KeyError:
                raise IndexSchemaError("No matching class for addressType {}".format(atype))

            if i == 0 and getattr(self, "lengths", None) and len(self.lengths) > 0:
                self._addressTypes.append(klass(i, self.lengths[i]))
            else:
                self._addressTypes.append(klass(i))
Beispiel #9
0
    def add_title(self,
                  text,
                  lang,
                  primary=False,
                  replace_primary=False,
                  presentation="combined"):
        """
        :param text: Text of the title
        :param language:  Language code of the title (e.g. "en" or "he")
        :param primary: Is this a primary title?
        :param replace_primary: must be true to replace an existing primary title
        :param presentation: The "presentation" field of a title indicates how it combines with earlier titles. Possible values:
            "combined" - in referencing this node, earlier titles nodes are prepended to this one (default)
            "alone" - this node is reference by this title alone
            "both" - this node is addressable both in a combined and a alone form.
        :return: the object
        """
        if any([
                t for t in self.titles
                if t["text"] == text and t["lang"] == lang
        ]):  #already there
            if not replace_primary:
                return
            else:  #update this title as primary: remove it, then re-add below
                self.remove_title(text, lang)
        d = {"text": text, "lang": lang}

        if primary:
            d["primary"] = True

        if presentation == "alone" or presentation == "both":
            d["presentation"] = presentation

        has_primary = any(
            [x for x in self.titles if x["lang"] == lang and x.get("primary")])
        if has_primary and primary:
            if not replace_primary:
                raise IndexSchemaError(
                    "Node {} already has a primary title.".format(
                        self.primary_title()))

            old_primary = self.primary_title(lang)
            self.titles = [
                t for t in self.titles
                if t["lang"] != lang or not t.get("primary")
            ]
            self.titles.append({"text": old_primary, "lang": lang})
            self._primary_title[lang] = None

        self.titles.append(d)
        return self
Beispiel #10
0
    def title_dict(self, lang="en", baselist=None):
        """
        Recursive function that generates a map from title to node
        :param node: the node to start from
        :param lang: "en" or "he"
        :param baselist: list of starting strings that lead to this node
        :return: map from title to node
        """
        if baselist is None:
            baselist = []

        title_dict = {}
        thisnode = self

        this_node_titles = [
            title["text"] for title in self.get_titles()
            if title["lang"] == lang and title.get("presentation") != "alone"
        ]
        if (not len(this_node_titles)) and (not self.is_default()):
            error = u'No "{}" title found for schema node: "{}"'.format(
                lang, self.key)
            error += u', child of "{}"'.format(
                self.parent.full_title("en")) if self.parent else ""
            raise IndexSchemaError(error)
        if baselist:
            node_title_list = [
                baseName + sep + title for baseName in baselist
                for sep in self.title_separators for title in this_node_titles
            ]
        else:
            node_title_list = this_node_titles

        alone_node_titles = [
            title["text"] for title in self.get_titles()
            if title["lang"] == lang and title.get("presentation") == "alone"
            or title.get("presentation") == "both"
        ]
        node_title_list += alone_node_titles

        if self.has_children():
            for child in self.children:
                if child.is_default():
                    thisnode = child
                else:
                    title_dict.update(child.title_dict(lang, node_title_list))

        for title in node_title_list:
            title_dict[title] = thisnode

        return title_dict