ObjectToDirectoryBinder.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 ObjectToDirectoryBinder extends DirectoryBuilder
00013     {
00017         public static function create(EntityProto $proto)
00018         {
00019             return new self($proto);
00020         }
00021         
00022         public function make($object, $recursive = true)
00023         {
00024             $this->checkDirectory();
00025 
00026             if (!$object) {
00027                 $this->safeClean();
00028 
00029                 return $this->directory;
00030             }
00031 
00032             $realDirectory = null;
00033 
00034             if (is_link($this->directory)) {
00035                 $realDirectory = readlink($this->directory);
00036 
00037                 if ($realDirectory === false)
00038                     throw new WrongStateException(
00039                         'invalid pointer: '.$this->directory
00040                     );
00041             }
00042 
00043             $reversePath = $this->identityMap->reverseLookup($object);
00044 
00045             if (
00046                 !$reversePath
00047                 && is_link($this->directory)
00048             ) {
00049                 throw new WrongStateException(
00050                     'you must always store your object somewhere '
00051                     .'before you going to update pointer '
00052                     .$this->directory
00053                 );
00054             }
00055 
00056             if (
00057                 $reversePath
00058                 && file_exists($this->directory)
00059                 && !$realDirectory
00060                 && $this->directory != $reversePath
00061             ) {
00062                 throw new WrongStateException(
00063                     'you should relocate object '
00064                     .$this->directory.' to '
00065                     .$reversePath
00066                     .' by yourself.'
00067                     .' cannot replace object with a link'
00068                 );
00069             }
00070 
00071             if (
00072                 $reversePath
00073                 && (
00074                     !file_exists($this->directory)
00075                     || $realDirectory
00076                 )
00077             ) {
00078                 if (
00079                     !$realDirectory
00080                     || $realDirectory != $reversePath
00081                 ) {
00082                     $this->safeClean();
00083 
00084                     $status = symlink($reversePath, $this->directory);
00085 
00086                     if ($status !== true)
00087                         throw new WrongStateException(
00088                             'error creating symlink'
00089                         );
00090                 }
00091 
00092                 return $reversePath;
00093             }
00094 
00095             $result = parent::make($object, $recursive);
00096 
00097             $this->identityMap->bind($result, $object);
00098 
00099             return $result;
00100         }
00101 
00105         public function makeReverseBuilder()
00106         {
00107             return
00108                 DirectoryToObjectBinder::create($this->proto)->
00109                 setIdentityMap($this->identityMap);
00110         }
00111 
00115         protected function getGetter($object)
00116         {
00117             return new ObjectGetter($this->proto, $object);
00118         }
00119         
00123         protected function getSetter(&$object)
00124         {
00125             return new DirectorySetter($this->proto, $object);
00126         }
00127     }
00128 ?>