DirectoryToObjectBinder.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2009 by Ivan Y. Khvostishkov                            *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00012     final class DirectoryToObjectBinder extends ObjectBuilder
00013     {
00014         private $identityMap = null;
00015         
00019         public static function create(EntityProto $proto)
00020         {
00021             return new self($proto);
00022         }
00023         
00024         public function __construct(EntityProto $proto)
00025         {
00026             parent::__construct($proto);
00027             
00028             $this->identityMap = new DirectoryContext;
00029         }
00030         
00031         public function setIdentityMap(DirectoryContext $identityMap)
00032         {
00033             $this->identityMap = $identityMap;
00034             
00035             return $this;
00036         }
00037         
00041         public function getIdentityMap()
00042         {
00043             return $this->identityMap;
00044         }
00045         
00049         public function cloneBuilder(EntityProto $proto)
00050         {
00051             $result = parent::cloneBuilder($proto);
00052             
00053             $result->setIdentityMap($this->identityMap);
00054             
00055             return $result;
00056         }
00057         
00058         public function cloneInnerBuilder($property)
00059         {
00060             $result = parent::cloneInnerBuilder($property);
00061             
00062             $result->setIdentityMap($this->identityMap);
00063             
00064             return $result;
00065         }
00066         
00070         public function makeReverseBuilder()
00071         {
00072             return
00073                 ObjectToDirectoryBinder::create($this->proto)->
00074                 setIdentityMap($this->identityMap);
00075         }
00076         
00077         public function make($object, $recursive = true)
00078         {
00079             Assert::isTrue(is_readable($object), "required object `$object` must exist");
00080             
00081             $realObject = $this->getRealObject($object);
00082             
00083             $result = $this->identityMap->lookup($realObject);
00084             
00085             if ($result)
00086                 return $result;
00087             
00088             $result = parent::make($realObject, $recursive);
00089             
00090             if ($result instanceof Identifiable)
00091                 $result->setId(basename($realObject));
00092             
00093             return $result;
00094         }
00095         
00096         protected function initialize($object, &$result)
00097         {
00098             parent::initialize($object, $result);
00099             
00100             $realObject = $this->getRealObject($object);
00101             
00102             $this->identityMap->bind($realObject, $result);
00103             
00104             return $this;
00105         }
00106         
00110         protected function getGetter($object)
00111         {
00112             return new DirectoryGetter($this->proto, $object);
00113         }
00114         
00118         protected function getSetter(&$object)
00119         {
00120             return new ObjectSetter($this->proto, $object);
00121         }
00122         
00123         private function getRealObject($object)
00124         {
00125             $result = $object;
00126             
00127             if (is_link($object)) {
00128                 $result = readlink($object);
00129                 
00130                 if ($result === false)
00131                     throw new WrongStateException("invalid link: $object");
00132                 
00133                 if (substr($result, 0, 1) !== DIRECTORY_SEPARATOR) {
00134                     $result = GenericUri::create()->
00135                         setScheme('file')->
00136                         setPath($object)->
00137                             transform(
00138                                 GenericUri::create()->
00139                                 setPath($result)
00140                             )->
00141                                 getPath();
00142                 }
00143             }
00144             
00145             $realResult = realpath($result);
00146             
00147             if ($realResult === false)
00148                 throw new WrongStateException(
00149                     "invalid context: $object ($result)"
00150                 );
00151             
00152             return $realResult;
00153         }
00154     }
00155 ?>