private function parseXml(SimpleXMLElement $xml, PiBX_AST_Tree $ast, $parentObject) { $count = $ast->countChildren(); if (!$xml->children()) { // a leaf node in the XML documents doesn't need to be parsed any further return (string) $xml; } if ($count == 0) { if ($ast instanceof PiBX_AST_Structure) { $newObject = $this->parseStructure($xml, $ast, $parentObject); } else { throw new RuntimeException('Not supported yet'); } } else { $newObject = $parentObject; for ($i = 0; $i < $count; $i++) { $child = $ast->get($i); $name = $child->getName(); $childXml = $xml->{$name}; if ($child instanceof PiBX_AST_Structure) { $newObject = $this->parseStructure($xml->{$name}, $child, $parentObject); } elseif ($child instanceof PiBX_AST_Collection) { $name = $ast->getName(); $list = $this->parseCollection($xml, $child, $parentObject); $setter = $child->getSetMethod(); $parentObject->{$setter}($list); } elseif ($child instanceof PiBX_AST_TypeAttribute) { $newObject = $this->parseTypeAttribute($xml, $child, $parentObject); } else { throw new RuntimeException('Not supported yet'); } } } return $newObject; }
/** * XSD-Choice elements are handled via private variables/constants * * @param PiBX_AST_Tree $tree * @return array The choice constants as strings */ public static function createChoiceConstantsFor(PiBX_AST_Tree $tree) { $childCount = $tree->countChildren(); $name = strtoupper($tree->getName()); $names = array(); for ($i = 0; $i < $childCount; ++$i) { $child = $tree->get($i); $childName = strtoupper($child->getName()); $names[] = $name . '_' . $childName . '_CHOICE'; } return $names; }
private function parseMapping(SimpleXMLElement $xml, PiBX_AST_Tree $part) { $nodes = $xml->xpath('./*'); foreach ($nodes as &$child) { $name = (string) $child->getName(); $attributes = $child->attributes(); if ($name == 'collection') { $name = (string) $attributes['name']; $setter = (string) $attributes['set-method']; $getter = (string) $attributes['get-method']; $newPart = new PiBX_AST_Collection($name); $newPart->setSetMethod($setter); $newPart->setGetMethod($getter); $class = (string) $attributes['class']; $this->classMap[$name] = $class; $this->elementAsts[$name] = $newPart; $this->parseMapping($child, $newPart); } elseif ($name == 'structure') { $name = (string) $attributes['name']; if ($part instanceof PiBX_AST_Collection) { // a structure in a collection is a reference to the actual structure $referencedType = (string) $attributes['map-as']; $type = $this->getClassnameForName($referencedType); $newPart = new PiBX_AST_Structure($name); $newPart->setType($type); $this->structuralReferences[$referencedType] = $name; } elseif ($part instanceof PiBX_AST_Type) { $referencedType = (string) $attributes['map-as']; $type = $this->getClassnameForName($referencedType); // a structure in a type is the structure "container" $newPart = new PiBX_AST_Structure($name, $type); $getMethod = (string) $attributes['get-method']; $setMethod = (string) $attributes['set-method']; $newPart->setGetMethod($getMethod); $newPart->setSetMethod($setMethod); } elseif ($part instanceof PiBX_AST_Structure) { $ordered = (string) $attributes['ordered']; $ordered = strtolower($ordered); $choice = (string) $attributes['choice']; $choice = strtolower($choice); if ($ordered == 'true' && $choice == 'false') { $part->setStructureType(PiBX_AST_StructureType::ORDERED()); } elseif ($ordered == 'false' && $choice == 'true') { $part->setStructureType(PiBX_AST_StructureType::CHOICE()); } else { throw new RuntimeException('Invalid structure state!'); } $structureValues = $child->xpath('./*'); // this handling is a bit clunky but needed, // since the choice structures are defined // somewhat redundant in the binding.xml foreach ($structureValues as &$struct) { $valueName = (string) $struct->getName(); if ($valueName != 'value') { throw new RuntimeException('No value-element within the structure.'); } $attributes = $struct->attributes(); $nameAttribute = (string) $attributes['name']; $newPart = new PiBX_AST_StructureElement($nameAttribute); $style = (string) $attributes['style']; $testMethod = (string) $attributes['test-method']; $getMethod = (string) $attributes['get-method']; $setMethod = (string) $attributes['set-method']; $newPart->setStyle($style); $newPart->setTestMethod($testMethod); $newPart->setGetMethod($getMethod); $newPart->setSetMethod($setMethod); $part->add($newPart); $this->elementAsts[$nameAttribute] = $newPart; } // no further processing needed // all structure values have been added break; } $this->elementAsts[$name] = $newPart; $this->parseMapping($child, $newPart); } elseif ($name == 'value') { $name = (string) $attributes['name']; if ($part instanceof PiBX_AST_Collection) { $newPart = new PiBX_AST_CollectionItem($name); } elseif ($part instanceof PiBX_AST_Type) { $newPart = new PiBX_AST_TypeAttribute($name); $style = (string) $attributes['style']; $setMethod = (string) $attributes['set-method']; $getMethod = (string) $attributes['get-method']; $newPart->setStyle($style); $newPart->setSetMethod($setMethod); $newPart->setGetMethod($getMethod); } $this->elementAsts[$name] = $newPart; } else { throw new InvalidArgumentException('Unexpected binding element "' . $name . '"'); } $part->add($newPart); } }
public function __construct($name = '', $type = '') { parent::__construct($name, $type); $this->isRootType = false; }
public function visitTypeAttributeEnter(PiBX_AST_Tree $tree) { if ($tree->countChildren() == 0) { // base type attribute $attributeName = PiBX_Binding_Names::getAttributeName($tree->getName()); $methodName = PiBX_Binding_Names::getCamelCasedName($tree->getName()); $this->currentClassAttributes .= "\tprivate \$" . $attributeName . ";\n"; $type = $tree->getType(); $methods = "\tpublic function set" . $methodName . "("; if (!PiBX_ParseTree_BaseType::isBaseType($type)) { // complexTypes (i.e. classes) have to be type-hinted // in the method signature. $expectedType = PiBX_Binding_Names::createClassnameFor($type); $methods .= $expectedType . ' '; } $methods .= "\$" . $attributeName . ") {\n"; if ($this->doTypeChecks) { $methods .= $this->typeChecks->getTypeCheckFor($tree->getType(), $attributeName); } $methods .= "\t\t\$this->" . $attributeName . " = \$" . $attributeName . ";\n" . "\t}\n" . "\tpublic function get" . $methodName . "() {\n" . "\t\treturn \$this->" . $attributeName . ";\n" . "\t}\n"; $this->currentClassMethods .= $methods; return false; } else { return true; } }
public function add(PiBX_AST_Tree $tree) { $this->children[] = $tree; $tree->setParent($this); return $this; }
public function __construct($name = '', $type = '') { parent::__construct($name, $type); }
public function __construct($name = '', $type = '') { parent::__construct($name, $type); $this->style = 'element'; }
/** * Converts the given parameter $object into its XML representation corresponding * to its AST. * * @param object $object The object to marshal * @param PiBX_AST_Tree $ast object's AST * @return void */ private function marshalObject($object, PiBX_AST_Tree $ast) { $astName = $ast->getName(); $lastNode = $this->currentDomNode; if ($astName != '') { // for every named element, a new node in the resulting xml-tree is created $this->currentDomNode = $this->dom->createElement($astName); $this->parentDomNode->appendChild($this->currentDomNode); } else { // "anonymous" elements are just chained down. No new node has to be created $this->currentDomNode = $this->parentDomNode; } if ($ast instanceof PiBX_AST_Type) { $this->marshalType($object, $ast); } elseif ($ast instanceof PiBX_AST_Collection) { $this->marshalCollection($object, $ast); } elseif ($ast instanceof PiBX_AST_Structure) { $this->marshalStructure($object, $ast); } elseif ($ast instanceof PiBX_AST_TypeAttribute) { $this->marshalTypeAttribute($object, $ast); } elseif ($ast instanceof PiBX_AST_StructureElement) { $this->marshalStructureElement($object, $ast); } elseif (is_string($object) || $ast instanceof PiBX_AST_CollectionItem) { $newNode = $this->dom->createTextNode($object); $this->currentDomNode->appendChild($newNode); } else { throw new RuntimeException('Currently not supported: ' . get_class($ast)); } }
public function visitTypeAttributeEnter(PiBX_AST_Tree $tree) { if ($tree->countChildren() == 0) { if (PiBX_ParseTree_BaseType::isBaseType($tree->getType())) { $this->xml .= '<value style="' . $tree->getStyle() . '"'; $this->xml .= ' name="' . $tree->getName() . '"'; $getter = PiBX_Binding_Names::createGetterNameFor($tree); $setter = PiBX_Binding_Names::createSetterNameFor($tree); $this->xml .= ' get-method="' . $getter . '"'; $this->xml .= ' set-method="' . $setter . '"'; $this->xml .= '/>'; } else { $this->xml .= '<structure map-as="' . $tree->getType() . '"'; $getter = PiBX_Binding_Names::createGetterNameFor($tree); $setter = PiBX_Binding_Names::createSetterNameFor($tree); $this->xml .= ' get-method="' . $getter . '"'; $this->xml .= ' set-method="' . $setter . '"'; $this->xml .= ' name="' . $tree->getName() . '"'; $this->xml .= '/>'; } return false; } else { return true; } }