<?php

/* RDFInt.php - RDF Interfaces for PHP
 * Copyright 2011 netlabs.org
 * Author: Christian Langanke, Adrian Gschwend
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace rdfa;

/**
 *  \class   Projection
 *  \brief   This class implements a projection as specified in the RDF API and RDFa specs of W3C.
 *  \details A projection relates to a specific subject of RDF data parsed by an instance of
 *           the rdfa::Data class and is to be created by the projection API methods this class only.
 *  \author  Christian Langanke
 *  \author  Adrian Gschwend
 *  \date    2011
 */
class Projection {

  /**
   * Version of the class
   */
  const version = '1.0.0';
  /**
   * Name of the fDebug context
   */
  const debugcontext = 'RDFA_PROJECTION';

  private $debugger;
  private $rdfaData;
  private $subject;

  // ---------------------------------------

  /**
   * Creates a Projection instance from a Data instance, reflecting a given subject in the triple data.
   *
   * Note: a projection is to be created by the following methods only:
   * - rdfa::Data::getProjection()
   * - rdfa::Data::getProjections()
   * - rdfa::Data::query()
   *
   * \param rdfaData     instance of Reader holding the RDF data
   * \param subject      subject of the projection
   * \param template     template array specifying the members to be created from data linked to the subject
   */
  public function __construct( $rdfaData, $subject, $template) {

    // setup debugger
    $this->debugger = \fDebug::getInstance();

    // check for required class
    if ((!is_object( $rdfaData)) ||
        ('\\' . get_class(  $rdfaData) != '\\rdfa\\Data'))
      throw new \Exception( 'Invalid Parameter: $rdfdata is not object of class \rdfa\Data.');

    // initialize
    $this->rdfaData = $rdfaData;
    $this->subject = $subject;

    $debugmessage = "Creating projection for subject: $subject";

    // create public members from template
    if (($template != Null) && (is_array( $template))) {
      $debugmessage .= "\nApplying template:\n";
      foreach ( $template as $key => $uri) {
        $value =  $this->get( $uri);
        if ($value != false) {
          $this->$key = $value;
          $debugmessage .= "$key=$value\n";
        } else {
          $debugmessage .= "### not found: $key\n";
        }
      }
    }

    $this->debugger->sendMessage( $debugmessage,
                                  self::debugcontext);

  } // public function __construct

  // --------------------------------------------------------

  /**
   * Gets properties of the subject of the projection.
   * Returns a list of properties.
   */
  public function getProperties() {
    return $this->rdfaData->getProperties( $this->subject);
  } // public function getProperties

  // --------------------------------------------------------

  /**
   * Gets unique properties of the subject of the projection.
   *
   * Ths method returns an associative list of properties => values.
   * All non-unique properties are NOT returned !
   *
   * <strong>NOTE: This method is a library specific extension to the RDF API and RDFa API.</strong>
   *
   */
  public function getUniqueProperties() {
    return $this->rdfaData->getUniqueProperties( $this->subject);
  } // public function getUniqueProperties

  // --------------------------------------------------------

  /**
   * Gets the subject of of the subject of the projection.
   */
  public function getSubject() {
    return $this->subject;
  } // public function getSubject

  // --------------------------------------------------------

  /**
   * Gets the first available value of a given property.
   *
   * \param property   property to retrieve the first value of
   */

  public function get( $property) {
    return $this->rdfaData->getFirstValue( $this->subject, $property);
  } // public function get

  // --------------------------------------------------------

  /**
   * Gets a list of all available values of a given property.
   *
   * \param property   property to retrieve all values of
   */

  public function getAll( $property) {
    return $this->rdfaData->getValues( $this->subject, $property);
  } // public function getAll

} // class Projection

?>