SchemaConverter
a phpmae:Class in JSON
Public PHP Methods
This class has no public methods yet or a problem occurred while retrieving them.
Source Code
<?php use Exception; use ML\IRI\IRI; use ML\JsonLD\JsonLD, ML\JsonLD\Graph, ML\JsonLD\Node; use Symfony\Component\Yaml\Yaml; use CloudObjects\SDK\COIDParser; /** * Implementation for coid://json.co-n.net/SchemaConverter */ class SchemaConverter { const CO = 'coid://cloudobjects.io/'; const JSON = 'coid://json.co-n.net/'; const RDFS = 'http://www.w3.org/2000/01/rdf-schema#'; private $map = [ // For all: 'default' => 'hasDefaultValue', 'format' => 'hasFormat', // For numbers: 'multipleOf' => 'isMultipleOf', 'maximum' => 'hasMaximum', 'exclusiveMaximum' => 'isMaximumExclusive', 'minimum' => 'hasMinimum', 'exclusiveMinimum' => 'isMinimumExclusive', // For strings: 'maxLength' => 'hasMaxLength', 'minLength' => 'hasMinLength', 'pattern' => 'hasPattern', // For arrays: 'maxItems' => 'hasMaxItems', 'minItems' => 'hasMinItems' ]; private $combineMap = [ 'oneOf' => 'isOneOf', 'allOf' => 'isAllOf', 'anyOf' => 'isAnyOf' ]; private function convertElement(array $element, Graph $graph, Node $node, string $rewriteRule = null) { if (isset($element['$ref'])) { // Handle unresolved reference $node->setType($graph->createNode(self::JSON.'ElementWithSchema')); $target = 'jsonpointer:'.$element['$ref'].'-'.$rewriteRule; if (isset($rewriteRule)) { $rewriteRule = explode(' ', $rewriteRule); $reference = $rewriteRule[1]; @preg_match('/'.$rewriteRule[0].'/', $element['$ref'], $matches); for ($i = 0; $i < count($matches); $i++) $reference = str_replace('$'.$i, $matches[$i], $reference); $targetCoid = COIDParser::fromString($reference); if (in_array(COIDParser::getType($targetCoid), [ COIDParser::COID_VERSIONED, COIDParser::COID_UNVERSIONED ])) $target = $reference; } $node->addPropertyValue(self::JSON.'hasSchema', $graph->createNode($target)); return; } // Add title -> rdfs:label if (isset($element['title']) && !empty(trim($element['title']))) $node->setProperty(self::RDFS.'label', $element['title']); // Add description -> rdfs:comment if (isset($element['description']) && !empty(trim($element['description']))) $node->setProperty(self::RDFS.'comment', $element['description']); $types = isset($element['type']) ? (is_array($element['type']) ? $element['type'] : [ $element['type'] ]) : []; // Element without a specified type? -> json:Element if (count($types) == 0) $node->setType($graph->createNode(self::JSON.'Element')); foreach ($types as $t) { switch ($t) { case "string": case "boolean": case "number": case "integer": case "null": // Simple types $name = strtoupper($t[0]).substr($t, 1); $node->addType($graph->createNode(self::JSON.$name)); break; case "object": // Object types are handled recursively if (isset($element['properties'])) { foreach ((array)$element['properties'] as $k => $e) { $newNode = $graph->createNode(); $newNode->setProperty(self::JSON.'hasKey', $k); if (isset($element['required']) && in_array($k, $element['required'])) $newNode->setProperty(self::JSON.'isRequired', 'true'); $this->convertElement((array)$e, $graph, $newNode, $rewriteRule); $node->addPropertyValue(self::JSON.'hasProperty', $newNode); } } $node->setType($graph->createNode(self::JSON.'Object')); break; case "array": $node->setType($graph->createNode(self::JSON.'Array')); if (isset($element['items'])) { $newNode = $graph->createNode(); $this->convertElement((array)$element['items'], $graph, $newNode, $rewriteRule); $node->addPropertyValue(self::JSON.'containsItems', $newNode); } break; default: throw new Exception("Unknown value for 'type': ".$t); } } if (isset($element['enum'])) { // Add enumeration of valid values foreach ((array)$element['enum'] as $enum) $node->addPropertyValue(self::JSON.'allowsValue', $enum); } foreach ($this->map as $key => $propName) { // Go through additional validations if (isset($element[$key])) $node->addPropertyValue(self::JSON.$propName, $element[$key]); } foreach ($this->combineMap as $key => $propName) { // Go through combining if (isset($element[$key]) && is_array($element[$key])) { foreach ($element[$key] as $subschema) { $newNode = $graph->createNode(); $subschema = (array)$subschema; if (isset($element['type']) && !isset($subschema['type'])) $subschema['type'] = $element['type']; $this->convertElement((array)$subschema, $graph, $newNode, $rewriteRule); $node->addPropertyValue(self::JSON.$propName, $newNode); } } } } /** * Converts a JSON schema into a configuration job. * * @param string $data Content of the JSON schema. * @param string $coid The desired COID for the schema. * @param string $rewrite_rule A rule to rewrite references into COIDs. * @param string $audience_coid The desired audience for the API. */ public function convert(string $data, string $coid, string $rewrite_rule, string $audience_coid) { try { $data = Yaml::parse($data); $coidAsIri = COIDParser::fromString($coid); if (!in_array(COIDParser::getType($coidAsIri), [ COIDParser::COID_VERSIONED, COIDParser::COID_UNVERSIONED ])) throw new Exception("Invalid COID for schema!"); $graph = JsonLD::getDocument('{}')->getGraph(); $schema = $graph->createNode((string)$coidAsIri); // Add audience if provided if (isset($audience_coid) && !empty($audience_coid)) { $audienceAsIri = COIDParser::fromString($audience_coid); if (!in_array(COIDParser::getType($audienceAsIri), [ COIDParser::COID_VERSIONED, COIDParser::COID_UNVERSIONED ])) throw new Exception("Invalid COID for audience parameter!"); $audienceNode = $graph->createNode($audience_coid); $schema->setProperty(self::CO.'isVisibleTo', $audienceNode); $schema->setProperty(self::CO.'permitsUsageTo', $audienceNode); } $this->convertElement($data, $graph, $schema, $rewrite_rule); // Return compact JSON-LD response $context = (object)[ 'json' => self::JSON, 'rdfs' => self::RDFS ]; return [ 'success' => true, 'configuration_job' => JsonLD::compact($graph->toJsonLd(), $context) ]; } catch (Exception $e) { return [ 'success' => false, 'error_message' => $e->getMessage() ]; } } /** * Parses JSON schema data and returns a graph node. * @param array $data JSON Schema * @param string $id The optional COID, URI, or BNode ID for the schema * @param Graph $graph Adds the schema to this graph * @param string|null $rewrite_rule A rule to rewrite references into COIDs. * * @return Node */ public function convertToNode(array $data, string $id = null, Graph $graph, string $rewrite_rule = null) { if (isset($id) && $graph->getNode($id) != null) return $graph->getNode($id); // do not create if already exists in graph $node = isset($id) ? $graph->createNode($id, true) : $graph->createNode(); $this->convertElement($data, $graph, $node, $rewrite_rule); if (count($node->getProperties()) == 2 && $node->getType()->getId() == 'coid://json.co-n.net/ElementWithSchema') { // Remove an unnecessary layer of redirection $targetNode = $node->getProperty('coid://json.co-n.net/hasSchema'); $graph->removeNode($node); return $targetNode; } return $node; } }
Meta
- URI / COID
- coid://json.co-n.net/SchemaConverter content_copy
- Revision
- 4-b03d77fdbb0adbdc502cc6f84f34f587 content_copy
- Short ID
- json:SchemaConverter content_copy
- Reference URL
- https://coid.link/json.co-n.net/SchemaConverter content_copy
- Last updated
- 2021-10-02 14:29 (UTC)
- Created at
- 2019-12-13 16:30 (UTC)
RDF
Objects in this namespace
- JSON
- Address
- Array
- Boolean
- Calendar
- Card
- Element
- ElementWithSchema
- Geo
- Integer
- Null
- Number
- Object
- Problem
- Reference
- SchemaConverter
- SchemaExporter
- SchemaYamlExporter
- String
- allowsValue
- containsItems
- hasDefaultValue
- hasFormat
- hasKey
- hasMaxItems
- hasMaxLength
- hasMaximum
- hasMinItems
- hasMinLength
- hasMinimum
- hasPattern
- hasProperty
- hasSchema
- isAllOf
- isAnyOf
- isMaximumExclusive
- isMinimumExclusive
- isMultipleOf
- isOneOf
- isRequired