Swapped key/value order in @coerce.

This commit is contained in:
Dave Longley 2011-10-20 16:46:20 -04:00
parent 915b154d8c
commit 72482dbe97

View file

@ -109,13 +109,12 @@ function jsonld_compact($ctx, $input)
*/ */
function jsonld_merge_contexts($ctx1, $ctx2) function jsonld_merge_contexts($ctx1, $ctx2)
{ {
// copy contexts // copy context to merged output
$merged = _clone($ctx1); $merged = _clone($ctx1);
$copy = _clone($ctx2);
// if the new context contains any IRIs that are in the merged context, // if the new context contains any IRIs that are in the merged context,
// remove them from the merged context, they will be overwritten // remove them from the merged context, they will be overwritten
foreach($copy as $key => $value) foreach($ctx2 as $key => $value)
{ {
// ignore special keys starting with '@' // ignore special keys starting with '@'
if(strpos($key, '@') !== 0) if(strpos($key, '@') !== 0)
@ -124,6 +123,7 @@ function jsonld_merge_contexts($ctx1, $ctx2)
{ {
if($mvalue === $value) if($mvalue === $value)
{ {
// FIXME: update related @coerce rules
unset($merged->$mkey); unset($merged->$mkey);
break; break;
} }
@ -131,103 +131,30 @@ function jsonld_merge_contexts($ctx1, $ctx2)
} }
} }
// @coerce must be specially-merged, remove from contexts
$coerceExists =
property_exists($merged, '@coerce') or
property_exists($copy, '@coerce');
if($coerceExists)
{
$c1 = property_exists($merged, '@coerce') ?
$merged->{'@coerce'} : new stdClass();
$c2 = property_exists($copy, '@coerce') ?
$copy->{'@coerce'} : new stdClass();
unset($merged->{'@coerce'});
unset($copy->{'@coerce'});
}
// merge contexts // merge contexts
foreach($copy as $key => $value) foreach($ctx2 as $key => $value)
{ {
$merged->$key = $value; // skip @coerce, to be merged below
if($key !== '@coerce')
{
$merged->$key = _clone($value);
}
} }
// special-merge @coerce // merge @coerce
if($coerceExists) if(property_exists($ctx2, '@coerce'))
{ {
foreach($c1 as $type => $p1) if(!property_exists($merged, '@coerce'))
{ {
// append existing-type properties that don't already exist $merged->{'@coerce'} = _clone($ctx2->{'@coerce'});
if(property_exists($c2, $type))
{
$p2 = $c2->$type;
// normalize props in c2 to array for single-code-path iterating
if(!is_array($p2))
{
$p2 = array($p2);
}
// add unique properties from p2 to p1
foreach($p2 as $i => $p)
{
if((!is_array($p1) and $p1 !== $p) or
(is_array($p1) and array_search($p, $p1) === false))
{
if(is_array($p1))
{
$p1[] = $p;
} }
else else
{ {
$p1 = array($p1, $p); foreach($ctx2->{'@coerce'} as $p => $type)
}
}
}
$c1->$type = $p1;
}
}
// add new types from new @coerce
foreach($c2 as $type => $value)
{ {
if(!property_exists($c1, $type)) $merged->{'@coerce'}->$p = $type;
{
$c1->$type = $value;
} }
} }
// ensure there are no property duplicates in @coerce
$unique = new stdClass();
$dups = array();
foreach($c1 as $type => $p)
{
if(is_string($p))
{
$p = array($p);
}
foreach($p as $v)
{
if(!property_exists($unique, $v))
{
$unique->$v = true;
}
else if(!in_array($v, $dups))
{
$dups[] = $v;
}
}
}
if(count($dups)> 0)
{
throw new Exception(
'Invalid type coercion specification. More than one ' .
'type specified for at least one property. duplicates=' .
print_r(dups, true));
}
$merged->{'@coerce'} = $c1;
} }
return $merged; return $merged;
@ -1625,23 +1552,12 @@ class JsonLdProcessor
// check type coercion for property // check type coercion for property
else if(property_exists($ctx, '@coerce')) else if(property_exists($ctx, '@coerce'))
{ {
// force compacted property // look up compacted property in coercion map
$p = _compactIri($ctx, $p, null); $p = _compactIri($ctx, $p, null);
if(property_exists($ctx->{'@coerce'}, $p))
foreach($ctx->{'@coerce'} as $type => $props)
{
// get coerced properties (normalize to an array)
if(!is_array($props))
{
$props = array($props);
}
// look for the property in the array
foreach($props as $prop)
{
// property found
if($prop === $p)
{ {
// property found, return expanded type
$type = $ctx->{'@coerce'}->$p;
$rval = _expandTerm($ctx, $type, $usedCtx); $rval = _expandTerm($ctx, $type, $usedCtx);
if($usedCtx !== null) if($usedCtx !== null)
{ {
@ -1649,23 +1565,7 @@ class JsonLdProcessor
{ {
$usedCtx->{'@coerce'} = new stdClass(); $usedCtx->{'@coerce'} = new stdClass();
} }
$usedCtx->{'@coerce'}->$p = $type;
if(!property_exists($usedCtx->{'@coerce'}, $type))
{
$usedCtx->{'@coerce'}->$type = $p;
}
else
{
$c = $usedCtx->{'@coerce'}->$type;
if(is_array($c) and in_array($p, $c) or
is_string($c) and $c !== $p)
{
_setProperty($usedCtx->{'@coerce'}, $type, $p);
}
}
}
break;
}
} }
} }
} }
@ -2672,9 +2572,9 @@ function _subframe(
// iterate over frame keys to add any missing values // iterate over frame keys to add any missing values
foreach($frame as $key => $f) foreach($frame as $key => $f)
{ {
// skip keywords, type query, and keys in value // skip keywords, type query, and non-null keys in value
if(strpos($key, '@') !== 0 and $key !== JSONLD_RDF_TYPE and if(strpos($key, '@') !== 0 and $key !== JSONLD_RDF_TYPE and
!property_exists($value, $key)) (!property_exists($value, $key) || $value->{$key} === null))
{ {
// add empty array to value // add empty array to value
if(is_array($f)) if(is_array($f))