/**
* Creates a new entity manager instance based on the passed configuration.
*
* @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance to create the entity manager for
* @param \AppserverIo\Appserver\Core\Api\Node\PersistenceUnitNodeInterface $persistenceUnitNode The datasource configuration
*
* @return object The entity manager instance
*/
public static function factory(ApplicationInterface $application, PersistenceUnitNodeInterface $persistenceUnitNode)
{
// register additional annotation libraries
foreach ($persistenceUnitNode->getAnnotationRegistries() as $annotationRegistry) {
// register the annotations specified by the annotation registery
$annotationRegistryType = $annotationRegistry->getType();
$registry = new $annotationRegistryType();
$registry->register($annotationRegistry);
}
// query whether or not an initialize EM configuration is available
if ($application->hasAttribute($persistenceUnitNode->getName()) === false) {
// globally ignore configured annotations to ignore
foreach ($persistenceUnitNode->getIgnoredAnnotations() as $ignoredAnnotation) {
AnnotationReader::addGlobalIgnoredName($ignoredAnnotation->getNodeValue()->__toString());
}
// load the metadata configuration
$metadataConfiguration = $persistenceUnitNode->getMetadataConfiguration();
// prepare the setup properties
$absolutePaths = $metadataConfiguration->getDirectoriesAsArray();
$proxyDir = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_PROXY_DIR);
$proxyNamespace = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_PROXY_NAMESPACE);
$autoGenerateProxyClasses = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_AUTO_GENERATE_PROXY_CLASSES);
$useSimpleAnnotationReader = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_USE_SIMPLE_ANNOTATION_READER);
// load the metadata driver factory class name
$metadataDriverFactory = $metadataConfiguration->getFactory();
// initialize the params to be passed to the factory
$metadataDriverParams = array(DriverKeys::USE_SIMPLE_ANNOTATION_READER => $useSimpleAnnotationReader);
// create the database configuration and initialize the entity manager
/** @var \Doctrine\DBAL\Configuration $configuration */
$configuration = new Configuration();
$configuration->setMetadataDriverImpl($metadataDriverFactory::get($configuration, $absolutePaths, $metadataDriverParams));
// initialize the metadata cache configuration
$metadataCacheConfiguration = $persistenceUnitNode->getMetadataCacheConfiguration();
$configuration->setMetadataCacheImpl(EntityManagerFactory::getCacheImpl($persistenceUnitNode, $metadataCacheConfiguration));
// initialize the query cache configuration
$queryCacheConfiguration = $persistenceUnitNode->getQueryCacheConfiguration();
$configuration->setQueryCacheImpl(EntityManagerFactory::getCacheImpl($persistenceUnitNode, $queryCacheConfiguration));
// initialize the result cache configuration
$resultCacheConfiguration = $persistenceUnitNode->getResultCacheConfiguration();
$configuration->setResultCacheImpl(EntityManagerFactory::getCacheImpl($persistenceUnitNode, $resultCacheConfiguration));
// proxy configuration
$configuration->setProxyDir($proxyDir = $proxyDir ?: sys_get_temp_dir());
$configuration->setProxyNamespace($proxyNamespace = $proxyNamespace ?: 'Doctrine\\Proxy');
$configuration->setAutoGenerateProxyClasses($autoGenerateProxyClasses = $autoGenerateProxyClasses ?: true);
// load the datasource node
$datasourceNode = null;
foreach ($application->getInitialContext()->getSystemConfiguration()->getDatasources() as $datasourceNode) {
if ($datasourceNode->getName() === $persistenceUnitNode->getDatasource()->getName()) {
break;
}
}
// throw a exception if the configured datasource is NOT available
if ($datasourceNode == null) {
throw new \Exception(sprintf('Can\'t find a datasource node for persistence unit %s', $persistenceUnitNode->getName()));
}
// load the database node
$databaseNode = $datasourceNode->getDatabase();
// throw an exception if the configured database is NOT available
if ($databaseNode == null) {
throw new \Exception(sprintf('Can\'t find database node for persistence unit %s', $persistenceUnitNode->getName()));
}
// load the driver node
$driverNode = $databaseNode->getDriver();
// throw an exception if the configured driver is NOT available
if ($driverNode == null) {
throw new \Exception(sprintf('Can\'t find driver node for persistence unit %s', $persistenceUnitNode->getName()));
}
// load the connection parameters
$connectionParameters = ConnectionUtil::get($application)->fromDatabaseNode($databaseNode);
// append the initialized EM configuration to the application
$application->setAttribute($persistenceUnitNode->getName(), array($connectionParameters, $configuration));
}
// load the initialized EM configuration from the application
list($connectionParameters, $configuration) = $application->getAttribute($persistenceUnitNode->getName());
// initialize and return a entity manager decorator instance
return new DoctrineEntityManagerDecorator(EntityManager::create($connectionParameters, $configuration));
}