BaseBuilder.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2006-2007 by Konstantin V. Arkhipov                     *
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 /* $Id: BaseBuilder.class.php 4687 2007-12-09 18:57:18Z voxus $ */
00012 
00016     abstract class BaseBuilder extends StaticFactory
00017     {
00018         public static function build(MetaClass $class)
00019         {
00020             throw new UnimplementedFeatureException('i am forgotten method');
00021         }
00022         
00023         protected static function buildFillers(MetaClass $class)
00024         {
00025             $out = null;
00026             
00027             $className = $class->getName();
00028             $varName = strtolower($className[0]).substr($className, 1);
00029 
00030             $setters = array();
00031             $valueObjects = array();
00032             
00033             $standaloneFillers = array();
00034             $chainFillers = array();
00035             
00036             $joinedStandaloneFillers = array();
00037             $joinedChainFillers = array();
00038             
00039             $cascadeStandaloneFillers = array();
00040             $cascadeChainFillers = array();
00041             
00042             foreach ($class->getWithInternalProperties() as $property) {
00043                 
00044                 if (
00045                     ($property->getRelationId() == MetaRelation::ONE_TO_ONE)
00046                     && ($property->getFetchStrategyId() != FetchStrategy::LAZY)
00047                     && (
00048                         !$property->getType()->isGeneric()
00049                         && $property->getType() instanceof ObjectType
00050                         && (
00051                             $property->getType()->getClass()->getPattern()
00052                                 instanceof ValueObjectPattern
00053                         )
00054                     )
00055                 ) {
00056                     $cascadeChainFillers[] = $property->toDaoSetter($className, true);
00057                     $joinedChainFillers[] = $property->toDaoSetter($className, false);
00058                     
00059                     $valueObjects[ucfirst($property->getName())] =
00060                         $property->getType()->getClassName();
00061                 } elseif (
00062                     ($property->getRelationId() == MetaRelation::ONE_TO_ONE)
00063                     && ($property->getFetchStrategyId() != FetchStrategy::LAZY)
00064                 ) {
00065                     $buildSetter = false;
00066                     
00067                     if ($filler = $property->toDaoSetter($className, true)) {
00068                         self::processFiller(
00069                             $property,
00070                             $cascadeStandaloneFillers,
00071                             $cascadeChainFillers,
00072                             $filler
00073                         );
00074                         
00075                         $buildSetter = true;
00076                     }
00077                     
00078                     if (
00079                         ($property->getFetchStrategyId() == FetchStrategy::CASCADE)
00080                         || ($class->getFetchStrategyId() == FetchStrategy::CASCADE)
00081                     ) {
00082                         $nonJoin = true;
00083                     } else {
00084                         $nonJoin = false;
00085                     }
00086                     
00087                     if ($filler = $property->toDaoSetter($className, $nonJoin)) {
00088                         if ($nonJoin) {
00089                             if (
00090                                 (
00091                                     $property->getType()->getClass()->getPattern()
00092                                         instanceof SpookedClassPattern
00093                                 ) || (
00094                                     $property->getType()->getClass()->getPattern()
00095                                         instanceof SpookedEnumerationPattern
00096                                 )
00097                             ) {
00098                                 $prefix =
00099                                     '// forcing cascade strategy '
00100                                     .'due to spooked property'."\n";
00101                             } else {
00102                                 $prefix =
00103                                     '// forcing cascade strategy'
00104                                     ."\n";
00105                             }
00106                         } else
00107                             $prefix = null;
00108                         
00109                         // TODO: make it sane
00110                         if (substr($filler, 0, 2) == 'if') {
00111                             $joinedStandaloneFillers[] = $prefix.$filler;
00112                         } else {
00113                             $joinedChainFillers[] = $prefix.$filler;
00114                         }
00115                         
00116                         $buildSetter = true;
00117                     }
00118                     
00119                     if ($buildSetter)
00120                         $setters[] = $property->toDaoField($className);
00121                 } else {
00122                     $filler = $property->toDaoSetter($className);
00123                     
00124                     if ($filler !== null) {
00125                         
00126                         $setters[] = $property->toDaoField($className);
00127                         
00128                         self::processFiller(
00129                             $property,
00130                             $standaloneFillers,
00131                             $chainFillers,
00132                             $filler
00133                         );
00134                     }
00135                 }
00136             }
00137             
00138             if ($valueObjects) {
00139                 foreach ($valueObjects as $valueName => $valueClass) {
00140                     $out .=
00141                         "Singleton::getInstance('{$valueClass}DAO')->"
00142                         ."setQueryFields(\$query, \${$varName}->get{$valueName}());\n";
00143                 }
00144                 
00145                 $out .= "\n";
00146             }
00147             
00148             if ($class->getPattern() instanceof ValueObjectPattern)
00149                 $visibility = 'public';
00150             else
00151                 $visibility = 'protected';
00152             
00153             if ($setters) {
00154                 $out .= <<<EOT
00155         return
00156             \$query->
00157 
00158 EOT;
00159                 $out .= implode("->\n", $setters).";\n";
00160                 $out .= <<<EOT
00161         }
00162 
00163 EOT;
00164             } elseif ($class->getWithInternalProperties()) {
00165                 $out .= <<<EOT
00166         return \$query;
00167     }
00168 
00169 EOT;
00170             }
00171             
00172             if ($class->getTypeId() == MetaClassType::CLASS_ABSTRACT) {
00173                 $out .= <<<EOT
00174 
00175 protected function fillSelf({$class->getFinalParent()->getName()} \${$varName}, &\$array, \$prefix = null)
00176 {
00177 
00178 EOT;
00179                 if ($class->hasBuildableParent()) {
00180                     if (
00181                         $class->getParent()->getTypeId()
00182                         == MetaClassType::CLASS_ABSTRACT
00183                     ) {
00184                         $out .= <<<EOT
00185 parent::fillSelf(\${$varName}, \$array, \$prefix);
00186 
00187 
00188 EOT;
00189                     }
00190                 }
00191             } else {
00192                 $out .= <<<EOT
00193 
00197 {$visibility} function makeSelf(&\$array, \$prefix = null)
00198 {
00199 
00200 EOT;
00201                 if ($class->hasBuildableParent()) {
00202                     if (
00203                         ($class->getTypeId() == MetaClassType::CLASS_ABSTRACT)
00204                         || (
00205                             $class->getParent()->getTypeId()
00206                             != MetaClassType::CLASS_ABSTRACT
00207                         )
00208                     ) {
00209                         $out .= <<<EOT
00210 \${$varName} = parent::makeSelf(\$array, \$prefix);
00211 
00212 
00213 EOT;
00214                     } else {
00215                         $out .= <<<EOT
00216 \${$varName} = parent::fillSelf(\$this->createObject(), \$array, \$prefix);
00217 
00218 
00219 EOT;
00220                     }
00221                 } else {
00222                     if ($class->hasChilds()) {
00223                         $out .= <<<EOT
00224 \${$varName} = \$this->createObject();
00225 
00226 
00227 EOT;
00228                     } else {
00229                         $out .= <<<EOT
00230 \${$varName} = new {$className}();
00231 
00232 
00233 EOT;
00234                     }
00235                 }
00236             }
00237             
00238             if ($chainFillers) {
00239                 
00240                 $out .= "\${$varName}->\n";
00241                 
00242                 $out .= implode("->\n", $chainFillers).";\n\n";
00243             }
00244             
00245             if ($standaloneFillers) {
00246                 $out .= implode("\n", $standaloneFillers)."\n";
00247             }
00248 
00249             $out .= <<<EOT
00250             return \${$varName};
00251         }
00252 
00253 EOT;
00254             if ($cascadeChainFillers || $cascadeStandaloneFillers) {
00255                 $out .= <<<EOT
00256 
00260 {$visibility} function makeCascade(/* {$className} */ \${$varName}, &\$array, \$prefix = null)
00261 {
00262 
00263 EOT;
00264                 if ($class->getParent()) {
00265                     $out .= <<<EOT
00266 \${$varName} = parent::makeCascade(\${$varName}, \$array, \$prefix);
00267 
00268 
00269 EOT;
00270                 }
00271                 
00272                 if ($cascadeChainFillers) {
00273                     $out .= "\${$varName}->\n";
00274                     
00275                     $out .= implode("->\n", $cascadeChainFillers).";\n\n";
00276                 }
00277                 
00278                 if ($cascadeStandaloneFillers) {
00279                     $out .= implode("\n", $cascadeStandaloneFillers)."\n";
00280                 }
00281                 
00282                 $out .= <<<EOT
00283 return \${$varName};
00284 }
00285 
00286 EOT;
00287             }
00288             
00289             if ($joinedChainFillers || $joinedStandaloneFillers) {
00290                 if ($joinedChainFillers)
00291                     $chain = implode("->\n", $joinedChainFillers).';';
00292                 else
00293                     $chain = null;
00294                 
00295                 if ($joinedStandaloneFillers)
00296                     $alone = implode("\n", $joinedStandaloneFillers);
00297                 else
00298                     $alone = null;
00299                 
00300                 $out .= <<<EOT
00301 
00305 {$visibility} function makeJoiners(/* {$className} */ \${$varName}, &\$array, \$prefix = null)
00306 {
00307 
00308 EOT;
00309                 if ($class->getParent()) {
00310                     $out .= <<<EOT
00311 \${$varName} = parent::makeJoiners(\${$varName}, \$array, \$prefix);
00312 
00313 
00314 EOT;
00315                 }
00316                 
00317                 if ($chain) {
00318                     $out .= <<<EOT
00319 \${$varName}->
00320     {$chain}
00321 
00322 
00323 EOT;
00324                 }
00325                 
00326                 if ($alone)
00327                     $out .= $alone."\n";
00328                 
00329                 $out .= <<<EOT
00330 return \${$varName};
00331 }
00332 
00333 EOT;
00334             }
00335             
00336             $out .= <<<EOT
00337 }
00338 
00339 EOT;
00340             
00341             return $out;
00342         }
00343         
00344         protected static function buildPointers(MetaClass $class)
00345         {
00346             $out = null;
00347             
00348             if ($class->getFetchStrategyId() == FetchStrategy::CASCADE) {
00349                 $out .= <<<EOT
00350 public function getDefaultStrategyId()
00351 {
00352     return FetchStrategy::CASCADE;
00353 }
00354 
00355 
00356 EOT;
00357             }
00358             
00359             if (!$class->getPattern() instanceof AbstractClassPattern) {
00360                 if (
00361                     $class->getIdentifier()->getColumnName() !== 'id'
00362                 ) {
00363                     $out .= <<<EOT
00364 public function getIdName()
00365 {
00366     return '{$class->getIdentifier()->getColumnName()}';
00367 }
00368 
00369 EOT;
00370                 }
00371                 
00372                 $out .= <<<EOT
00373 public function getTable()
00374 {
00375     return '{$class->getTableName()}';
00376 }
00377 
00378 public function getObjectName()
00379 {
00380     return '{$class->getName()}';
00381 }
00382 
00383 public function getSequence()
00384 {
00385     return '{$class->getTableName()}_id';
00386 }
00387 EOT;
00388             } else {
00389                 $out .= <<<EOT
00390 // no get{Table,ObjectName,Sequence} for abstract class
00391 EOT;
00392             }
00393             
00394             if ($liaisons = $class->getReferencingClasses()) {
00395                 $uncachers = array();
00396                 foreach ($liaisons as $className) {
00397                     $uncachers[] = $className.'::dao()->uncacheLists();';
00398                 }
00399                 
00400                 $uncachers = implode("\n", $uncachers);
00401                 
00402                 $out .= <<<EOT
00403 
00404 
00405 public function uncacheLists()
00406 {
00407 {$uncachers}
00408 
00409 return parent::uncacheLists();
00410 }
00411 EOT;
00412             }
00413             
00414             if ($source = $class->getSourceLink()) {
00415                 $out .= <<<EOT
00416 
00417 
00418 public function getLinkName()
00419 {
00420     return '{$source}';
00421 }
00422 
00423 EOT;
00424             }
00425             
00426             return $out;
00427         }
00428         
00429         protected static function getHead()
00430         {
00431             $head = self::startCap();
00432             
00433             $head .=
00434                 ' *   This file is autogenerated - do not edit.'
00435                 .'                               *';
00436 
00437             return $head."\n".self::endCap();
00438         }
00439         
00440         protected static function startCap()
00441         {
00442             $version = ONPHP_VERSION;
00443             $date = date('Y-m-d H:i:s');
00444             
00445             $info = " *   Generated by onPHP-{$version} at {$date}";
00446             $info = str_pad($info, 77, ' ', STR_PAD_RIGHT).'*';
00447             
00448             $cap = <<<EOT
00449 <?php
00450 /*****************************************************************************
00451  *   Copyright (C) 2006-2007, onPHP's MetaConfiguration Builder.             *
00452 {$info}
00453 
00454 EOT;
00455 
00456             return $cap;
00457         }
00458         
00459         protected static function endCap()
00460         {
00461             $cap = <<<EOT
00462  *****************************************************************************/
00463 /* \$Id\$ */
00464 
00465 
00466 EOT;
00467             return $cap;
00468         }
00469         
00470         protected static function getHeel()
00471         {
00472             return '?>';
00473         }
00474         
00475         /* void */ private static function processFiller(
00476             MetaClassProperty $property,
00477             /* array */ &$standaloneFillers,
00478             /* array */ &$chainFillers,
00479             $filler
00480         )
00481         {
00482             if (
00483                 (
00484                     !$property->getType()->isGeneric()
00485                     || $property->getType() instanceof ObjectType
00486                 )
00487                 && !$property->isRequired()
00488                 && !(
00489                     $property->getType() instanceof ObjectType
00490                     && !$property->getType()->isGeneric()
00491                     && (
00492                         $property->getType()->getClass()->getPattern()
00493                             instanceof ValueObjectPattern
00494                     )
00495                 )
00496             )
00497                 $standaloneFillers[] =
00498                     implode(
00499                         "\n",
00500                         explode("\n", $filler)
00501                     );
00502             else
00503                 $chainFillers[] =
00504                     implode(
00505                         "\n",
00506                         explode("\n", $filler)
00507                     );
00508         }
00509     }
00510 ?>

Generated on Sun Dec 9 21:56:24 2007 for onPHP by  doxygen 1.5.4