/extensions/SemanticMediaWiki/includes/export/SMW_Exp_Data.php
https://github.com/ChuguluGames/mediawiki-svn · PHP · 255 lines · 131 code · 18 blank · 106 comment · 34 complexity · 9ee1b4ed1021fcdb608114c4b73e8a83 MD5 · raw file
- <?php
- /**
- * SMWExpData is a class representing semantic data that is ready for easy
- * serialisation in OWL or RDF.
- *
- * @author Markus Krötzsch
- * @file
- * @ingroup SMW
- */
- /**
- * SMWExpData is a data container for export-ready semantic content. It is
- * organised as a tree-shaped data structure with one root subject and zero
- * or more children connected with labelled edges to the root. Children are
- * again SMWExpData objects, and edges are annotated with SMWExpNsElements
- * specifying properties.
- * @note We do not allow property element without namespace abbreviation
- * here. Property aabbreviations are mandatory for some serialisations.
- *
- * @ingroup SMW
- */
- class SMWExpData extends SMWExpElement {
- /**
- * The subject of the data that we store.
- * @var SMWExpResource
- */
- protected $m_subject;
- /**
- * Array mapping property URIs to arrays their values, given as
- * SMWExpElement objects.
- * @var array of array of SMWElement
- */
- protected $m_children = array();
- /**
- * Array mapping property URIs to arrays their SMWExpResource
- * @var array of SMWExpResource
- */
- protected $m_edges = array();
- /**
- * Constructor. $subject is the SMWExpResource for the
- * subject about which this SMWExpData is.
- */
- public function __construct( SMWExpResource $subject ) {
- parent::__construct( $subject->getDataItem() );
- $this->m_subject = $subject;
- }
- /**
- * Turn an array of SMWExpElements into an RDF collection.
- *
- * @param $elements array of SMWExpElement
- * @return SMWExpData
- */
- public static function makeCollection( array $elements ) {
- if ( count( $elements ) == 0 ) {
- return new SMWExpData( SMWExporter::getSpecialNsResource( 'rdf', 'nil' ) );
- } else {
- $rdftype = SMWExporter::getSpecialNsResource( 'rdf', 'type' );
- $rdffirst = SMWExporter::getSpecialNsResource( 'rdf', 'first' );
- $rdfrest = SMWExporter::getSpecialNsResource( 'rdf', 'rest' );
- $result = new SMWExpData( new SMWExpResource( '' ) ); // bnode
- $result->addPropertyObjectValue( $rdftype, new SMWExpData( SMWExporter::getSpecialNsResource( 'rdf', 'List' ) ) );
- $result->addPropertyObjectValue( $rdffirst, array_shift( $elements ) );
- $result->addPropertyObjectValue( $rdfrest, SMWExpData::makeCollection( $elements ) );
- return $result;
- }
- }
- /**
- * Return subject to which the stored semantic annotation refer to.
- *
- * @return SMWExpResource
- */
- public function getSubject() {
- return $this->m_subject;
- }
- /**
- * Store a value for a property identified by its title object. No
- * duplicate elimination as this is usually done in SMWSemanticData
- * already (which is typically used to generate this object).
- *
- * @param SMWExpNsResource $property
- * @param SMWExpData $child
- */
- public function addPropertyObjectValue( SMWExpNsResource $property, SMWExpElement $child ) {
- if ( !array_key_exists( $property->getUri(), $this->m_edges ) ) {
- $this->m_children[$property->getUri()] = array();
- $this->m_edges[$property->getUri()] = $property;
- }
- $this->m_children[$property->getUri()][] = $child;
- }
- /**
- * Return the list of SMWExpResource objects for all properties for
- * which some values have been given.
- *
- * @return array of SMWExpResource
- */
- public function getProperties() {
- return $this->m_edges;
- }
- /**
- * Return the list of SMWExpElement values associated to some property
- * (element).
- *
- * @return array of SMWExpElement
- */
- public function getValues( SMWExpResource $property ) {
- if ( array_key_exists( $property->getUri(), $this->m_children ) ) {
- return $this->m_children[$property->getUri()];
- } else {
- return array();
- }
- }
- /**
- * Return the list of SMWExpData values associated to some property that is
- * specifed by a standard namespace id and local name.
- *
- * @param $namespaceId string idetifying a known special namespace (e.g. "rdf")
- * @param $localName string of local name (e.g. "type")
- * @return array of SMWExpData
- */
- public function getSpecialValues( $namespaceId, $localName ) {
- $pe = SMWExporter::getSpecialNsResource( $namespaceId, $localName );
- return $this->getValues( $pe );
- }
- /**
- * This function finds the main type (class) element of the subject
- * based on the current property assignments. It returns this type
- * element (SMWExpElement) and removes the according type assignement
- * from the data. If no type is assigned, the element for rdf:Resource
- * is returned.
- *
- * @note Under all normal conditions, the result will be an
- * SMWExpResource.
- *
- * @return SMWExpElement
- */
- public function extractMainType() {
- $pe = SMWExporter::getSpecialNsResource( 'rdf', 'type' );
- if ( array_key_exists( $pe->getUri(), $this->m_children ) ) {
- $result = array_shift( $this->m_children[$pe->getUri()] );
- if ( count( $this->m_children[$pe->getUri()] ) == 0 ) {
- unset( $this->m_edges[$pe->getUri()] );
- unset( $this->m_children[$pe->getUri()] );
- }
- return ( $result instanceof SMWExpData ) ? $result->getSubject() : $result;
- } else {
- return SMWExporter::getSpecialNsResource( 'rdf', 'Resource' );
- }
- }
- /**
- * Check if this element encodes an RDF list, and if yes return an
- * array of SMWExpElements corresponding to the collection elements in
- * the specified order. Otherwise return false.
- * The method only returns lists that can be encoded using
- * parseType="Collection" in RDF/XML, i.e. only lists of non-literal
- * resources.
- *
- * @return mixed array of SMWExpElement (but not SMWExpLiteral) or false
- */
- public function getCollection() {
- $rdftypeUri = SMWExporter::getSpecialNsResource( 'rdf', 'type' )->getUri();
- $rdffirstUri = SMWExporter::getSpecialNsResource( 'rdf', 'first' )->getUri();
- $rdfrestUri = SMWExporter::getSpecialNsResource( 'rdf', 'rest' )->getUri();
- $rdfnilUri = SMWExporter::getSpecialNsResource( 'rdf', 'nil' )->getUri();
- // first check if we are basically an RDF List:
- if ( ( $this->m_subject->isBlankNode() ) &&
- ( count( $this->m_children ) == 3 ) &&
- ( array_key_exists( $rdftypeUri, $this->m_children ) ) &&
- ( count( $this->m_children[$rdftypeUri] ) == 1 ) &&
- ( array_key_exists( $rdffirstUri, $this->m_children ) ) &&
- ( count( $this->m_children[$rdffirstUri] ) == 1 ) &&
- !( end( $this->m_children[$rdffirstUri] ) instanceof SMWExpLiteral ) &&
- // (parseType collection in RDF not possible with literals :-/)
- ( array_key_exists( $rdfrestUri, $this->m_children ) ) &&
- ( count( $this->m_children[$rdfrestUri] ) == 1 ) ) {
- $typedata = end( $this->m_children[$rdftypeUri] );
- $rdflistUri = SMWExporter::getSpecialNsResource( 'rdf', 'List' )->getUri();
- if ( $typedata->getSubject()->getUri() == $rdflistUri ) {
- $first = end( $this->m_children[$rdffirstUri] );
- $rest = end( $this->m_children[$rdfrestUri] );
- if ( $rest instanceof SMWExpData ) {
- $restlist = $rest->getCollection();
- if ( $restlist === false ) {
- return false;
- } else {
- array_unshift( $restlist, $first );
- return $restlist;
- }
- } elseif ( ( $rest instanceof SMWExpResource ) &&
- ( $rest->getUri() == $rdfnilUri ) ) {
- return array( $first );
- } else {
- return false;
- }
- } else {
- return false;
- }
- } elseif ( ( count( $this->m_children ) == 0 ) && ( $this->m_subject->getUri() == $rdfnilUri ) ) {
- return array();
- } else {
- return false;
- }
- }
- /**
- * Return an array of ternary arrays (subject predicate object) of
- * SMWExpElements that represents the flattened version of this data.
- *
- * @return array of array of SMWExpElement
- */
- public function getTripleList( SMWExpElement $subject = null ) {
- global $smwgBnodeCount;
- if ( !isset( $smwgBnodeCount ) ) {
- $smwgBnodeCount = 0;
- }
- if ( $subject == null ) {
- $subject = $this->m_subject;
- }
- $result = array();
- foreach ( $this->m_edges as $key => $edge ) {
- foreach ( $this->m_children[$key] as $childElement ) {
- if ( $childElement instanceof SMWExpData ) {
- $childSubject = $childElement->getSubject();
- } else {
- $childSubject = $childElement;
- }
- if ( ( $childSubject instanceof SMWExpResource ) &&
- ( $childSubject->isBlankNode() ) ) { // bnode, rename ID to avoid unifying bnodes of different contexts
- // TODO: should we really rename bnodes of the form "_id" here?
- $childSubject = new SMWExpResource( '_' . $smwgBnodeCount++, $childSubject->getDataItem() );
- }
- $result[] = array( $subject, $edge, $childSubject );
- if ( $childElement instanceof SMWExpData ) { // recursively add child's triples
- $result = array_merge( $result, $childElement->getTripleList( $childSubject ) );
- }
- }
- }
- return $result;
- }
- }