| 389 | |
| 390 | |
| 391 | class Classification(Facet): |
| 392 | def __init__(self, value=None, system=None, uri=None, cardinality: Cardinality = "required", instructions=None): |
| 393 | self.parameters = ["value", "system", "@uri", "@cardinality", "@instructions"] |
| 394 | self.applicability_templates = [ |
| 395 | "Data having a {system} reference of {value}", |
| 396 | "Data classified using {system}", |
| 397 | "Data classified as {value}", |
| 398 | ] |
| 399 | self.requirement_templates = [ |
| 400 | "Shall have a {system} reference of {value}", |
| 401 | "Shall be classified using {system}", |
| 402 | "Shall be classified as {value}", |
| 403 | ] |
| 404 | self.prohibited_templates = [ |
| 405 | "Shall not have a {system} reference of {value}", |
| 406 | "Shall not be classified using {system}", |
| 407 | "Shall not be classified as {value}", |
| 408 | ] |
| 409 | |
| 410 | super().__init__(value, system, uri, cardinality, instructions) |
| 411 | |
| 412 | def filter( |
| 413 | self, ifc_file: ifcopenshell.file, elements: Optional[list[ifcopenshell.entity_instance]] |
| 414 | ) -> list[ifcopenshell.entity_instance]: |
| 415 | if isinstance(elements, list): |
| 416 | return super().filter(ifc_file, elements) |
| 417 | return ifc_file.by_type("IfcObjectDefinition") |
| 418 | |
| 419 | def __call__(self, inst: ifcopenshell.entity_instance, logger: Optional[Logger] = None) -> ClassificationResult: |
| 420 | leaf_references = ifcopenshell.util.classification.get_references(inst) |
| 421 | |
| 422 | references = leaf_references.copy() |
| 423 | for leaf_reference in leaf_references: |
| 424 | references.update(ifcopenshell.util.classification.get_inherited_references(leaf_reference)) |
| 425 | |
| 426 | is_pass = bool(references) |
| 427 | reason = None |
| 428 | |
| 429 | if not is_pass: |
| 430 | if self.cardinality == "optional": |
| 431 | return ClassificationResult(True) |
| 432 | reason = {"type": "NOVALUE"} |
| 433 | |
| 434 | if is_pass and self.value: |
| 435 | values = [getattr(r, "Identification", getattr(r, "ItemReference", None)) for r in references] |
| 436 | is_pass = any([self.value == v for v in values]) |
| 437 | if not is_pass: |
| 438 | reason = {"type": "VALUE", "actual": values} |
| 439 | |
| 440 | if is_pass: |
| 441 | classifications = filter(None, (ifcopenshell.util.classification.get_classification(r) for r in references)) |
| 442 | systems = [r.Name for r in classifications] |
| 443 | is_pass = any([self.system == s for s in systems]) |
| 444 | if not is_pass: |
| 445 | reason = {"type": "SYSTEM", "actual": systems} |
| 446 | |
| 447 | if self.cardinality == "prohibited": |
| 448 | return ClassificationResult(not is_pass, {"type": "PROHIBITED"}) |
no outgoing calls