<?php 

/**
 * Include PEAR base class
 */
require_once 'PEAR.php';

// ----------------------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------------------
// Version                   : 0.7
// Authors                   : Chris Bizer (chris@bizer.de),
// Daniel Westphal (dawe@gmx.de),
// Leandro Mariano Lopez (llopez@xinergiaargentina.com),
// Radoslaw Oldakowski (radol@gmx.de)

// Description               : Constants and default configuration
// ----------------------------------------------------------------------------------
// General
// ----------------------------------------------------------------------------------
define('RDF_DEFAULT_ALGORITHM',     'MD5');
define('RDF_DEFAULT_ENCODING',      'UTF-8');
define('RDF_INDENTATION',           '    ');
define('RDF_LINEFEED',              chr(10));
// ----------------------------------------------------------------------------------
// Error Messages
// ----------------------------------------------------------------------------------
define('RDF_ERROR',                 -1);
define('RDF_ERROR_NOT_SUPPORTED',   -2);
define('RDF_ERROR_CONFIG_ERROR',    -3);
define('RDF_ERROR_MISSING_DEPS',    -4);
define('RDF_ERROR_UNEXPECTED',      -5);
define('RDF_ERROR_MISMATCH',        -6);
// ----------------------------------------------------------------------------------
// Model
// ----------------------------------------------------------------------------------
define('RDF_BNODE_PREFIX', 'bNode');
// ----------------------------------------------------------------------------------
// Parser
// ----------------------------------------------------------------------------------
// RDFParser: Set this option to false if you want to use IDs containing CombiningChars or 
// Extenders (see http://www.w3.org/TR/REC-xml-names/#NT-NCName). If set to TRUE, they're assumed to be invalid.
define('RDF_VALIDATE_IDS', true);
// N3 and N-Triple-Parser: Set this option to true in order to override the given bnode 
// labels and rename them to the defined BNODE_PREFIX
define('RDF_FIX_BLANKNODES', true);
define('RDF_NAMESPACE_SEPARATOR_CHAR', '^');
define('RDF_NAMESPACE_SEPARATOR_STRING', '^');
define('RDF_IN_TOP_LEVEL', 0);
define('RDF_IN_RDF', 1);
define('RDF_IN_DESCRIPTION', 2);
define('RDF_IN_PROPERTY_UNKNOWN_OBJECT', 3);
define('RDF_IN_PROPERTY_RESOURCE', 4);
define('RDF_IN_PROPERTY_EMPTY_RESOURCE', 5);
define('RDF_IN_PROPERTY_LITERAL', 6);
define('RDF_IN_PROPERTY_PARSE_TYPE_LITERAL', 7);
define('RDF_IN_PROPERTY_PARSE_TYPE_RESOURCE', 8);
define('RDF_IN_XML', 9);
define('RDF_IN_UNKNOWN', 10);
define('RDF_IN_PROPERTY_PARSE_TYPE_COLLECTION', 11);
define('RDF_SUBJECT_TYPE_URI', 0);
define('RDF_SUBJECT_TYPE_DISTRIBUTED', 1);
define('RDF_SUBJECT_TYPE_PREFIX', 2);
define('RDF_SUBJECT_TYPE_ANONYMOUS', 3);
define('RDF_SUBJECT_TYPE_BNODE', 4);
define('RDF_OBJECT_TYPE_RESOURCE', 0);
define('RDF_OBJECT_TYPE_LITERAL', 1);
define('RDF_OBJECT_TYPE_XML', 2);
define('RDF_OBJECT_TYPE_BNODE', 3);
// ----------------------------------------------------------------------------------
// Serializer
// ----------------------------------------------------------------------------------
// RDF, N3, N-Triple Serializer: set to TRUE in oder to suppres the "Generated by RAP" 
// comment in the output files.
define('RDF_HIDE_ADVERTISE', false);
// RDF Serializer: Set to TRUE, if the serializer should use entities for URIs.
define('RDF_SER_USE_ENTITIES', false);
// RDF Serializer: Set to TRUE, if the serializer should serialize triples as XML 
// attributes where possible.
define('RDF_SER_USE_ATTRIBUTES', false);
// RDF Serializer: Set to TRUE in order to sort the statements of a model before 
// serializing them.
define('RDF_SER_SORT_MODEL', true);
// RDF Serializer: Set to TRUE, if the serializer should use qualified names for RDF
// reserved words.
// NOTE: There is only one default namespace allowed within an XML document.
//       Therefore if SER_RDF_QNAMES in is set to FALSE and you pass the parameter
//       $xml_default_namespace to the method serialize() of class RDFSerializer, 
//       the model will be serialized as if SER_RDF_QNAMES were set to TRUE.
define('RDF_SER_RDF_QNAMES', true);
// RDF Serializer: Set to TRUE, if the serializer should start documents with the 
// xml declaration <?xml version="1.0" encoding="UTF-8" >.
define('RDF_SER_XML_DECLARATION', true);
// N3 Serializer: Set to TRUE, if the N3 serializer should try to compress the blank node 
// syntax using [] whereever possible.
define('RDF_N3SER_BNODE_SHORT', true);
// RDF Serializer: Set to TRUE, if the serializer should write text values always as 
// escaped CDATA.
define('RDF_USE_CDATA', false);
define('RDF_USE_ANY_QUOTE', false);
define('RDF_GENERAL_PREFIX_BASE', 'ns');
define('RDF_MAX_ALLOWED_ABBREVIATED_LENGTH', 60);
// ----------------------------------------------------------------------------------
// Util
// ----------------------------------------------------------------------------------
// Definition of the colors used by the method RDF_Util:writeHTMLTable
define('RDF_HTML_TABLE_HEADER_COLOR', '#FFFFFF');
define('RDF_HTML_TABLE_RESOURCE_COLOR', '#FFFFCC');
define('RDF_HTML_TABLE_LITERAL_COLOR', '#E7E7EF');
define('RDF_HTML_TABLE_BNODE_COLOR', '#FFCCFF');
define('RDF_HTML_TABLE_RDF_NS_COLOR', '#CCFFCC');
// ----------------------------------------------------------------------------------
// RDF
// ----------------------------------------------------------------------------------
define('RDF_SYNTAX_COMPACT', true);
define('RDF_NAMESPACE_URI', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
define('RDF_NAMESPACE_PREFIX', 'rdf');
define('RDF', 'RDF');
define('RDF_DESCRIPTION', 'Description');
define('RDF_ID', 'ID');
define('RDF_ABOUT', 'about');
define('RDF_ABOUT_EACH', 'aboutEach');
define('RDF_ABOUT_EACH_PREFIX', 'aboutEachPrefix');
define('RDF_BAG_ID', 'bagID');
define('RDF_RESOURCE', 'resource');
define('RDF_VALUE', 'value');
define('RDF_PARSE_TYPE', 'parseType');
define('RDF_PARSE_TYPE_LITERAL', 'Literal');
define('RDF_PARSE_TYPE_RESOURCE', 'Resource');
define('RDF_PARSE_TYPE_COLLECTION', 'Collection');
define('RDF_TYPE', 'type');
define('RDF_BAG', 'Bag');
define('RDF_SEQ', 'Seq');
define('RDF_ALT', 'Alt');
define('RDF_LI', 'li');
define('RDF_STATEMENT', 'Statement');
define('RDF_SUBJECT', 'subject');
define('RDF_PREDICATE', 'predicate');
define('RDF_OBJECT', 'object');
define('RDF_NODEID', 'nodeID');
define('RDF_DATATYPE', 'datatype');
define('RDF_SEEALSO', 'seeAlso');
define('RDF_PROPERTY', 'Property');
define('RDF_LIST', 'List');
define('RDF_NIL', 'nil');
define('RDF_REST', 'rest');
define('RDF_FIRST', 'first');
define('RDF_XMLLITERAL', 'XMLLiteral');
// ----------------------------------------------------------------------------------
// RDF Schema
// ----------------------------------------------------------------------------------
define('RDF_SCHEMA_URI', 'http://www.w3.org/2000/01/rdf-schema#');
define('RDF_DATATYPE_SCHEMA_URI', 'http://www.w3.org/TR/xmlschema-2');
define('RDF_SCHEMA_PREFIX', 'rdfs');
define('RDF_RDFS_SUBCLASSOF', 'subClassOf');
define('RDF_RDFS_SUBPROPERTYOF', 'subPropertyOf');
// ----------------------------------------------------------------------------------
// XML
// ----------------------------------------------------------------------------------
define('RDF_XML_NAMESPACE_PREFIX', 'xml');
define('RDF_XML_NAMESPACE_DECLARATION_PREFIX', 'xmlns');
define('RDF_XML_NAMESPACE_URI', 'http://www.w3.org/XML/1998/namespace');
define('RDF_XML_LANG', 'lang');
define('RDF_DATATYPE_SHORTCUT_PREFIX', 'datatype:');
// ----------------------------------------------------------------------------------
// RDF DATATYPE SHORTCUTS (extends datatype shortcuts to the full XML datatype URIs)
// ----------------------------------------------------------------------------------
$GLOBALS['_RDF_default_datatype'] = array(
    'STRING'   => RDF_DATATYPE_SCHEMA_URI . '#string',
    'DECIMAL'  => RDF_DATATYPE_SCHEMA_URI . '#decimal',
    'INTEGER'  => RDF_DATATYPE_SCHEMA_URI . '#integer',
    'INT'      => RDF_DATATYPE_SCHEMA_URI . '#int',
    'SHORT'    => RDF_DATATYPE_SCHEMA_URI . '#short',
    'BYTE'     => RDF_DATATYPE_SCHEMA_URI . '#byte',
    'LONG'     => RDF_DATATYPE_SCHEMA_URI . '#long',
    'LANGUAGE' => RDF_DATATYPE_SCHEMA_URI . '#language',
    'NAME'     => RDF_DATATYPE_SCHEMA_URI . '#name'
);

class RDF
{
    function factory($class, &$param)
    {
       $file = 'RDF/'.str_replace('_', '/', $class).'.php';
       include_once $file;
       $classname = 'RDF_'.$class;
       $obj =& new $classname();
       if (method_exists($obj, 'init')) {
           call_user_func_array(array(&$obj, 'init'), $param);
       }
       return $obj;
    }

    // }}}
    // {{{ raiseError()

    /**
     * This method is used to communicate an error and invoke error
     * callbacks etc.  Basically a wrapper for PEAR::raiseError
     * without the message string.
     *
     * @param mixed    integer error code, or a PEAR error object (all
     *                 other parameters are ignored if this parameter is
     *                 an object
     *
     * @param int      error mode, see PEAR_Error docs
     *
     * @param mixed    If error mode is PEAR_ERROR_TRIGGER, this is the
     *                 error level (E_USER_NOTICE etc).  If error mode is
     *                 PEAR_ERROR_CALLBACK, this is the callback function,
     *                 either as a function name, or as an array of an
     *                 object and method name.  For other error modes this
     *                 parameter is ignored.
     *
     * @param string   Extra debug information.  Defaults to the last
     *                 query and native error code.
     *
     * @return object  a PEAR error object
     *
     * @see PEAR_Error
     */
    function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
    {
        // The error is yet a MDB error object
        if (is_object($code)) {
            // because we the static PEAR::raiseError, our global
            // handler should be used if it is set
            if ($mode === null && !empty($this->_default_error_mode)) {
                $mode    = $this->_default_error_mode;
                $options = $this->_default_error_options;
            }
            return PEAR::raiseError($code, null, $mode, $options, null, null, true);
        }

        return PEAR::raiseError(null, $code, $mode, $options, $userinfo, 'RDF_Error', true);
    }
    /**
     * Return a textual error message for a RAP error code.
     *
     * @access  public
     * @param   int     error code
     * @return  string  error message
     */
    function errorMessage($value)
    {
        // make the variable static so that it only has to do the defining on the first call
        static $errorMessages;

        // define the varies error messages
        if (!isset($errorMessages)) {
            $errorMessages = array(
                RDF_ERROR                   => 'Unknown error',
                RDF_ERROR_NOT_SUPPORTED     => 'Feature not supported',
                RDF_ERROR_CONFIG_ERROR      => 'Config file error',
                RDF_ERROR_MISSING_DEPS      => 'Missing package depedencies',
                RDF_ERROR_UNEXPECTED        => 'Unexpected',
                RDF_ERROR_MISMATCH          => 'Mismatch',
            );
        }

        // If this is an error object, then grab the corresponding error code
        if (RDF::isError($value)) {
            $value = $value->getCode();
        }

        // return the textual error message corresponding to the code
        return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[RDF_ERROR];
    } // end func errorMessage

    function isError($value)
    {
        return is_a($value, 'RDF_Error');
    }
}

// ----------------------------------------------------------------------------------
// Class: RDF_Object
// ----------------------------------------------------------------------------------
/**
 * An abstract object.
 * Root object with some general methods, that should be overloaded. 
 * 
 * @version V0.7
 * @author Chris Bizer <chris@bizer.de> 
 * @abstract 
 * @package util
 */
class RDF_Object
{
    function factory()
    {
       $errmsg = 'Not implemented';
        return RDF::raiseError(RDF_ERROR, null, null, $errmsg);
    }

    /**
     * Serializes a object into a string
     * 
     * @access public 
     * @return string 
     */
    function toString()
    {
        $objectvars = get_object_vars($this);
        foreach($objectvars as $key => $value) {
            $content.= $key . "='" . $value . "'; ";
        }
        return 'Instance of ' . get_class($this) . '; Properties: ' . $content;
    }
}

/**
 * RDF_Error implements a class for reporting RDF error
 * messages.
 *
 * @package RDF
 * @category RDF
 * @author  Stig Bakken <ssb@fast.no>
 */
class RDF_Error extends PEAR_Error
{
    // }}}
    // {{{ constructor

    /**
     * RDF_Error constructor.
     *
     * @param mixed   $code      RDF error code, or string with error message.
     * @param integer $mode      what 'error mode' to operate in
     * @param integer $level     what error level to use for
     *                           $mode & PEAR_ERROR_TRIGGER
     * @param smixed  $debuginfo additional debug info, such as the last query
     */
    function RDF_Error($code = RDF_ERROR, $mode = PEAR_ERROR_RETURN,
              $level = E_USER_NOTICE, $debuginfo = null)
    {
        if (is_int($code)) {
            $this->PEAR_Error('RDF Error: '.RDF::errorMessage($code), $code,
                $mode, $level, $debuginfo);
        } else {
            $this->PEAR_Error("RDF Error: $code", RDF_ERROR, $mode, $level,
                $debuginfo);
        }
    }
}

require_once 'RDF/Util.php';
require_once 'RDF/Literal.php';
require_once 'RDF/Resource.php';
require_once 'RDF/BlankNode.php';
require_once 'RDF/Statement.php';
require_once 'RDF/StatementIterator.php';

require_once 'RDF/Parser.php';
require_once 'RDF/Serializer.php';

?>