From b0c1d0cfe8c41d48acfd8a906cd375fa4444104e Mon Sep 17 00:00:00 2001 From: Dave Longley Date: Wed, 6 Mar 2013 14:34:03 -0500 Subject: [PATCH] Remove property generator support. --- jsonld.php | 249 ++++++----------------------------------------------- 1 file changed, 28 insertions(+), 221 deletions(-) diff --git a/jsonld.php b/jsonld.php index fe8cd2f..e614852 100644 --- a/jsonld.php +++ b/jsonld.php @@ -1,7 +1,7 @@ _compactValue($active_ctx, $active_property, $element); } - // shallow copy element and arrays so keys and values can be removed - // during property generator compaction - $shallow = new stdClass(); - foreach($element as $expanded_property => $expanded_value) { - if(is_array($element->{$expanded_property})) { - $shallow->{$expanded_property} = $element->{$expanded_property}; - } - else { - $shallow->{$expanded_property} = $element->{$expanded_property}; - } - } - $element = $shallow; - // process element keys in order $keys = array_keys((array)$element); sort($keys); $rval = new stdClass(); foreach($keys as $expanded_property) { - // skip key if removed during property generator duplicate handling - if(!property_exists($element, $expanded_property)) { - continue; - } - $expanded_value = $element->{$expanded_property}; // compact @id and @type(s) @@ -1771,7 +1753,7 @@ class JsonLdProcessor { if(count($expanded_value) === 0) { $item_active_property = $this->_compactIri( $active_ctx, $expanded_property, $expanded_value, - array('vocab' => true), $element); + array('vocab' => true)); self::addValue( $rval, $item_active_property, array(), array('propertyIsArray' => true)); @@ -1782,21 +1764,10 @@ class JsonLdProcessor { // compact property and get container type $item_active_property = $this->_compactIri( $active_ctx, $expanded_property, $expanded_item, - array('vocab' => true), $element); + array('vocab' => true)); $container = self::getContextValue( $active_ctx, $item_active_property, '@container'); - // remove any duplicates that were (presumably) generated by a - // property generator - if(property_exists($active_ctx->mappings, $item_active_property)) { - $mapping = $active_ctx->mappings->{$item_active_property}; - if($mapping && $mapping->propertyGenerator) { - $this->_findPropertyGeneratorDuplicates( - $active_ctx, $element, $expanded_property, $expanded_item, - $item_active_property, true); - } - } - // get @list value if appropriate $is_list = self::_isList($expanded_item); $list = null; @@ -1957,20 +1928,13 @@ class JsonLdProcessor { $mapping = null; } - // expand key using property generator - if($mapping && $mapping->propertyGenerator) { - $expanded_property = $mapping->{'@id'}; - } // expand key to IRI - else { - $expanded_property = $this->_expandIri( - $active_ctx, $key, array('vocab' => true)); - } + $expanded_property = $this->_expandIri( + $active_ctx, $key, array('vocab' => true)); // drop non-absolute IRI keys that aren't keywords if($expanded_property === null || - !(is_array($expanded_property) || - self::_isAbsoluteIri($expanded_property) || + !(self::_isAbsoluteIri($expanded_property) || self::_isKeyword($expanded_property))) { continue; } @@ -2088,26 +2052,14 @@ class JsonLdProcessor { '@list' => self::arrayify($expanded_value)); } - // add copy of value for each property from property generator - if(is_array($expanded_property)) { - $expanded_value = $this->_labelBlankNodes( - $active_ctx->namer, $expanded_value); - foreach($expanded_property as $iri) { - self::addValue( - $rval, $iri, self::copy($expanded_value), - array('propertyIsArray' => true)); - } - } // add value for property - else { - // use an array except for certain keywords - $use_array = (!in_array( - $expanded_property, array( - '@index', '@id', '@type', '@value', '@language'))); - self::addValue( - $rval, $expanded_property, $expanded_value, - array('propertyIsArray' => $use_array)); - } + // use an array except for certain keywords + $use_array = (!in_array( + $expanded_property, array( + '@index', '@id', '@type', '@value', '@language'))); + self::addValue( + $rval, $expanded_property, $expanded_value, + array('propertyIsArray' => $use_array)); } // get property count on expanded output @@ -3917,7 +3869,6 @@ class JsonLdProcessor { * @param active_ctx the active context. * @param iri the IRI to pick the term for. * @param value the value to pick the term for. - * @param parent the parent of the value (required for property generators). * @param containers the preferred containers. * @param type_or_language either '@type' or '@language'. * @param type_or_language_value the preferred value for '@type' or @@ -3926,7 +3877,7 @@ class JsonLdProcessor { * @return mixed the preferred term. */ protected function _selectTerm( - $active_ctx, $iri, $value, $parent, $containers, + $active_ctx, $iri, $value, $containers, $type_or_language, $type_or_language_value) { $containers[] = '@none'; if($type_or_language_value === null) { @@ -3969,33 +3920,14 @@ class JsonLdProcessor { $type_or_language_value_map = $container_map->{$container}->{$type_or_language}; foreach($options as $option) { - if($term !== null) { - break; - } - // if type/language option not available in the map, continue if(!property_exists($type_or_language_value_map, $option)) { continue; } - $term_info = $type_or_language_value_map->{$option}; - - // see if a property generator matches - if(is_object($parent)) { - foreach($term_info->propertyGenerators as $property_generator) { - $match = $this->_findPropertyGeneratorDuplicates( - $active_ctx, $parent, $iri, $value, $property_generator, false); - if($match) { - $term = $property_generator; - break; - } - } - } - - // no matching property generator, use a simple term instead - if($term === null) { - $term = $term_info->term; - } + // select term + $term = $type_or_language_value_map->{$option}; + break; } } return $term; @@ -4010,12 +3942,11 @@ class JsonLdProcessor { * @param mixed $value the value to check or null. * @param assoc $relative_to options for how to compact IRIs: * vocab: true to split after @vocab, false not to. - * @param mixed $parent the parent element for the value. * * @return string the compacted term, prefix, keyword alias, or original IRI. */ protected function _compactIri( - $active_ctx, $iri, $value=null, $relative_to=array(), $parent=null) { + $active_ctx, $iri, $value=null, $relative_to=array()) { // can't compact null if($iri === null) { return $iri; @@ -4127,7 +4058,7 @@ class JsonLdProcessor { // do term selection $term = $this->_selectTerm( - $active_ctx, $iri, $value, $parent, + $active_ctx, $iri, $value, $containers, $type_or_language, $type_or_language_value); if($term !== null) { return $term; @@ -4142,7 +4073,7 @@ class JsonLdProcessor { continue; } // skip entries with @ids that are not partial matches - if($definition === null || $definition->propertyGenerator || + if($definition === null || $definition->{'@id'} === $iri || strpos($iri, $definition->{'@id'}) !== 0) { continue; @@ -4290,76 +4221,6 @@ class JsonLdProcessor { return $rval; } - /** - * Finds and, if specified, removes any duplicate values that were - * presumably generated by a property generator in the given element. - * - * @param stdClass $active_ctx the active context. - * @param stdClass $element the element to remove duplicates from. - * @param string $expanded_property the property to map to a property - * generator. - * @param mixed $value the value to compare against when duplicate checking. - * @param string $active_property the property generator term. - * @param bool $remove true to remove the duplicates found, false not to. - * - * @return bool true if duplicates were found for every IRI. - */ - protected function _findPropertyGeneratorDuplicates( - $active_ctx, $element, $expanded_property, $value, $active_property, - $remove) { - $rval = true; - - // get property generator IRIs - $iris = $active_ctx->mappings->{$active_property}->{'@id'}; - - // for each IRI that isn't 'expandedProperty', remove a single duplicate - // from element, if found - foreach($iris as $iri) { - if($rval === false) { - break; - } - - if($iri === $expanded_property) { - continue; - } - - $rval = false; - if(!property_exists($element, $iri)) { - break; - } - - $length = count($element->{$iri}); - - // handle empty array case - if(is_array($value) && count($value) === 0) { - $rval = true; - if($remove) { - unset($element->{$iri}); - } - continue; - } - - // handle other cases - for($pi = 0; $pi < $length; ++$pi) { - if(self::compareValues($element->{$iri}[$pi], $value)) { - // duplicate found - $rval = true; - - if($remove) { - // remove it in place - array_splice($element->{$iri}, $pi, 1); - if(count($element->{$iri}) === 0) { - unset($element->{$iri}); - } - } - break; - } - } - } - - return $rval; - } - /** * Creates a term definition during context processing. * @@ -4436,8 +4297,7 @@ class JsonLdProcessor { } // define/redefine term to expanded IRI/keyword - $active_ctx->mappings->{$term} = (object)array( - '@id' => $id, 'propertyGenerator' => false); + $active_ctx->mappings->{$term} = (object)array('@id' => $id); $defined->{$term} = true; return; } @@ -4451,44 +4311,10 @@ class JsonLdProcessor { // create new mapping $mapping = new stdClass(); - $mapping->propertyGenerator = false; if(property_exists($value, '@id')) { $id = $value->{'@id'}; - // handle property generator - if(is_array($id)) { - if($active_ctx->namer === null) { - throw new JsonLdException( - 'Incompatible JSON-LD options; a property generator was found ' . - 'in the @context, but blank node renaming has been disabled; ' . - 'it must be enabled to use property generators.', - 'jsonld.OptionsError', array('context' => $local_ctx)); - } - - $property_generator = array(); - $ids = $id; - foreach($ids as $id) { - // expand @id - if(is_string($id)) { - $id = $this->_expandIri( - $active_ctx, $id, array('vocab' => true, 'base' => true), - $local_ctx, $defined); - } - if(!is_string($id) || self::_isKeyword($id)) { - throw new JsonLdException( - 'Invalid JSON-LD syntax; property generators must consist of ' . - 'an @id array containing only strings and no string can be ' . - '"@type".', - 'jsonld.SyntaxError', array('context' => $local_ctx)); - } - $property_generator[] = $id; - } - // add sorted property generator as @id in mapping - sort($property_generator); - $mapping->{'@id'} = $property_generator; - $mapping->propertyGenerator = true; - } - else if(!is_string($id)) { + if(!is_string($id)) { throw new JsonLdException( 'Invalid JSON-LD syntax; @context @id value must be an array ' . 'of strings or a string.', @@ -4626,15 +4452,7 @@ class JsonLdProcessor { if(isset($relative_to['vocab']) && $relative_to['vocab']) { if(property_exists($active_ctx->mappings, $value)) { - // term dependency cannot be a property generator $mapping = $active_ctx->mappings->{$value}; - if($local_ctx !== null && $mapping && $mapping->propertyGenerator) { - throw new JsonLdException( - 'Invalid JSON-LD syntax; a term definition cannot have a property ' . - 'generator as a dependency.', - 'jsonld.SyntaxError', - array('context' => $local_ctx, 'value' => $value)); - } // value is explicitly ignored with a null mapping if($mapping === null) { @@ -4642,9 +4460,7 @@ class JsonLdProcessor { } // value is a term - if(!$mapping->propertyGenerator) { - $rval = $mapping->{'@id'}; - } + $rval = $mapping->{'@id'}; } } @@ -4664,11 +4480,11 @@ class JsonLdProcessor { $active_ctx, $local_ctx, $prefix, $defined); } - // use mapping if prefix is defined and not a property generator + // use mapping if prefix is defined if(property_exists($active_ctx->mappings, $prefix)) { $mapping = $active_ctx->mappings->{$prefix}; - if($mapping && !$mapping->propertyGenerator) { - $rval = $active_ctx->mappings->{$prefix}->{'@id'} . $suffix; + if($mapping) { + $rval = $mapping->{'@id'} . $suffix; } } } @@ -5006,7 +4822,7 @@ class JsonLdProcessor { } /** - * Adds or updates the term or property generator for the given entry. + * Adds the term for the given entry if not already added. * * @param stdClass $mapping the term mapping. * @param string $term the term to add. @@ -5016,16 +4832,7 @@ class JsonLdProcessor { */ function _addPreferredTerm($mapping, $term, $entry, $type_or_language_value) { if(!property_exists($entry, $type_or_language_value)) { - $entry->{$type_or_language_value} = (object)array( - 'term' => null, 'propertyGenerators' => array()); - } - - $e = $entry->{$type_or_language_value}; - if($mapping->propertyGenerator) { - $e->propertyGenerators[] = $term; - } - else if($e->term === null) { - $e->term = $term; + $entry->{$type_or_language_value} = $term; } }