{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "definitions": {
    "id": {
      "description": "A globally unique identifier.",
      "type": "string",
      "pattern": "^[_a-zA-Z]{1}[_a-zA-Z0-9.-]*$"
    },
    "revision": {
      "description": "A globally unique revision tag with one or multiple blocks with alphanumeric characters separated by a special character [.:,;/-]. Sequential as well as branching/merging notations are possible.",
      "type": "string",
      "pattern": "^(?:[0-9a-zA-Z]+[.:,;/-])*[0-9a-zA-Z]+$"
    },
    "replaces": {
      "description": "For change and configuration management; the first revision has 0 entries, a simple modification has 1 entry and the result of a merge has 2 entries.",
      "type": "array",
      "maxItems": 2,
      "uniqueItems": true,
      "items": {
        "$ref": "#/definitions/revision"
      }
    },
    "key": {
      "description": "A unique key for a particular revision of an identifiable item, e.g. of a resource.",
      "oneOf": [
        {
          "description": "A string with a valid identifier; where the last revision (i.e. revision=0) is implied.",
          "$ref": "#/definitions/id"
        },
        {
          "description": "A key consisting of a globally unique identifier and a revision. No or an undefined revision means the latest revision of the identified item.",
          "type": "object",
          "properties": {
            "id": {
              "$ref": "#/definitions/id"
            },
            "revision": {
              "$ref": "#/definitions/revision"
            }
          },
          "required": ["id"]
        }
      ]
    },
    "dateTime": {
      "description": "An ISO-8601 dateTime string. For reduced accuracy, any number of values may be dropped, but only from right to left.",
      "type": "string",
      "format": "date-time"
    },
    "icon": {
      "description": "A symbol for display as a prefix to titles; applicable to all instances of the class. Is usually a XML-encoded UTF-8 symbol, can be an URL or dataURL.",
      "type": "string"
    },
    "instantiation": {
      "description": "Indicates whether an instance of the class is created automatically, manually or both. All is allowed, if the property is omitted. The class is abstract and cannot be instantiated, if the property list is present, but empty.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "string",
        "enum": ["auto", "user"]
      }
    },
    "alternativeIds": {
      "description": "The list of consolidated items which can be used in case a consolidated item shall be updated.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "description": "A list of pointers to resources resp statements which have been merged to this one.",
        "oneOf": [
          {
            "description": "A string with a valid identifier of a model-element; where the last revision (i.e. revision=0) is implied.",
            "$ref": "#/definitions/id"
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "description": "A string with a valid identifier of a model-element",
                "$ref": "#/definitions/id"
              },
              "revision": {
                "$ref": "#/definitions/revision"
              },
              "project": {
                "description": "A string with a valid project identifier",
                "$ref": "#/definitions/id"
              }
            },
            "required": ["id"]
          }
        ]
      }
    },
    "value": {
      "description": "A property value according to the property class.",
      "oneOf": [
        {
          "description": "A string containing some text or a special value.",
          "type": "string"
        },
        {
          "description": "A list of items with text and language properties. Thus, the information can be given in multiple languages.",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "object",
            "properties": {
              "text": {
                "description": "A string containing some text.",
                "type": "string"
              },
              "language": {
                "description": "An IETF language tag such as 'en', 'en-US, 'fr' or 'de'.",
                "type": "string"
              }
            },
            "additionalProperties": false,
            "required": ["text", "language"]
          }
        }
      ]
    },
    "nodes": {
      "description": "A list of pointers to resources; may be nested to build a tree, i.e. a hierarchy of pointers.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/definitions/id"
          },
          "title": {
            "$ref": "#/definitions/value",
            "description": "The node's label; if missing, the title of the referenced resource is applied."
          },
          "description": {
            "$ref": "#/definitions/value"
          },
          "resource": {
            "description": "The pointer to the resource to be displayed at this position.",
            "$ref": "#/definitions/key"
          },
          "nodes": {
            "description": "The next hierarchy level.",
            "$ref": "#/definitions/nodes"
          },
          "revision": {
            "$ref": "#/definitions/revision"
          },
          "replaces": {
            "$ref": "#/definitions/replaces"
          },
          "changedAt": {
            "$ref": "#/definitions/dateTime"
          },
          "changedBy": {
            "type": "string"
          }
        },
        "required": ["id", "resource", "changedAt"]
      }
    },
    "properties": {
      "description": "A list of properties of a resource or statement.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/definitions/id"
          },
          "title": {
            "$ref": "#/definitions/value",
            "description": "The property's label; if missing, the title of the property's class is applied."
          },
          "description": {
            "$ref": "#/definitions/value"
          },
          "class": {
            "$ref": "#/definitions/key",
            "description": "Must be a member of propertyClasses. In addition, it must be listed in the propertyClasses of the parent's class."
          },
          "value": {
            "$ref": "#/definitions/value",
            "description": "If the value is unknown, omit the whole property. By default, the class' value applies."
          },
          "revision": {
            "$ref": "#/definitions/revision"
          },
          "replaces": {
            "$ref": "#/definitions/replaces"
          },
          "changedAt": {
            "$ref": "#/definitions/dateTime",
            "description": "Without change information, the parent's change information applies."
          },
          "changedBy": {
            "type": "string"
          }
        },
        "required": ["class", "value"]
      }
    }
  },
  "description": "The Specification Integration Facility (SpecIF) integrates partial system models from different methods and tools in a semantic net. Collaborators shall browse, search and audit engineering results in a common context. Also, the exchange of model information between organizations and tools is facilitated. SpecIF represents the visible, i.e. the diagrams and the text, as well as the semantics of system specifications.",
  "id": "http://specif.de/v1.0/schema#",
  "properties": {
    "$schema": {
      "type": "string",
      "format": "uri",
      "pattern": "^https?:\\/\\/(specif\\.de\\/v1\\.0\\/schema|.+\\/specif-1\\.0)\\.json$",
      "description": "An absolute URL pointing to this SpecIF schema."
    },
    "id": {
      "$ref": "#/definitions/id"
    },
    "title": {
      "$ref": "#/definitions/value"
    },
    "description": {
      "$ref": "#/definitions/value"
    },
    "isExtension": {
      "type": "boolean",
      "description": "Indicates that the project is not schema-compliant on its own; by default the value is 'false'. Of course, it is expected that once extended the project is schema-compliant."
    },
    "generator": {
      "type": "string"
    },
    "generatorVersion": {
      "type": "string"
    },
    "rights": {
      "type": "object",
      "properties": {
        "title": {
          "type": "string"
        },
        "type": {
          "type": "string"
        },
        "url": {
          "type": "string",
          "format": "uri"
        }
      },
      "required": ["title", "type", "url"]
    },
    "createdAt": {
      "$ref": "#/definitions/dateTime"
    },
    "createdBy": {
      "description": "The creator of the SpecIF data-set (file). If specified, at least an e-mail address must be given.",
      "type": "object",
      "properties": {
        "familyName": {
          "type": "string"
        },
        "givenName": {
          "type": "string"
        },
        "org": {
          "type": "object",
          "properties": {
            "organizationName": {
              "type": "string"
            }
          },
          "required": ["organizationName"]
        },
        "email": {
          "type": "object",
          "properties": {
            "type": {
              "type": "string"
            },
            "value": {
              "type": "string",
              "format": "email"
            }
          },
          "required": ["value"]
        }
      },
      "required": ["email"]
    },
    "language": {
      "description": "An IETF language tag such as 'en', 'en-US, 'fr' or 'de' showing the used language of simple property values. Is superseded by a resource's, statement's or property's language value.",
      "type": "string"
    },
    "dataTypes": {
      "description": "The base data types for use by property class definitions.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "title": "Data-type 'Boolean' or 'dateTime'",
                "description": "The corresponding definition in https://www.w3.org/TR/xmlschema-2/ applies.",
                "enum": ["xs:boolean", "xs:dateTime"]
              },
              "id": {
                "$ref": "#/definitions/id"
              },
              "title": {
                "$ref": "#/definitions/value"
              },
              "description": {
                "$ref": "#/definitions/value"
              },
              "revision": {
                "$ref": "#/definitions/revision"
              },
              "replaces": {
                "$ref": "#/definitions/replaces"
              },
              "changedAt": {
                "$ref": "#/definitions/dateTime"
              },
              "changedBy": {
                "type": "string"
              }
            },
            "additionalProperties": false,
            "required": ["id", "title", "type", "changedAt"]
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "title": "Data-type 'Integer'",
                "description": "The corresponding definition in https://www.w3.org/TR/xmlschema-2/ applies.",
                "enum": ["xs:integer"]
              },
              "id": {
                "$ref": "#/definitions/id"
              },
              "title": {
                "$ref": "#/definitions/value"
              },
              "description": {
                "$ref": "#/definitions/value"
              },
              "minInclusive": {
                "type": "number",
                "title": "Minimum Value of a Number",
                "description": "Optional use by dataTypes 'xs:integer' and 'xs:double'."
              },
              "maxInclusive": {
                "type": "number",
                "title": "Maximum Value of a Number",
                "description": "Optional use by dataTypes 'xs:integer' and 'xs:double'."
              },
              "revision": {
                "$ref": "#/definitions/revision"
              },
              "replaces": {
                "$ref": "#/definitions/replaces"
              },
              "changedAt": {
                "$ref": "#/definitions/dateTime"
              },
              "changedBy": {
                "type": "string"
              }
            },
            "additionalProperties": false,
            "required": ["id", "title", "type", "changedAt"]
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "title": "Data-type 'Double'",
                "description": "The corresponding definition in https://www.w3.org/TR/xmlschema-2/ applies.",
                "enum": ["xs:double"]
              },
              "id": {
                "$ref": "#/definitions/id"
              },
              "title": {
                "$ref": "#/definitions/value"
              },
              "description": {
                "$ref": "#/definitions/value"
              },
              "fractionDigits": {
                "type": "integer",
                "title": "Number of fraction digits of a Decimal Number",
                "description": "Optional use by dataType 'xs:double', indicates the number of decimals.",
                "minimum": 1
              },
              "minInclusive": {
                "type": "number",
                "title": "Minimum Value of a Number",
                "description": "Optional use by dataTypes 'xs:integer' and 'xs:double'."
              },
              "maxInclusive": {
                "type": "number",
                "title": "Maximum Value of a Number",
                "description": "Optional use by dataTypes 'xs:integer' and 'xs:double'."
              },
              "revision": {
                "$ref": "#/definitions/revision"
              },
              "replaces": {
                "$ref": "#/definitions/replaces"
              },
              "changedAt": {
                "$ref": "#/definitions/dateTime"
              },
              "changedBy": {
                "type": "string"
              }
            },
            "additionalProperties": false,
            "required": ["id", "title", "type", "changedAt"]
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "title": "Data-type 'String' or 'Formatted Text'",
                "description": "The corresponding definition in https://www.w3.org/TR/xmlschema-2/ resp. https://www.w3.org/TR/xhtml1/ applies.",
                "enum": ["xs:string", "xhtml"]
              },
              "id": {
                "$ref": "#/definitions/id"
              },
              "title": {
                "$ref": "#/definitions/value"
              },
              "description": {
                "$ref": "#/definitions/value"
              },
              "maxLength": {
                "type": "integer",
                "title": "Maximum String Length",
                "description": "Optional use by dataTypes 'xs:string' and 'xhtml'.",
                "minimum": 0
              },
              "revision": {
                "$ref": "#/definitions/revision"
              },
              "replaces": {
                "$ref": "#/definitions/replaces"
              },
              "changedAt": {
                "$ref": "#/definitions/dateTime"
              },
              "changedBy": {
                "type": "string"
              }
            },
            "additionalProperties": false,
            "required": ["id", "title", "type", "changedAt"]
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "title": "Data-type 'Enumeration'",
                "description": "The corresponding definition in https://www.w3.org/TR/xmlschema-2/ applies.",
                "enum": ["xs:enumeration"]
              },
              "id": {
                "$ref": "#/definitions/id"
              },
              "title": {
                "$ref": "#/definitions/value"
              },
              "description": {
                "$ref": "#/definitions/value"
              },
              "values": {
                "type": "array",
                "title": "Enumerated Values",
                "description": "Mandatory use by dataType 'xs:enumeration'. If 'multiple' is true 0..n options may be selected, otherwise exactly one must be selected.",
                "uniqueItems": true,
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "$ref": "#/definitions/id"
                    },
                    "value": {
                      "$ref": "#/definitions/value"
                    }
                  },
                  "required": ["id", "value"]
                }
              },
              "multiple": {
                "type": "boolean",
                "description": "Optional use by dataType 'xs:enumeration'. Indicates whether multiple values can be chosen; by default the value is 'false'."
              },
              "revision": {
                "$ref": "#/definitions/revision"
              },
              "replaces": {
                "$ref": "#/definitions/replaces"
              },
              "changedAt": {
                "$ref": "#/definitions/dateTime"
              },
              "changedBy": {
                "type": "string"
              }
            },
            "additionalProperties": false,
            "required": ["id", "title", "type", "changedAt"]
          }
        ]
      }
    },
    "propertyClasses": {
      "description": "Class definition of a property for resources or statements. Is a sub-element of the respective resourceClass or statementClass. If no revision or change information is specified, the respective values of the parent element apply.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/definitions/id"
          },
          "title": {
            "$ref": "#/definitions/value"
          },
          "description": {
            "$ref": "#/definitions/value"
          },
          "dataType": {
            "$ref": "#/definitions/key",
            "description": "Must be a member of dataTypes."
          },
          "multiple": {
            "type": "boolean",
            "description": "Optional use by a propertyClass with dataType 'xs:enumeration'. Indicates whether multiple values can be chosen. If omitted, the 'multiple' property of the dataType applies; by default the value is 'false'."
          },
          "value": {
            "$ref": "#/definitions/value",
            "description": "An optional default value in case the instantiated resource's or statement's property is missing."
          },
          "revision": {
            "$ref": "#/definitions/revision"
          },
          "replaces": {
            "$ref": "#/definitions/replaces"
          },
          "changedAt": {
            "$ref": "#/definitions/dateTime"
          },
          "changedBy": {
            "type": "string"
          }
        },
        "required": ["id", "title", "dataType", "changedAt"]
      }
    },
    "resourceClasses": {
      "description": "The class definitions for resources.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/definitions/id"
          },
          "title": {
            "$ref": "#/definitions/value"
          },
          "description": {
            "$ref": "#/definitions/value"
          },
          "extends": {
            "$ref": "#/definitions/key",
            "description": "Must be a member of resourceClasses."
          },
          "icon": {
            "$ref": "#/definitions/icon"
          },
          "isHeading": {
            "type": "boolean"
          },
          "instantiation": {
            "$ref": "#/definitions/instantiation"
          },
          "propertyClasses": {
            "type": "array",
            "description": "A collection of keys of eligible property classes",
            "minItems": 0,
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/key",
              "description": "Must be a member of propertyClasses."
            }
          },
          "revision": {
            "$ref": "#/definitions/revision"
          },
          "replaces": {
            "$ref": "#/definitions/replaces"
          },
          "changedAt": {
            "$ref": "#/definitions/dateTime"
          },
          "changedBy": {
            "type": "string"
          }
        },
        "required": ["id", "title", "changedAt"]
      }
    },
    "statementClasses": {
      "description": "The class definitions for statements in subject-predicate-object statements, where subject and object are resources.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/definitions/id"
          },
          "title": {
            "$ref": "#/definitions/value"
          },
          "description": {
            "$ref": "#/definitions/value"
          },
          "extends": {
            "$ref": "#/definitions/key",
            "description": "Must be a member of statementClasses."
          },
          "icon": {
            "$ref": "#/definitions/icon"
          },
          "instantiation": {
            "$ref": "#/definitions/instantiation"
          },
          "isUndirected": {
            "type": "boolean",
            "description": "Indicates that an instance's subject and object are equivalent and can be exchanged without changing its meaning. Is superseded by a statement's definition."
          },
          "propertyClasses": {
            "type": "array",
            "description": "A collection of keys of eligible property classes",
            "minItems": 0,
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/key",
              "description": "Must be a member of propertyClasses."
            }
          },
          "subjectClasses": {
            "type": "array",
            "title": "Resource and statement classes eligible as subject",
            "description": "A collection of id's of eligible resource and statement classes; if 'subjectClasses' is missing, all resource or statement classes are eligible.",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/key",
              "description": "Must be a member of resourceClasses or statementClasses."
            }
          },
          "objectClasses": {
            "type": "array",
            "title": "Resource and statement classes eligible as object",
            "description": "A collection of id's of eligible resource and statement classes; if 'objectClasses' is missing, all resource or statement classes are eligible.",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/key",
              "description": "Must be a member of resourceClasses or statementClasses."
            }
          },
          "revision": {
            "$ref": "#/definitions/revision"
          },
          "replaces": {
            "$ref": "#/definitions/replaces"
          },
          "changedAt": {
            "$ref": "#/definitions/dateTime"
          },
          "changedBy": {
            "type": "string"
          }
        },
        "required": ["id", "title", "changedAt"]
      }
    },
    "resources": {
      "description": "The resources such as diagrams, model elements or requirements.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/definitions/id"
          },
          "title": {
            "$ref": "#/definitions/value"
          },
          "description": {
            "$ref": "#/definitions/value"
          },
          "class": {
            "$ref": "#/definitions/key",
            "description": "Must be a member of resourceClasses."
          },
          "language": {
            "description": "An IETF language tag such as 'en', 'en-US, 'fr' or 'de' showing the used language of simple property values. Is superseded by a property's language value.",
            "type": "string"
          },
          "properties": {
            "$ref": "#/definitions/properties"
          },
          "revision": {
            "$ref": "#/definitions/revision"
          },
          "replaces": {
            "$ref": "#/definitions/replaces"
          },
          "alternativeIds": {
            "$ref": "#/definitions/alternativeIds"
          },
          "changedAt": {
            "$ref": "#/definitions/dateTime"
          },
          "changedBy": {
            "type": "string"
          }
        },
        "required": ["id", "title", "class", "changedAt"]
      }
    },
    "statements": {
      "description": "Subject-predicate-Object statements, where subject and object are resources. In other terms, statements are directed relations between two resources building a semantic net.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/definitions/id"
          },
          "title": {
            "$ref": "#/definitions/value",
            "description": "The statement's appelation; if missing, the statementClass' title applies."
          },
          "description": {
            "$ref": "#/definitions/value"
          },
          "class": {
            "$ref": "#/definitions/key",
            "description": "Must be a member of statementClasses."
          },
          "subject": {
            "$ref": "#/definitions/key",
            "description": "Must be a member of resources or statements."
          },
          "object": {
            "$ref": "#/definitions/key",
            "description": "Must be a member of resources or statements."
          },
          "language": {
            "description": "An IETF language tag such as 'en', 'en-US, 'fr' or 'de' showing the used language of simple property values. Is superseded by a property's language value.",
            "type": "string"
          },
          "properties": {
            "$ref": "#/definitions/properties"
          },
          "revision": {
            "$ref": "#/definitions/revision"
          },
          "replaces": {
            "$ref": "#/definitions/replaces"
          },
          "alternativeIds": {
            "$ref": "#/definitions/alternativeIds"
          },
          "changedAt": {
            "$ref": "#/definitions/dateTime"
          },
          "changedBy": {
            "type": "string"
          }
        },
        "required": ["id", "class", "subject", "object", "changedAt"]
      }
    },
    "hierarchies": {
      "description": "A list of hierarchies with pointers to resources; may be nested to build a tree, i.e. a hierarchy of pointers.",
      "$ref": "#/definitions/nodes"
    },
    "files": {
      "description": "A list of files being referenced by a resource's or statement's property of dataType XHTML using an <object> tag. A file should have a media type as defined by IANA (see below).",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/definitions/id"
          },
          "title": {
            "description": "In case of a file, the title is the absolute or relative URL.",
            "$ref": "#/definitions/value"
          },
          "description": {
            "$ref": "#/definitions/value"
          },
          "type": {
            "description": "The file's media type (formerly MIME-type) according to https://www.iana.org/assignments/media-types/media-types.xhtml.",
            "type": "string"
          },
          "revision": {
            "$ref": "#/definitions/revision"
          },
          "replaces": {
            "$ref": "#/definitions/replaces"
          },
          "changedAt": {
            "$ref": "#/definitions/dateTime"
          },
          "changedBy": {
            "type": "string"
          }
        },
        "required": ["id", "title", "type", "changedAt"]
      }
    }
  },
  "required": [
    "$schema",
    "id",
    "title",
    "resourceClasses",
    "statementClasses",
    "resources",
    "statements",
    "hierarchies"
  ],
  "title": "JSON-Schema for SpecIF v1.0",
  "type": "object"
}
