<?php

require_once 'common/Object.php';
require_once 'common/collection/ArrayList.php';
require_once 'dsn/IHandler.php';

/**
 * Reader for files.
 * 
 * This class can process a DSN to read a mapping from a file.
 * 
 * @author  $Author: pruna $
 * @package orm/reader
 * @version $Revision: 1.3 $
 * @created 05-May-2006
 * @modified $Date: 2005/12/06 02:56:45 $
 */
class OrmReaderFile extends Object implements IHandler {
    
    /**
     * @const
     */
    const READER_SCHEME_FILE = 'file';
    
    /**
     * Determines if this handler is the proper one for this DSN.
     *
     * @access    public
     * @param     DSN       $dsn     DSN that should see if is able to handle
     * @return    boolean
     */
    public function canHandle($dsn) {
        if ($dsn->getScheme() === self::READER_SCHEME_FILE) {
            return TRUE;
        }
        return FALSE;
    }
    
    /**
     * Handles the object.
     * 
     * If you call this method, it's assumed that <em>canHandle</em> has 
     * returned true.
     * 
     * @access    public
     * @param     DSN        $dsn      DSN to handle
     * @param     object     $caller   Caller object
     * @return    mixed
     */
    public function handle($dsn, $caller) {
        // Add dsn's path and mapsPaths defined for caller, as available ones
        $paths = new ArrayList();
        $paths->add($dsn->getFolder());
        if (!is_null($caller->getMapsPaths())) {
            $paths->addAll(Collection::castCollection($caller->getMapsPaths()));
            if (is_string($caller->getMapsPaths())) {
                $paths->add($caller->getMapsPaths());
            }
        }
        $file = simplexml_load_file(
                FileSystemUtils::getFilePath($dsn->getFile(), $paths));
        
        return $this->processVars($file->map, $dsn);
    }
    
    /**
     * Process query vars.
     * 
     * Process query vars passed to DSN. It can handle <em>xpath</em> and 
     * <em>uid</em> vars.
     * 
     * @access    protected
     * @param     DSN        $dsn      DSN to handle
     * @param     object     $caller   Caller object
     * @return    mixed
     */
    protected function processVars($xml, $dsn) {
        $vars = $dsn->getQueryVars();
        if (isset($vars['xpath'])) {
            $simpleXml = $xml->xpath($vars['xpath']);
            return $simpleXml[0];
        } elseif (isset($vars['uid'])) {
            $simpleXml = $xml->xpath('//[@uid="' . $vars['uid'] . '"]');
            return $simpleXml[0];
        }
        return $xml;
    }
}

?>