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))
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'")
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'")
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()
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))
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()
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))
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))
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
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