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