Skip to content
This repository has been archived by the owner on Jan 1, 2020. It is now read-only.

Commit

Permalink
Merge pull request #71 from jonathonwalz/add-chainmapper
Browse files Browse the repository at this point in the history
Add chain mapper implementation
  • Loading branch information
flack committed Feb 11, 2015
2 parents 3e8859d + 88fe97e commit 263f642
Show file tree
Hide file tree
Showing 13 changed files with 333 additions and 28 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Changelog
=========

1.1
-----
* Added ChainRdfMapper and ChainedRdfMapperInterface to allow using more than one mapper in parallel.
* BC break: If you implemented your own mapper, note that RdfMapperInterface::objectToName was added

1.0
-----

* **2014-01-13**: Moved workflows from Manager to RestService. If you used
the Manager before, please update your code to use the RestService.
Before:
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "0.9-dev"
"dev-master": "1.1-dev"
}
}
}
34 changes: 30 additions & 4 deletions src/Midgard/CreatePHP/Mapper/AbstractRdfMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,28 @@ public function prepareObject(TypeInterface $type, $parent = null)
if ($parent !== null) {
throw new \Exception('Parent is not null, please extend this method to configure the parent');
}
list($prefix, $shortname) = explode(':', $type->getRdfType());
$ns = $type->getVocabularies();
$ns = $ns[$prefix];
$name = $ns.$shortname;
$name = $this->getTypeMapKey($type);
if (isset($this->typeMap[$name])) {
$class = $this->typeMap[$name];
return new $class;
}
throw new \Exception('No information on ' . $name);
}

/**
* Get's the possible key used in the typemap for the type
*
* @param TypeInterface $type
* @return string
*/
protected function getTypeMapKey(TypeInterface $type)
{
list($prefix, $shortname) = explode(':', $type->getRdfType());
$ns = $type->getVocabularies();
$ns = $ns[$prefix];
return $ns.$shortname;
}

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -149,12 +160,27 @@ protected function getField($object, RdfElementDefinitionInterface $child)
*
* @param string $className
* @return string exactly the same as $className
* @deprecated Deprecated in 1.1 use objectToName instead.
*/
public function canonicalName($className)
{
return $className;
}

/**
* {@inheritDoc}
*
* The default implementation uses get_class on objects
*/
public function objectToName($object)
{
if (! is_object($object)) {
throw new \RuntimeException("$object is not an object");
}

return $this->canonicalName(get_class($object));
}

/**
* This sort method is used for sorting elements in the given array according the reference array
* which contains some of the array keys of the first array.
Expand Down
44 changes: 42 additions & 2 deletions src/Midgard/CreatePHP/Mapper/BaseDoctrineRdfMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\Common\Persistence\Mapping\MappingException;
use Doctrine\Common\Util\ClassUtils;
use Midgard\CreatePHP\RdfChainableMapperInterface;
use Midgard\CreatePHP\Entity\EntityInterface;
use Midgard\CreatePHP\Entity\PropertyInterface;
use Midgard\CreatePHP\Type\TypeInterface;

/**
* Base mapper for doctrine, removing the proxy class names in canonicalClassName
Expand All @@ -20,7 +24,7 @@
*
* @package Midgard.CreatePHP
*/
abstract class BaseDoctrineRdfMapper extends AbstractRdfMapper
abstract class BaseDoctrineRdfMapper extends AbstractRdfMapper implements RdfChainableMapperInterface
{
/** @var ObjectManager */
protected $om;
Expand Down Expand Up @@ -68,6 +72,16 @@ public function canonicalName($className)
return $className;
}

/**
* {@inheritDoc}
*
* use getRealClass if className names a doctrine proxy class.
*/
public function objectToName($object)
{
return $this->canonicalName(ClassUtils::getClass($object));
}

/**
* {@inheritDoc}
*/
Expand All @@ -94,4 +108,30 @@ public function setPropertyValue($object, PropertyInterface $property, $value)

return parent::setPropertyValue($object, $property, $value);
}
}

/**
* {@inheritDoc}
*/
public function supports($object)
{
return $this->om->contains($object);
}

/**
* {@inheritDoc}
*/
public function supportsCreate(TypeInterface $type)
{
$name = $this->getTypeMapKey($type);
if (isset($this->typeMap[$name])) {
try {
$metadata = $this->om->getClassMetadata($this->typeMap[$name]);

return is_object($metadata);
} catch (MappingException $e) {
}
}

return false;
}
}
177 changes: 177 additions & 0 deletions src/Midgard/CreatePHP/Mapper/ChainRdfMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
<?php

namespace Midgard\CreatePHP\Mapper;

use Midgard\CreatePHP\RdfChainableMapperInterface;
use Midgard\CreatePHP\RdfMapperInterface;
use Midgard\CreatePHP\Entity\PropertyInterface;
use Midgard\CreatePHP\Entity\CollectionInterface;
use Midgard\CreatePHP\Type\TypeInterface;
use Midgard\CreatePHP\Entity\EntityInterface;
use RuntimeException;

/**
* Looks at all registered mappers to find one that can handle objects.
*
* @package Midgard.CreatePHP
*/
class ChainRdfMapper implements RdfMapperInterface
{
/**
* All the registered mappers
*
* @var RdfMapperInterface[]
*/
private $mappers = array();

/**
* Mappers index by the spl_object_hash of objects created by CreatePHP
*
* @var RdfMapperInterface[]
*/
private $createdObjects = array();

/**
* Register a mapper with a key. The key will be prefixed to all subjects.
*
* @param RdfChainableMapperInterface $mapper
* @param string $mapperKey
*/
public function registerMapper(RdfChainableMapperInterface $mapper, $mapperKey)
{
$this->mappers[$mapperKey] = $mapper;
}

/**
* Get the mapper than can handle object.
*
* @param mixed $object
* @return RdfChainableMapperInterface
* @throws RuntimeException when no mapper can handle the object
*/
protected function getMapperForObject($object)
{
foreach ($this->mappers as $mapper) {
if ($mapper->supports($object)) {
return $mapper;
}
}

$hash = spl_object_hash($object);
if (isset($this->createdObjects[$hash])) {
return $this->createdObjects[$hash];
}

throw new RuntimeException("No mapper can create a subject for object.");
}
/**
* {@inheritdoc}
*/
public function setPropertyValue($object, PropertyInterface $property, $value)
{
return $this->getMapperForObject($object)->setPropertyValue($object, $property, $value);
}

/**
* {@inheritdoc}
*/
public function getPropertyValue($object, PropertyInterface $property)
{
return $this->getMapperForObject($object)->getPropertyValue($object, $property);
}

/**
* {@inheritdoc}
*/
public function isEditable($object)
{
return $this->getMapperForObject($object)->isEditable($object);
}

/**
* {@inheritdoc}
*/
public function getChildren($object, CollectionInterface $collection)
{
return $this->getMapperForObject($object)->getChildren($object, $collection);
}

/**
* {@inheritdoc}
*/
public function canonicalName($className)
{
return $className;
}

/**
* {@inheritdoc}
*/
public function objectToName($object)
{
return $this->getMapperForObject($object)->objectToName($object);
}

/**
* {@inheritdoc}
*/
public function prepareObject(TypeInterface $controller, $parent = null)
{
foreach ($this->mappers as $mapper) {
if ($mapper->supportsCreate($controller)) {
$object = $mapper->prepareObject($controller, $parent);
$this->createdObjects[spl_object_hash($object)] = $mapper;

return $object;
}
}

throw new RuntimeException(sprintf('None of the registered mappers can create an object of type %s', $controller->getRdfType()));
}

/**
* {@inheritdoc}
*/
public function store(EntityInterface $entity)
{
return $this->getMapperForObject($entity->getObject())->store($entity);
}

/**
* {@inheritdoc}
*/
public function getBySubject($subject)
{
list($mapperKey, $mapperSubject) = explode('|', $subject, 2);

if (!isset($this->mappers[$mapperKey])) {
throw new RuntimeException("Invalid subject: $subject");
}

$object = $this->mappers[$mapperKey]->getBySubject($mapperSubject);

return $object;
}

/**
* {@inheritdoc}
*/
public function createSubject($object)
{
foreach ($this->mappers as $mapperKey => $mapper) {
if ($mapper->supports($object)) {
return $mapperKey.'|'.$mapper->createSubject($object);
}
}

throw new RuntimeException(sprintf('None of the registered mappers can create the subject for object of class %s', get_class($object)));
}

/**
* {@inheritdoc}
*/
public function orderChildren(EntityInterface $entity, CollectionInterface $node, $expectedOrder)
{
return $this->getMapperForObject($entity->getObject())->orderChildren($entity, $node, $expectedOrder);
}
}
2 changes: 1 addition & 1 deletion src/Midgard/CreatePHP/Mapper/DoctrineOrmMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function createSubject($object)

$idstring = implode('|', $key);

return str_replace('\\', '-', $this->canonicalName(get_class($object))) . "|$idstring";
return str_replace('\\', '-', $this->objectToName($object))."|$idstring";
}

/**
Expand Down
7 changes: 2 additions & 5 deletions src/Midgard/CreatePHP/Metadata/AbstractRdfDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,11 @@ protected abstract function getAttributes($element);
/**
* {@inheritDoc}
*
* The default implementation uses get_class on objects
* @deprecated Deprecated in 1.1 call on the mapper object instead.
*/
public function objectToName($object, RdfMapperInterface $mapper)
{
if (! is_object($object)) {
throw new \RuntimeException("$object is not an object");
}
return $mapper->canonicalName(get_class($object));
return $mapper->objectToName($object);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Midgard/CreatePHP/Metadata/RdfDriverInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public function loadType($name, RdfMapperInterface $mapper, RdfTypeFactory $type
* @param object $object
*
* @return string the canonical name of this object
*
* @deprecated Deprecated in 1.1 call on the mapper object instead.
*/
public function objectToName($object, RdfMapperInterface $mapper);

Expand Down
2 changes: 1 addition & 1 deletion src/Midgard/CreatePHP/Metadata/RdfTypeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function __construct(RdfMapperInterface $mapper, RdfDriverInterface $driv
public function getTypeByObject($object)
{
return $this->getTypeByName(
$this->driver->objectToName($object, $this->mapper)
$this->mapper->objectToName($object)
);
}

Expand Down
Loading

0 comments on commit 263f642

Please sign in to comment.