Update to latest spec changes.

This commit is contained in:
Dave Longley 2012-04-27 16:18:05 -04:00
parent 0e6040c9e1
commit 2135f34a72
1 changed files with 97 additions and 73 deletions

View File

@ -838,7 +838,7 @@ class JsonLdProcessor {
// compact subject references
if(self::_isSubjectReference($element)) {
$type = self::getContextValue($ctx, $property, '@type');
if($type === '@id') {
if($type === '@id' || $property === '@graph') {
$element = $this->_compactIri($ctx, $element->{'@id'});
return $element;
}
@ -1000,14 +1000,9 @@ class JsonLdProcessor {
'jsonld.SyntaxError', array('value' => $value));
}
// @type must be a string, array of strings, or an empty JSON object
if($prop === '@type' &&
!(is_string($value) || self::_isArrayOfStrings($value) ||
self::_isEmptyObject($value))) {
throw new JsonLdException(
'Invalid JSON-LD syntax; "@type" value must a string, an array ' +
'of strings, or an empty object.',
'jsonld.SyntaxError', array('value' => $value));
// validate @type value
if($prop === '@type') {
$this->_validateTypeValue($value);
}
// @graph must be an array or an object
@ -1060,6 +1055,25 @@ class JsonLdProcessor {
}
}
// optimize away @id for @type
if($prop === '@type') {
if(self::_isSubjectReference($value)) {
$value = $value->{'@id'};
}
else if(is_array($value)) {
$val = array();
foreach($value as $v) {
if(self::_isSubjectReference($v)) {
$val[] = $v->{'@id'};
}
else {
$val[] = $v;
}
}
$value = $val;
}
}
// add value, use an array if not @id, @type, @value, or @language
$use_array = !($prop === '@id' || $prop === '@type' ||
$prop === '@value' || $prop === '@language');
@ -1363,8 +1377,8 @@ class JsonLdProcessor {
// get type definition from context
$type = self::getContextValue($ctx, $property, '@type');
// do @id expansion
if($type === '@id') {
// do @id expansion (automatic for @graph)
if($type === '@id' || $prop === '@graph') {
$rval = (object)array('@id' => $this->_expandTerm($ctx, $value, $base));
}
// other type
@ -2427,11 +2441,6 @@ class JsonLdProcessor {
return $iri;
}
// compact rdf:type
if($iri === self::RDF_TYPE) {
return '@type';
}
// term is a keyword
if(self::_isKeyword($iri)) {
// return alias if available
@ -2656,8 +2665,12 @@ class JsonLdProcessor {
'jsonld.SyntaxError', array('context' => $ctx));
}
// expand @id to full IRI
$id = $this->_expandContextIri($active_ctx, $ctx, $id, $base, $defined);
// expand @id if it is not @type
if($id !== '@type') {
// expand @id to full IRI
$id = $this->_expandContextIri(
$active_ctx, $ctx, $id, $base, $defined);
}
// add @id to mapping
$mapping->{'@id'} = $id;
@ -3022,24 +3035,24 @@ class JsonLdProcessor {
/**
* Returns whether or not the given value is a keyword (or a keyword alias).
*
* @param string $value the value to check.
* @param string $v the value to check.
* @param stdClass [$ctx] the active context to check against.
*
* @return bool true if the value is a keyword, false if not.
*/
protected static function _isKeyword($value, $ctx=null) {
protected static function _isKeyword($v, $ctx=null) {
if($ctx !== null) {
if(property_exists($ctx->keywords, $value)) {
if(property_exists($ctx->keywords, $v)) {
return true;
}
foreach($ctx->keywords as $kw => $aliases) {
if(in_array($value, $aliases) !== false) {
if(in_array($v, $aliases) !== false) {
return true;
}
}
}
else {
switch($value) {
switch($v) {
case '@context':
case '@container':
case '@default':
@ -3061,125 +3074,136 @@ class JsonLdProcessor {
}
/**
* Returns true if the given input is an empty Object.
* Returns true if the given value is an empty Object.
*
* @param mixed $input the input to check.
* @param mixed $v the value to check.
*
* @return bool true if the input is an empty Object, false if not.
* @return bool true if the value is an empty Object, false if not.
*/
protected static function _isEmptyObject($input) {
return is_object($input) && count(get_object_vars($input)) === 0;
protected static function _isEmptyObject($v) {
return is_object($v) && count(get_object_vars($v)) === 0;
}
/**
* Returns true if the given input is an Array of Strings.
* Throws an exception if the given value is not a valid @type value.
*
* @param mixed $input the input to check.
*
* @return bool true if the input is an Array of Strings, false if not.
* @param mixed $v the value to check.
*/
protected static function _isArrayOfStrings($input) {
if(!is_array($input)) {
return false;
protected static function _validateTypeValue($v) {
// must be a string, subject reference, or empty object
if(is_string($v) || self::_isSubjectReference($v) ||
self::_isEmptyObject($v)) {
return;
}
foreach($input as $v) {
if(!is_string($v)) {
return false;
// must be an array
$is_valid = false;
if(is_array($v)) {
$is_valid = true;
foreach($v as $e) {
if(!(is_string($e) || self::_isSubjectReference($e))) {
$is_valid = false;
break;
}
}
}
return true;
if(!$is_valid) {
throw new JsonLdException(
'Invalid JSON-LD syntax; "@type" value must a string, an array ' +
'of strings, or an empty object.',
'jsonld.SyntaxError', array('value' => $v));
}
}
/**
* Returns true if the given value is a subject with properties.
*
* @param mixed $value the value to check.
* @param mixed $v the value to check.
*
* @return bool true if the value is a subject with properties, false if not.
*/
protected static function _isSubject($value) {
$rval = false;
protected static function _isSubject($v) {
// Note: A value is a subject if all of these hold true:
// 1. It is an Object.
// 2. It is not a @value, @set, or @list.
// 3. It has more than 1 key OR any existing key is not @id.
if(is_object($value) &&
!property_exists($value, '@value') &&
!property_exists($value, '@set') &&
!property_exists($value, '@list')) {
$count = count(get_object_vars($value));
$rval = ($count > 1 || !property_exists($value, '@id'));
$rval = false;
if(is_object($v) &&
!property_exists($v, '@value') &&
!property_exists($v, '@set') &&
!property_exists($v, '@list')) {
$count = count(get_object_vars($v));
$rval = ($count > 1 || !property_exists($v, '@id'));
}
return $rval;
}
/**
* Returns true if the given value is a subject reference.
*
* @param mixed $value the value to check.
* @param mixed $v the value to check.
*
* @return bool true if the value is a subject reference, false if not.
*/
protected static function _isSubjectReference($value) {
protected static function _isSubjectReference($v) {
// Note: A value is a subject reference if all of these hold true:
// 1. It is an Object.
// 2. It has a single key: @id.
return (is_object($value) && count(get_object_vars($value)) === 1 &&
property_exists($value, '@id'));
return (is_object($v) && count(get_object_vars($v)) === 1 &&
property_exists($v, '@id'));
}
/**
* Returns true if the given value is a @value.
*
* @param mixed $value the value to check.
* @param mixed $v the value to check.
*
* @return bool true if the value is a @value, false if not.
*/
protected static function _isValue($value) {
protected static function _isValue($v) {
// Note: A value is a @value if all of these hold true:
// 1. It is an Object.
// 2. It has the @value property.
return is_object($value) && property_exists($value, '@value');
return is_object($v) && property_exists($v, '@value');
}
/**
* Returns true if the given value is a @list.
*
* @param mixed $value the value to check.
* @param mixed $v the value to check.
*
* @return bool true if the value is a @list, false if not.
*/
protected static function _isList($value) {
protected static function _isList($v) {
// Note: A value is a @list if all of these hold true:
// 1. It is an Object.
// 2. It has the @list property.
return is_object($value) && property_exists($value, '@list');
return is_object($v) && property_exists($v, '@list');
}
/**
* Returns true if the given value is a blank node.
*
* @param mixed $value the value to check.
* @param mixed $v the value to check.
*
* @return bool true if the value is a blank node, false if not.
*/
protected static function _isBlankNode($value) {
$rval = false;
protected static function _isBlankNode($v) {
// Note: A value is a blank node if all of these hold true:
// 1. It is an Object.
// 2. If it has an @id key its value begins with '_:'.
// 3. It has no keys OR is not a @value, @set, or @list.
if(is_object($value)) {
if(property_exists($value, '@id')) {
$rval = (strpos($value->{'@id'}, '_:') === 0);
$rval = false;
if(is_object($v)) {
if(property_exists($v, '@id')) {
$rval = (strpos($v->{'@id'}, '_:') === 0);
}
else {
$rval = (count(get_object_vars($value)) === 0 ||
!(property_exists($value, '@value') ||
property_exists($value, '@set') ||
property_exists($value, '@list')));
$rval = (count(get_object_vars($v)) === 0 ||
!(property_exists($v, '@value') ||
property_exists($v, '@set') ||
property_exists($v, '@list')));
}
}
return $rval;
@ -3188,12 +3212,12 @@ class JsonLdProcessor {
/**
* Returns true if the given value is an absolute IRI, false if not.
*
* @param string $value the value to check.
* @param string $v the value to check.
*
* @return bool true if the value is an absolute IRI, false if not.
*/
protected static function _isAbsoluteIri($value) {
return strpos($value, ':') !== false;
protected static function _isAbsoluteIri($v) {
return strpos($v, ':') !== false;
}
}