00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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 ?>