Exemple #1
0
 public function testEasyPoXSD()
 {
     $filepath = dirname(__FILE__) . '/../../_files/EasyPO/';
     $schema = simplexml_load_file($filepath . '/easypo.xsd');
     $parser = new PiBX_CodeGen_SchemaParser();
     $parser->setSchema($schema);
     $parsedTree = $parser->parse();
     $namespaces = array('xs' => 'http://www.w3.org/2001/XMLSchema', 'po' => 'http://openuri.org/easypo');
     $expectedTypeList = array();
     $expectedType1 = new PiBX_AST_Type('purchase-order');
     $expectedType1->setAsRoot();
     $expectedType1->setTargetNamespace('http://openuri.org/easypo');
     $expectedType1->setNamespaces($namespaces);
     $expectedType1->add(new PiBX_AST_TypeAttribute('customer', 'customer'));
     $expectedType1->add(new PiBX_AST_TypeAttribute('date', 'dateTime'));
     $ta = new PiBX_AST_TypeAttribute('line-item', 'line-item');
     $ta->add(new PiBX_AST_CollectionItem('line-item', 'line-item'));
     $expectedType1->add($ta);
     $expectedType1->add(new PiBX_AST_TypeAttribute('shipper', 'shipper'));
     $expectedType2 = new PiBX_AST_Type('customer');
     $expectedType2->add(new PiBX_AST_TypeAttribute('name', 'string'));
     $expectedType2->add(new PiBX_AST_TypeAttribute('address', 'string'));
     $ta = new PiBX_AST_TypeAttribute('age', 'int');
     $ta->setStyle('attribute');
     $expectedType2->add($ta);
     $ta = new PiBX_AST_TypeAttribute('moo', 'int');
     $ta->setStyle('attribute');
     $expectedType2->add($ta);
     $ta = new PiBX_AST_TypeAttribute('poo', 'int');
     $ta->setStyle('attribute');
     $expectedType2->add($ta);
     $expectedType3 = new PiBX_AST_Type('line-item');
     $expectedType3->add(new PiBX_AST_TypeAttribute('description', 'string'));
     $expectedType3->add(new PiBX_AST_TypeAttribute('per-unit-ounces', 'decimal'));
     $expectedType3->add(new PiBX_AST_TypeAttribute('price', 'decimal'));
     $expectedType3->add(new PiBX_AST_TypeAttribute('quantity', 'integer'));
     $expectedType4 = new PiBX_AST_Type('shipper');
     $expectedType4->add(new PiBX_AST_TypeAttribute('name', 'string'));
     $expectedType4->add(new PiBX_AST_TypeAttribute('per-ounce-rate', 'decimal'));
     $parser = new PiBX_CodeGen_SchemaParser();
     $parser->setSchema($schema);
     $tree = $parser->parse();
     $creator = new PiBX_CodeGen_ASTCreator(new PiBX_CodeGen_TypeUsage());
     $tree->accept($creator);
     $typeList = $creator->getTypeList();
     $this->assertEquals(4, count($typeList));
     $this->assertEquals($expectedType1, $typeList[0]);
     $this->assertEquals($expectedType2, $typeList[1]);
     $this->assertEquals($expectedType3, $typeList[2]);
     $this->assertEquals($expectedType4, $typeList[3]);
 }
Exemple #2
0
 private function parseTypeAttribute(SimpleXMLElement $xml, PiBX_AST_TypeAttribute $ast, $parentObject)
 {
     $name = $ast->getName();
     if ($ast->getStyle() == 'element') {
         $value = (string) $xml->{$name};
     } elseif ($ast->getStyle() == 'attribute') {
         $attributes = $xml->attributes();
         $value = (string) $attributes[$name];
     }
     $setter = $ast->getSetMethod();
     $parentObject->{$setter}($value);
     return $parentObject;
 }
Exemple #3
0
 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);
     }
 }
Exemple #4
0
 function visitElementNode(PiBX_ParseTree_Tree $tree)
 {
     $this->plowTypesForLevel($tree->getLevel());
     $logMessage = $tree->getLevel() . str_pad("  ", $tree->getLevel()) . " element";
     if ($tree->isAnonym()) {
         $logMessage .= " <anonym>";
     } else {
         $logMessage .= " (" . $tree->getName() . ")";
     }
     if ($tree->getLevel() > 0) {
         if ($this->currentType() instanceof PiBX_AST_Type) {
             $ta = new PiBX_AST_TypeAttribute($tree->getName());
             $ta->setType($tree->getType());
             $schemaType = $tree->getType();
             $sf = new PiBX_CodeGen_ASTStackFrame($tree->getLevel(), $ta);
             array_push($this->stack, $sf);
             // elements with maxOccurs "unbounded" are collections/lists
             // with no parent collection element.
             if ($tree->getMaxOccurs() == 'unbounded') {
                 $ci = new PiBX_AST_CollectionItem($tree->getName());
                 $ci->setType($tree->getType());
                 $sf = new PiBX_CodeGen_ASTStackFrame($tree->getLevel(), $ci);
                 array_push($this->stack, $sf);
             }
         } elseif ($this->currentType() instanceof PiBX_AST_Collection) {
             $ci = new PiBX_AST_CollectionItem($tree->getName());
             $ci->setType($tree->getType());
             $sf = new PiBX_CodeGen_ASTStackFrame($tree->getLevel(), $ci);
             array_push($this->stack, $sf);
         } elseif ($this->currentType() instanceof PiBX_AST_Structure) {
             $se = new PiBX_AST_StructureElement($tree->getName(), $tree->getType());
             $sf = new PiBX_CodeGen_ASTStackFrame($tree->getLevel(), $se);
             array_push($this->stack, $sf);
         }
     } elseif ($tree->getLevel() == 0) {
         $logMessage .= " - global";
         $t = new PiBX_AST_Type($tree->getName());
         if ($this->countTypes() == 0) {
             // the first type is the XSD-root.
             $t->setAsRoot();
             $t->setTargetNamespace($tree->getParent()->getTargetNamespace());
             $t->setNamespaces($tree->getNamespaces());
         }
         $sf = new PiBX_CodeGen_ASTStackFrame(-1, $t);
         array_push($this->stack, $sf);
         /*
          * Yes, add it two times.
          * It's a limitation that exist in the current implementation
          * of the TypeUsage-class.
          * The concrete class (which is the root element/type of a schema)
          * will not be referenced more than one time (at the definition).
          * But it must not be removed in an AST optimization afterwards,
          * so we just increase the usage-counter by one.
          */
         $this->typeUsage->addType($tree->getName());
         $this->typeUsage->addType($tree->getName());
     } else {
         throw new RuntimeException('invalid element state');
     }
     $this->lastLevel = $tree->getLevel();
     $this->log($logMessage);
 }
Exemple #5
0
 public function testBooksBinding()
 {
     $filepath = dirname(__FILE__) . '/../_files/Books';
     $bindingFile = $filepath . '/binding.xml';
     $expectedXml = file_get_contents($bindingFile);
     $binding = new PiBX_Runtime_Binding($bindingFile);
     $asts = $binding->parse();
     $this->assertEquals(2, count($asts));
     // first tree/type
     $expectedAst1 = new PiBX_AST_Type('Collection');
     $expectedAst1->setType('Collection');
     $expectedAst1->setAsRoot();
     $collection = new PiBX_AST_Collection('books');
     $collection->setGetMethod('getBooks');
     $collection->setSetMethod('setBooks');
     $structure = new PiBX_AST_Structure('book');
     $structure->setType('BookType');
     $expectedAst1->add($collection->add($structure));
     $this->assertEquals($expectedAst1, $asts[0]);
     // second tree/type
     $expectedAst2 = new PiBX_AST_Type('bookType');
     $expectedAst2->setType('BookType');
     $value1 = new PiBX_AST_TypeAttribute('name');
     $value1->setStyle('element');
     $value1->setGetMethod('getName');
     $value1->setSetMethod('setName');
     $expectedAst2->add($value1);
     $value2 = new PiBX_AST_TypeAttribute('ISBN');
     $value2->setStyle('element');
     $value2->setGetMethod('getISBN');
     $value2->setSetMethod('setISBN');
     $expectedAst2->add($value2);
     $value3 = new PiBX_AST_TypeAttribute('price');
     $value3->setStyle('element');
     $value3->setGetMethod('getPrice');
     $value3->setSetMethod('setPrice');
     $expectedAst2->add($value3);
     $value4 = new PiBX_AST_Collection('authors');
     $value4->setGetMethod('getAuthorNames');
     $value4->setSetMethod('setAuthorNames');
     $value4item = new PiBX_AST_CollectionItem('authorName');
     $value4->add($value4item);
     $expectedAst2->add($value4);
     $value5 = new PiBX_AST_TypeAttribute('description');
     $value5->setStyle('element');
     $value5->setGetMethod('getDescription');
     $value5->setSetMethod('setDescription');
     $expectedAst2->add($value5);
     $value6 = new PiBX_AST_Structure('promotion');
     $value6->setStructureType(PiBX_AST_StructureType::CHOICE());
     $value6Item1 = new PiBX_AST_StructureElement('Discount');
     $value6Item1->setTestMethod('ifPromotionDiscount');
     $value6Item1->setGetMethod('getPromotionDiscount');
     $value6Item1->setSetMethod('setPromotionDiscount');
     $value6Item1->setStyle('element');
     $value6Item2 = new PiBX_AST_StructureElement('None');
     $value6Item2->setTestMethod('ifPromotionNone');
     $value6Item2->setGetMethod('getPromotionNone');
     $value6Item2->setSetMethod('setPromotionNone');
     $value6Item2->setStyle('element');
     $value6->add($value6Item1);
     $value6->add($value6Item2);
     $expectedAst2->add($value6);
     $value7 = new PiBX_AST_TypeAttribute('publicationDate');
     $value7->setStyle('element');
     $value7->setGetMethod('getPublicationDate');
     $value7->setSetMethod('setPublicationDate');
     $expectedAst2->add($value7);
     $value8 = new PiBX_AST_TypeAttribute('bookCategory');
     $value8->setStyle('element');
     $value8->setGetMethod('getBookCategory');
     $value8->setSetMethod('setBookCategory');
     $expectedAst2->add($value8);
     $value9 = new PiBX_AST_TypeAttribute('itemId');
     $value9->setStyle('attribute');
     $value9->setGetMethod('getItemId');
     $value9->setSetMethod('setItemId');
     $expectedAst2->add($value9);
     $this->assertEquals($expectedAst2, $asts[1]);
 }
Exemple #6
0
 public function testBooksExampleXSD()
 {
     $data = file_get_contents(dirname(__FILE__) . '/../_files/Books/books.xsd');
     $expectedTypeList = array();
     $expectedType1 = new PiBX_AST_Type('Collection');
     $expectedType1->setAsRoot();
     $expectedType1->setAttributeCount(1);
     $expectedType1->setNamespaces(array('xs' => 'http://www.w3.org/2001/XMLSchema'));
     $ta = new PiBX_AST_TypeAttribute('books');
     $c = new PiBX_AST_Collection();
     $ci = new PiBX_AST_CollectionItem('book');
     $ci->setType('bookType');
     $expectedType1->add($ta);
     $ta->add($c);
     $c->add($ci);
     $expectedTypeList[] = $expectedType1;
     $expectedType2 = new PiBX_AST_Type('bookType');
     $expectedType2->setAttributeCount(8);
     $expectedType2->add(new PiBX_AST_TypeAttribute('name', 'string'));
     $expectedType2->add(new PiBX_AST_TypeAttribute('ISBN', 'long'));
     $expectedType2->add(new PiBX_AST_TypeAttribute('price', 'string'));
     $ta = new PiBX_AST_TypeAttribute('authors');
     $c = new PiBX_AST_Collection();
     $ci = new PiBX_AST_CollectionItem('authorName', 'string');
     $c->add($ci);
     $ta->add($c);
     $expectedType2->add($ta);
     $expectedType2->add(new PiBX_AST_TypeAttribute('description', 'string'));
     $ta = new PiBX_AST_TypeAttribute('promotion');
     $s = new PiBX_AST_Structure();
     $s->setStructureType(PiBX_AST_StructureType::CHOICE());
     $s->add(new PiBX_AST_StructureElement('Discount', 'string'));
     $s->add(new PiBX_AST_StructureElement('None', 'string'));
     $ta->add($s);
     $expectedType2->add($ta);
     $expectedType2->add(new PiBX_AST_TypeAttribute('publicationDate', 'date'));
     $ta = new PiBX_AST_TypeAttribute('bookCategory');
     $e = new PiBX_AST_Enumeration();
     $e->add(new PiBX_AST_EnumerationValue('magazine', 'string'));
     $e->add($ev = new PiBX_AST_EnumerationValue('novel', 'string'));
     $e->add($ev = new PiBX_AST_EnumerationValue('fiction', 'string'));
     $e->add($ev = new PiBX_AST_EnumerationValue('other', 'string'));
     $ta->add($e);
     $expectedType2->add($ta);
     $ta = new PiBX_AST_TypeAttribute('itemId', 'string');
     $ta->setStyle('attribute');
     $expectedType2->add($ta);
     $expectedTypeList[] = $expectedType2;
     $enumeration = new PiBX_AST_Enumeration();
     $enumeration->add(new PiBX_AST_EnumerationValue('magazine', 'string'));
     $enumeration->add(new PiBX_AST_EnumerationValue('novel', 'string'));
     $enumeration->add(new PiBX_AST_EnumerationValue('fiction', 'string'));
     $enumeration->add(new PiBX_AST_EnumerationValue('other', 'string'));
     $expectedType3 = new PiBX_AST_Type('bookCategoryType');
     $expectedType3->add($enumeration);
     $expectedTypeList[] = $expectedType3;
     $schema = simplexml_load_string($data);
     $parser = new PiBX_CodeGen_SchemaParser();
     $parser->setSchema($schema);
     $tree = $parser->parse();
     $creator = new PiBX_CodeGen_ASTCreator(new PiBX_CodeGen_TypeUsage());
     $tree->accept($creator);
     $typeList = $creator->getTypeList();
     $this->assertEquals(3, count($typeList));
     $this->assertEquals($expectedType1, $typeList[0]);
     $this->assertEquals($expectedType2, $typeList[1]);
     $this->assertEquals($expectedType3, $typeList[2]);
 }
Exemple #7
0
 private function marshalTypeAttribute($object, PiBX_AST_TypeAttribute $ast)
 {
     if ($ast->getStyle() == 'element') {
         $getter = $ast->getGetMethod();
         $value = $object->{$getter}();
         $newNode = $this->dom->createTextNode($value);
         $this->currentDomNode->appendChild($newNode);
     } elseif ($ast->getStyle() == 'attribute') {
         $getter = $ast->getGetMethod();
         $name = $ast->getName();
         $value = $object->{$getter}();
         if ($value != '') {
             // TODO check for "optional" attribute in binding.
             $this->parentDomNode->setAttribute($name, $value);
         }
         // in marshalObject() a child is added everytime.
         // no matter what type it is ("attribute" or "element"),
         // so we can just remove it here
         $this->parentDomNode->removeChild($this->currentDomNode);
     } else {
         throw new RuntimeException('Invalid TypeAttribute style "' . $ast->getStyle() . '"');
     }
 }