MetaClass.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: MetaClass.class.php 4687 2007-12-09 18:57:18Z voxus $ */
00012 
00016     class MetaClass
00017     {
00018         private $name       = null;
00019         private $tableName  = null;
00020         private $type       = null;
00021         
00022         private $parent     = null;
00023         
00024         private $properties = array();
00025         private $interfaces = array();
00026         private $references = array();
00027         
00028         private $pattern    = null;
00029         private $identifier = null;
00030         
00031         private $source     = null;
00032         
00033         private $strategy   = null;
00034         
00035         private $build      = true;
00036         
00037         public function __construct($name)
00038         {
00039             $this->name = $name;
00040             
00041             $dumb = strtolower(
00042                 preg_replace(':([A-Z]):', '_\1', $name)
00043             );
00044             
00045             if ($dumb[0] == '_')
00046                 $this->tableName = substr($dumb, 1);
00047             else
00048                 $this->tableName = $dumb;
00049         }
00050         
00051         public function getName()
00052         {
00053             return $this->name;
00054         }
00055         
00056         public function getTableName()
00057         {
00058             return $this->tableName;
00059         }
00060         
00064         public function setTableName($name)
00065         {
00066             $this->tableName = $name;
00067             
00068             return $this;
00069         }
00070         
00074         public function getType()
00075         {
00076             return $this->type;
00077         }
00078         
00079         public function getTypeId()
00080         {
00081             return
00082                 $this->type
00083                     ? $this->type->getId()
00084                     : null;
00085         }
00086         
00090         public function setType(MetaClassType $type)
00091         {
00092             $this->type = $type;
00093             
00094             return $this;
00095         }
00096         
00100         public function getParent()
00101         {
00102             return $this->parent;
00103         }
00104         
00108         public function getFinalParent()
00109         {
00110             if ($this->parent)
00111                 return $this->parent->getFinalParent();
00112             
00113             return $this;
00114         }
00115         
00119         public function setParent(MetaClass $parent)
00120         {
00121             $this->parent = $parent;
00122             
00123             return $this;
00124         }
00125         
00126         public function hasBuildableParent()
00127         {
00128             return (
00129                 $this->parent
00130                 && (
00131                     !$this->getFinalParent()->getPattern()
00132                         instanceof InternalClassPattern
00133                 )
00134             );
00135         }
00136         
00137         public function getProperties()
00138         {
00139             return $this->properties;
00140         }
00141         
00143         public function getAllProperties()
00144         {
00145             if ($this->parent)
00146                 return array_merge(
00147                     $this->parent->getAllProperties(),
00148                     $this->properties
00149                 );
00150             
00151             return $this->getProperties();
00152         }
00153         
00155         public function getWithInternalProperties()
00156         {
00157             if (
00158                 $this->parent
00159                 && (
00160                     $this->getFinalParent()->getPattern()
00161                         instanceof InternalClassPattern
00162                 )
00163             ) {
00164                 $out = $this->properties;
00165                 
00166                 $class = $this;
00167                 
00168                 while ($parent = $class->getParent()) {
00169                     if ($parent->getPattern() instanceof InternalClassPattern) {
00170                         $out = array_merge($parent->getProperties(), $out);
00171                     }
00172                     
00173                     $class = $parent;
00174                 }
00175                 
00176                 return $out;
00177             }
00178             
00179             return $this->getProperties();
00180         }
00181         
00183         public function getParentsProperties()
00184         {
00185             $out = array();
00186             
00187             $class = $this;
00188             
00189             while ($parent = $class->getParent()) {
00190                 $out = array_merge($out, $parent->getProperties());
00191                 $class = $parent;
00192             }
00193             
00194             return $out;
00195         }
00196         
00200         public function addProperty(MetaClassProperty $property)
00201         {
00202             $name = $property->getName();
00203             
00204             if (!isset($this->properties[$name]))
00205                 $this->properties[$name] = $property;
00206             else
00207                 throw new WrongArgumentException(
00208                     "property '{$name}' already exist"
00209                 );
00210             
00211             if ($property->isIdentifier())
00212                 $this->identifier = $property;
00213             
00214             return $this;
00215         }
00216         
00221         public function getPropertyByName($name)
00222         {
00223             if (isset($this->properties[$name]))
00224                 return $this->properties[$name];
00225             
00226             throw new MissingElementException("unknown property '{$name}'");
00227         }
00228         
00229         public function hasProperty($name)
00230         {
00231             return isset($this->properties[$name]);
00232         }
00233         
00237         public function dropProperty($name)
00238         {
00239             if (isset($this->properties[$name])) {
00240                 
00241                 if ($this->properties[$name]->isIdentifier())
00242                     unset($this->identifier);
00243                 
00244                 unset($this->properties[$name]);
00245             
00246             } else
00247                 throw new MissingElementException(
00248                     "property '{$name}' does not exist"
00249                 );
00250             
00251             return $this;
00252         }
00253         
00254         public function getInterfaces()
00255         {
00256             return $this->interfaces;
00257         }
00258         
00262         public function addInterface($name)
00263         {
00264             $this->interfaces[] = $name;
00265             
00266             return $this;
00267         }
00268         
00272         public function getPattern()
00273         {
00274             return $this->pattern;
00275         }
00276         
00280         public function setPattern(GenerationPattern $pattern)
00281         {
00282             $this->pattern = $pattern;
00283             
00284             return $this;
00285         }
00286         
00290         public function getIdentifier()
00291         {
00292             // return parent's identifier, if we're child
00293             if (!$this->identifier && $this->parent)
00294                 return $this->parent->getIdentifier();
00295             
00296             return $this->identifier;
00297         }
00298         
00302         public function setSourceLink($link)
00303         {
00304             $this->source = $link;
00305             
00306             return $this;
00307         }
00308         
00309         public function getSourceLink()
00310         {
00311             return $this->source;
00312         }
00313         
00317         public function setReferencingClass($className)
00318         {
00319             $this->references[$className] = true;
00320             
00321             return $this;
00322         }
00323         
00324         public function getReferencingClasses()
00325         {
00326             return array_keys($this->references);
00327         }
00328         
00332         public function setFetchStrategy(FetchStrategy $strategy)
00333         {
00334             $this->strategy = $strategy;
00335             
00336             return $this;
00337         }
00338         
00342         public function getFetchStrategy()
00343         {
00344             return $this->strategy;
00345         }
00346         
00347         public function getFetchStrategyId()
00348         {
00349             if ($this->strategy)
00350                 return $this->strategy->getId();
00351             
00352             return null;
00353         }
00354         
00355         public function hasChilds()
00356         {
00357             foreach (MetaConfiguration::me()->getClassList() as $class) {
00358                 if (
00359                     $class->getParent()
00360                     && $class->getParent()->getName() == $this->getName()
00361                 )
00362                     return true;
00363             }
00364             
00365             return false;
00366         }
00367         
00368         public function dump()
00369         {
00370             if ($this->doBuild())
00371                 return $this->pattern->build($this);
00372             
00373             return $this->pattern;
00374         }
00375         
00376         public function doBuild()
00377         {
00378             return $this->build;
00379         }
00380         
00384         public function setBuild($do)
00385         {
00386             $this->build = $do;
00387             
00388             return $this;
00389         }
00390         
00391         public function toComplexType(&$containers, $withoutSoap)
00392         {
00393             $abstractType =
00394                 ($this->pattern instanceof AbstractClassPattern)
00395                     ? " abstract=\"true\" "
00396                     : null;
00397             
00398             $element =
00399 <<<XML
00400 
00401     <complexType name="{$this->getName()}"
00402                     {$abstractType}
00403     >
00404 
00405 XML;
00406             
00407             if ($this->getParent()) {
00408                 $element .=
00409 <<<XML
00410 
00411         <complexContent>
00412             <extension base="tns:{$this->getParent()->getName()}">
00413 
00414 XML;
00415             }
00416             
00417             $element .=
00418 <<<XML
00419         <sequence>
00420 XML;
00421             
00422             foreach ($this->properties as $property) {
00423                 $generateRestriction = false;
00424             
00425                 $element .=
00426 <<<XML
00427 
00428             <element
00429                 name="{$property->getName()}"
00430                 
00431 XML;
00432                     $xsdType = null;
00433                     
00434                     if ($property->getType() instanceof ObjectType) {
00435                         if (
00436                             $property->getRelation()
00437                             &&
00438                                 $property->getRelation()->getId()
00439                                 == MetaRelation::ONE_TO_MANY
00440                         ) {
00441                             $containerName =
00442                                 self::makeXsdContainerName(
00443                                     $property->getType()
00444                                 );
00445                             
00446                             $containers[$containerName] = $property->getType();
00447                             
00448                             $xsdType = "tns:" . $containerName;
00449                         } else
00450                             $xsdType = $property->getType()->toXsdType();
00451                     } else
00452                         $xsdType = $property->getType()->toXsdType();
00453                 
00454                 if ($property->getSize()) {
00455                     if (!$withoutSoap) {
00456                         if ($property->getType() instanceof FixedLengthStringType)
00457                             $element .= " minLength=\"" . $property->getSize() . "\" ";
00458                         
00459                         $element .= " maxLength=\"" . $property->getSize() . "\" ";
00460                     } else
00461                         $generateRestriction = true;
00462                 }
00463                 
00464                 if ($generateRestriction) {
00465                     $element .= <<<XML
00466                             >
00467                 <simpleType>
00468                     <xsd:restriction base="{$xsdType}">
00469                         <xsd:maxLength value="{$property->getSize()}"/>
00470                     </xsd:restriction>
00471                 </simpleType>
00472 XML;
00473                 } else {
00474                     $element .=
00475 <<<XML
00476                 type="{$xsdType}"
00477 XML;
00478                 }
00479 
00480                 
00481                 if ($generateRestriction) {
00482                     $element .= <<<XML
00483                     
00484             </element>
00485 XML;
00486                 } else {
00487                     $element .= <<<XML
00488                             />
00489 XML;
00490                 }
00491             }
00492             
00493             $element .=
00494 <<<XML
00495 
00496         </sequence>
00497 XML;
00498             
00499             if ($this->getParent()) {
00500                 $element .=
00501 <<<XML
00502 
00503             </extension>
00504         </complexContent>
00505 XML;
00506             }
00507             
00508             $element .=
00509 <<<XML
00510 
00511     </complexType>
00512 
00513 XML;
00514             
00515             return $element;
00516         }
00517         
00518         public static function buildXsdContainer(
00519             ObjectType $object, $withoutSoap = false
00520         )
00521         {
00522             $typeName = self::makeXsdContainerName($object);
00523             
00524             if (!$withoutSoap) {
00525                 $containerXml =
00526 <<<XML
00527     <complexType name="{$typeName}">
00528         <complexContent>
00529             <restriction base="soapenc:Array">
00530                 <attribute
00531                     ref="soapenc:arrayType"
00532                     wsdl:arrayType="tns:{$object->getClass()->getName()}[]"
00533                 />
00534             </restriction>
00535         </complexContent>
00536     </complexType>
00537 
00538 XML;
00539             } else {
00540                 $className = mb_strtolower($object->getClass()->getName());
00541                 
00542                 $containerXml =
00543 <<<XML
00544     <complexType name="{$typeName}">
00545         <sequence>
00546             <element
00547                 name="{$className}"
00548                 minOccurs="0"
00549                 maxOccurs="unbounded"
00550                 type="tns:{$object->getClass()->getName()}"
00551             />
00552         </sequence>
00553     </complexType>
00554 
00555 XML;
00556                 }
00557                 
00558                 return $containerXml;
00559         }
00560         
00561         private static function makeXsdContainerName(ObjectType $object)
00562         {
00563             return $object->getClass()->getName() . 'List';
00564         }
00565     }
00566 ?>

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