/**
  * <p>
  * Reads and returns a <tt>DataObject</tt> representing the object to be
  * cached saved to the database. If the object has already been read into
  * the cache, the cached object will be returned instead.
  * </p>
  * <p>
  * If the object is a reference object (i.e. <tt>&lt;object ref="{object-id}" /></tt>)
  * then we attempt to resolve the object reference and return that as the
  * read <tt>DataObject</tt>. Otherwise, the <tt>&lt;object></tt> element is
  * parsed. If a reference cannot be obtained within the current
  * <tt>DataSource</tt>, the search will be extended to other data sources
  * associated with the attributed <tt>$populator</tt>.
  * </p>
  * <p>
  * When parsing an <tt>&lt;object></tt> element we read all of the
  * <tt>&lt;property></tt> elements and parse their values, assigning them
  * to the <tt>DataObject</tt>. Once
  * </p>
  *
  * @param XmlElement $element
  * @return \Rhapsody\SetupBundle\Data\DataObject the <tt>DataObject</tt>.
  */
 public function parseObject($element, $persist = true)
 {
     // ** Assert that the $element is an instance of PHP's SimpleXMLElement...
     if (!$element instanceof \SimpleXMLElement) {
         throw new \InvalidArgumentException('Read object expects a valid <object> XML element. Given: ' . gettype($element));
     }
     $metadata = ObjectMetadataParser::parseMetadata($element);
     // ** Get the object's ID, and check the cache to see if it is in there...
     $name = $metadata->getName();
     if ($this->has($name)) {
         return $this->get($name);
     }
     // ** Is this an object reference? If so, we need to resolve the reference...
     $ref = $metadata->getRef();
     if (!empty($ref)) {
         return $this->getReference($ref);
     }
     // ** Create a new object with the metadata...
     $object = new Object($metadata);
     // ** If the object has a parent specified, inherit the properties and values from the parent...
     if ($object->hasParent()) {
         $parent = $this->getReference($object->getParentRef());
         $this->getLog()->debug('The object: ' . $object . ' has a parent object specified. Inheriting properties from parent: ' . $parent);
         $object->inherit($parent);
     }
     // ** Parse all of the properties defined in the XML and set them on the object...
     $properties = $this->parseProperties($element);
     if ($properties !== null) {
         foreach ($properties as $property) {
             $object->addProperty($property);
             $object->set($property);
         }
     }
     // ** If the object has a name, cache it for future reference...
     if (!empty($name)) {
         $this->cache($name, $object);
     }
     // ** If the object is persistable, and it doesn't already have an object ID, queue it for persistence...
     if ($object->isPersistable() && $persist === true) {
         $id = $object->getId();
         if (empty($id)) {
             $this->queue($object);
         }
     }
     return $object;
 }
    public function testParse()
    {
        $xml = <<<EOT
<object name="myobj" class="My\\Class\\Object" transient="true">
\t<property name="greeting" value="hello" />
\t<property name="subject" value="world" />
</object>
EOT;
        $parser = new ObjectMetadataParser();
        $element = new XmlElement($xml);
        $metadata = $parser->parse($element);
        $this->assertEquals('My\\Class\\Object', $metadata->getClassName());
        $this->assertEquals('myobj', $metadata->getName());
        $this->assertEquals(null, $metadata->getParentRef());
        $this->assertEquals(null, $metadata->getRef());
        $this->assertEquals(false, $metadata->isAbstract());
        $this->assertEquals(true, $metadata->isTransient());
    }
 /**
  *
  */
 public static function parseMetadata($xml)
 {
     $parser = new ObjectMetadataParser();
     return $parser->parse($xml);
 }