/** * Provisions all web applications. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * * @return void */ public function provision(ApplicationInterface $application) { // check if the webapps directory exists if (is_dir($webappPath = $application->getWebappPath())) { // prepare the glob expression with the application's directories to parse $applicationDirectories = AppEnvironmentHelper::getEnvironmentAwareGlobPattern($webappPath, '{WEB-INF,META-INF}/provision', GLOB_BRACE); // load the service instance /** @var \AppserverIo\Appserver\Core\Api\ProvisioningService $service */ $service = $this->getService(); // load the configuration service instance /** @var \AppserverIo\Appserver\Core\Api\ConfigurationService $configurationService */ $configurationService = $this->getInitialContext()->newService('AppserverIo\\Appserver\\Core\\Api\\ConfigurationService'); // load the container node to initialize the system properties /** @var \AppserverIo\Appserver\Core\Api\Node\ContainerNodeInterface $containerNode */ $containerNode = $application->getContainer()->getContainerNode(); // iterate through all provisioning files (provision.xml), validate them and attach them to the configuration foreach ($service->globDir($applicationDirectories, GLOB_BRACE) as $provisionFile) { try { // validate the file, but skip it if the validation fails $configurationService->validateFile($provisionFile, null); // load the system properties $properties = $service->getSystemProperties($containerNode); // append the application specific properties $properties->add(SystemPropertyKeys::WEBAPP, $webappPath); $properties->add(SystemPropertyKeys::WEBAPP_NAME, basename($webappPath)); $properties->add(SystemPropertyKeys::WEBAPP_CACHE, $application->getCacheDir()); $properties->add(SystemPropertyKeys::WEBAPP_SESSION, $application->getSessionDir()); // create a new provision node instance and replace the properties $provisionNode = new ProvisionNode(); $provisionNode->initFromFile($provisionFile); $provisionNode->replaceProperties($properties); // query whether we've a datasource configured or not if ($datasource = $provisionNode->getDatasource()) { // try to load the datasource from the system configuration $datasourceNode = $service->findByName($datasource->getName()); // try to inject the datasource node if available if ($datasourceNode != null) { $provisionNode->injectDatasource($datasourceNode); } } /* Re-provision the provision.xml (reinitialize). * * ATTENTION: The re-provisioning is extremely important, because * this allows dynamic replacement of placeholders by using the * XML file as a template that will reinterpreted with the PHP * interpreter! */ $provisionNode->reprovision($provisionFile); // execute the provisioning workflow $this->executeProvision($application, $provisionNode, new \SplFileInfo($webappPath)); } catch (ConfigurationException $ce) { // load the logger and log the XML validation errors $systemLogger = $this->getInitialContext()->getSystemLogger(); $systemLogger->error($ce->__toString()); // additionally log a message that DS will be missing $systemLogger->critical(sprintf('Will skip reading provisioning steps in %s, provisioning might not have been done.', $provisionFile)); } } } }
/** * The main method that creates new instances in a separate context. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance to register the class loader with * @param \AppserverIo\Appserver\Core\Api\Node\ManagerNodeInterface $managerConfiguration The manager configuration * * @return void */ public static function visit(ApplicationInterface $application, ManagerNodeInterface $managerConfiguration) { // initialize the authentication manager $authenticationManager = new StandardAuthenticationManager(); // attach the instance $application->addManager($authenticationManager, $managerConfiguration); }
/** * The main method that creates a new provisioner instance. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance to register the provisioner with * @param \AppserverIo\Appserver\Core\Api\Node\ProvisionerNodeInterface $provisionerConfiguration The provisioner configuration * * @return void */ public static function visit(ApplicationInterface $application, ProvisionerNodeInterface $provisionerConfiguration) { // load the initial context $initialContext = $application->getInitialContext(); // initialize the bean manager $provisioner = new StandardProvisioner($initialContext, $provisionerConfiguration); // attach the instance $application->addProvisioner($provisioner, $provisionerConfiguration); }
/** * Visitor method that registers the class loaders in the application. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance to register the class loader with * @param \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNodeInterface $configuration The class loader configuration * * @return void */ public static function visit(ApplicationInterface $application, ClassLoaderNodeInterface $configuration) { // load the web application path we want to register the class loader for $webappPath = $application->getWebappPath(); // initialize the class path and the enforcement directories $classPath = array(); $enforcementDirs = array(); // add the possible class path if folder is available foreach ($configuration->getDirectories() as $directory) { if (is_dir($webappPath . $directory->getNodeValue())) { array_push($classPath, $webappPath . $directory->getNodeValue()); if ($directory->isEnforced()) { array_push($enforcementDirs, $webappPath . $directory->getNodeValue()); } } } // initialize the arrays of different omit possibilities $omittedEnforcement = array(); $omittedAutoLoading = array(); // iterate over all namespaces and check if they are omitted in one or the other way foreach ($configuration->getNamespaces() as $namespace) { // is the enforcement omitted for this namespace? if ($namespace->omitEnforcement()) { $omittedEnforcement[] = $namespace->getNodeValue()->__toString(); } // is the autoloading omitted for this namespace? if ($namespace->omitAutoLoading()) { $omittedAutoLoading[] = $namespace->getNodeValue()->__toString(); } } // initialize the class loader configuration $config = new Config(); // set the environment mode we want to use $config->setValue('environment', $configuration->getEnvironment()); // set the cache directory $config->setValue('cache/dir', $application->getCacheDir()); // set the default autoloader values $config->setValue('autoloader/dirs', $classPath); // collect the omitted namespaces (if any) $config->setValue('autoloader/omit', $omittedAutoLoading); $config->setValue('enforcement/omit', $omittedEnforcement); // set the default enforcement configuration values $config->setValue('enforcement/dirs', $enforcementDirs); $config->setValue('enforcement/enforce-default-type-safety', $configuration->getTypeSafety()); $config->setValue('enforcement/processing', $configuration->getProcessing()); $config->setValue('enforcement/level', $configuration->getEnforcementLevel()); $config->setValue('enforcement/logger', $application->getInitialContext()->getSystemLogger()); // create a autoloader instance and initialize it $classLoader = new DgClassLoader($config); $classLoader->init(new StackableStructureMap($config->getValue('autoloader/dirs'), $config->getValue('enforcement/dirs'), $config), new AspectRegister()); // add the autoloader to the manager $application->addClassLoader($classLoader, $configuration); }
/** * The main method that creates new instances in a separate context. * * @param \AppserverIo\Psr\Application\ApplicationInterface|\AppserverIo\Psr\Naming\NamingDirectoryInterface $application The application instance to register the class loader with * @param \AppserverIo\Appserver\Core\Api\Node\ManagerNodeInterface $managerConfiguration The manager configuration * * @return void */ public static function visit(ApplicationInterface $application, ManagerNodeInterface $managerConfiguration) { // check if the correct autoloader has been registered, if so we have to get its aspect register. // if not we have to fail here $classLoader = $application->search('DgClassLoader'); $aspectRegister = $classLoader->getAspectRegister(); // initialize the aspect manager $aspectManager = new AspectManager(); $aspectManager->injectApplication($application); $aspectManager->injectAspectRegister($aspectRegister); // attach the instance $application->addManager($aspectManager, $managerConfiguration); }
/** * Visitor method that registers the class loaders in the application. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance to register the class loader with * @param \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNodeInterface $configuration The class loader configuration * * @return void */ public static function visit(ApplicationInterface $application, ClassLoaderNodeInterface $configuration) { // initialize the storage for the class map and the include path $classMap = new GenericStackable(); $includePath = array(); // load the application directory $webappPath = $application->getWebappPath(); // load the composer class loader for the configured directories foreach ($configuration->getDirectories() as $directory) { // we prepare the directories to include scripts AFTER registering (in application context) $includePath[] = $webappPath . $directory->getNodeValue(); } // initialize and return the SPL class loader instance $application->addClassLoader(new SplClassLoader($classMap, $includePath), $configuration); }
/** * 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) { AnnotationRegistry::registerAutoloadNamespace($annotationRegistry->getNamespace(), $annotationRegistry->getDirectoriesAsArray($application->getWebappPath())); } // 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($application->getWebappPath()); $proxyDir = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_PROXY_DIR); $isDevMode = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_IS_DEV_MODE); $useSimpleAnnotationReader = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_USE_SIMPLE_ANNOTATION_READER); // load the factory method from the available mappings $factoryMethod = EntityManagerFactory::$metadataMapping[$metadataConfiguration->getType()]; // create the database configuration and initialize the entity manager $configuration = Setup::$factoryMethod($absolutePaths, $isDevMode, $proxyDir, null, $useSimpleAnnotationReader); // 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())); } // initialize and return a entity manager decorator instance return new DoctrineEntityManagerDecorator(EntityManager::create(ConnectionUtil::get($application)->fromDatabaseNode($databaseNode), $configuration)); }
/** * Visitor method that registers the class loaders in the application. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance to register the class loader with * @param \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNodeInterface $configuration The class loader configuration * * @return void */ public static function visit(ApplicationInterface $application, ClassLoaderNodeInterface $configuration) { // load the application directory $webappPath = $application->getWebappPath(); // initialize the array with the configured directories $directories = array(); // load the composer class loader for the configured directories /** @var \AppserverIo\Appserver\Core\Api\Node\DirectoryNode $directory */ foreach ($configuration->getDirectories() as $directory) { // we prepare the directories to include scripts AFTER registering (in application context) $directories[] = $webappPath . $directory->getNodeValue(); // check if an autoload.php is available if (file_exists($webappPath . $directory->getNodeValue() . DIRECTORY_SEPARATOR . 'autoload.php')) { // if yes, we try to instanciate a new class loader instance $classLoader = new ComposerClassLoader($directories); // set the composer include paths if (file_exists($webappPath . $directory->getNodeValue() . '/composer/include_paths.php')) { $includePaths = (require $webappPath . $directory->getNodeValue() . '/composer/include_paths.php'); array_push($includePaths, get_include_path()); set_include_path(join(PATH_SEPARATOR, $includePaths)); } // add the composer namespace declarations if (file_exists($webappPath . $directory->getNodeValue() . '/composer/autoload_namespaces.php')) { $map = (require $webappPath . $directory->getNodeValue() . '/composer/autoload_namespaces.php'); foreach ($map as $namespace => $path) { $classLoader->set($namespace, $path); } } // add the composer PSR-4 compatible namespace declarations if (file_exists($webappPath . $directory->getNodeValue() . '/composer/autoload_psr4.php')) { $map = (require $webappPath . $directory->getNodeValue() . '/composer/autoload_psr4.php'); foreach ($map as $namespace => $path) { $classLoader->setPsr4($namespace, $path); } } // add the composer class map if (file_exists($webappPath . $directory->getNodeValue() . '/composer/autoload_classmap.php')) { $classMap = (require $webappPath . $directory->getNodeValue() . '/composer/autoload_classmap.php'); if ($classMap) { $classLoader->addClassMap($classMap); } } // attach the class loader instance $application->addClassLoader($classLoader, $configuration); } } }
/** * The main method that creates new instances in a separate context. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance to register the class loader with * @param \AppserverIo\Appserver\Core\Api\Node\ManagerNodeInterface $managerConfiguration The manager configuration * * @return void */ public static function visit(ApplicationInterface $application, ManagerNodeInterface $managerConfiguration) { // load the registered loggers $loggers = $application->getInitialContext()->getLoggers(); // initialize the bean locator $beanLocator = new BeanLocator(); // create the initial context instance $initialContext = new NamingContext(); $initialContext->injectApplication($application); // initialize the stackable for the data, the stateful + singleton session beans and the naming directory $data = new StackableStorage(); $instances = new GenericStackable(); $statefulSessionBeans = new StackableStorage(); $singletonSessionBeans = new StackableStorage(); // initialize the default settings for the stateful session beans $statefulSessionBeanSettings = new DefaultStatefulSessionBeanSettings(); $statefulSessionBeanSettings->mergeWithParams($managerConfiguration->getParamsAsArray()); // we need a factory instance for the stateful session bean instances $statefulSessionBeanMapFactory = new StatefulSessionBeanMapFactory($statefulSessionBeans); $statefulSessionBeanMapFactory->injectLoggers($loggers); $statefulSessionBeanMapFactory->start(); // create an instance of the object factory $objectFactory = new GenericObjectFactory(); $objectFactory->injectInstances($instances); $objectFactory->injectApplication($application); $objectFactory->start(); // add a garbage collector and timer service workers for each application $garbageCollector = new StandardGarbageCollector(); $garbageCollector->injectApplication($application); $garbageCollector->start(); // initialize the bean manager $beanManager = new BeanManager(); $beanManager->injectData($data); $beanManager->injectApplication($application); $beanManager->injectResourceLocator($beanLocator); $beanManager->injectObjectFactory($objectFactory); $beanManager->injectInitialContext($initialContext); $beanManager->injectGarbageCollector($garbageCollector); $beanManager->injectStatefulSessionBeans($statefulSessionBeans); $beanManager->injectSingletonSessionBeans($singletonSessionBeans); $beanManager->injectDirectories($managerConfiguration->getDirectories()); $beanManager->injectStatefulSessionBeanSettings($statefulSessionBeanSettings); $beanManager->injectStatefulSessionBeanMapFactory($statefulSessionBeanMapFactory); // attach the instance $application->addManager($beanManager, $managerConfiguration); }
/** * The main method that creates new instances in a separate context. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance to register the class loader with * @param \AppserverIo\Appserver\Core\Api\Node\ManagerNodeInterface $managerConfiguration The manager configuration * * @return void */ public static function visit(ApplicationInterface $application, ManagerNodeInterface $managerConfiguration) { // load the registered loggers $loggers = $application->getInitialContext()->getLoggers(); // initialize the session pool $sessions = new StackableStorage(); $checksums = new StackableStorage(); $sessionPool = new StackableStorage(); $sessionSettings = new DefaultSessionSettings(); $sessionMarshaller = new StandardSessionMarshaller(); // we need a session factory instance $sessionFactory = new SessionFactory($sessionPool); $sessionFactory->injectLoggers($loggers); $sessionFactory->start(); // we need a persistence manager and garbage collector $persistenceManager = new FilesystemPersistenceManager(); $persistenceManager->injectLoggers($loggers); $persistenceManager->injectSessions($sessions); $persistenceManager->injectChecksums($checksums); $persistenceManager->injectSessionSettings($sessionSettings); $persistenceManager->injectSessionMarshaller($sessionMarshaller); $persistenceManager->injectSessionFactory($sessionFactory); $persistenceManager->injectUser($application->getUser()); $persistenceManager->injectGroup($application->getGroup()); $persistenceManager->injectUmask($application->getUmask()); $persistenceManager->start(); // we need a garbage collector $garbageCollector = new StandardGarbageCollector(); $garbageCollector->injectLoggers($loggers); $garbageCollector->injectSessions($sessions); $garbageCollector->injectSessionFactory($sessionFactory); $garbageCollector->injectSessionSettings($sessionSettings); $garbageCollector->start(); // and finally we need the session manager instance $sessionManager = new StandardSessionManager(); $sessionManager->injectSessions($sessions); $sessionManager->injectSessionFactory($sessionFactory); $sessionManager->injectSessionSettings($sessionSettings); $sessionManager->injectGarbageCollector($garbageCollector); $sessionManager->injectPersistenceManager($persistenceManager); // attach the instance $application->addManager($sessionManager, $managerConfiguration); }
/** * Initializes the manager instance. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * * @return void * @see \AppserverIo\Psr\Application\ManagerInterface::initialize() * * @throws \Exception */ public function initialize(ApplicationInterface $application) { // iterate over all servlets and return the matching one $authenticationAdapters = array(); foreach ($application->search('ServletContextInterface')->getSecuredUrlConfigs() as $securedUrlConfig) { // continue if the can't find a config if ($securedUrlConfig == null) { continue; } // extract URL pattern and authentication configuration list($urlPattern, $auth) = array_values($securedUrlConfig); // load security configuration $configuredAuthType = $securedUrlConfig['auth']['auth-type']; // check the authentication type switch ($configuredAuthType) { case "Basic": $authImplementation = '\\AppserverIo\\Http\\Authentication\\BasicAuthentication'; break; case "Digest": $authImplementation = '\\AppserverIo\\Http\\Authentication\\DigestAuthentication'; break; default: throw new \Exception(sprintf('Unknown authentication type %s', $configuredAuthType)); } // in preparation we have to flatten the configuration structure $config = $securedUrlConfig['auth']; array_shift($config); $options = $config['options']; unset($config['options']); // we do need to make some alterations if (isset($options['file'])) { $options['file'] = $application->getWebappPath() . DIRECTORY_SEPARATOR . $options['file']; } // initialize the authentication manager /** @var \AppserverIo\Http\Authentication\AuthenticationInterface $auth */ $auth = new $authImplementation(array_merge(array('type' => $authImplementation), $config, $options)); $authenticationAdapters[$urlPattern] = $auth; } $this->authenticationAdapters = $authenticationAdapters; }
/** * 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) { AnnotationRegistry::registerAutoloadNamespace($annotationRegistry->getNamespace(), $annotationRegistry->getDirectoriesAsArray($application->getWebappPath())); } // load the metadata configuration $metadataConfiguration = $persistenceUnitNode->getMetadataConfiguration(); // prepare the setup properties $absolutePaths = $metadataConfiguration->getDirectoriesAsArray($application->getWebappPath()); $proxyDir = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_PROXY_DIR); $isDevMode = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_IS_DEV_MODE); $useSimpleAnnotationReader = $metadataConfiguration->getParam(MetadataConfigurationNode::PARAM_USE_SIMPLE_ANNOTATION_READER); // load the factory method from the available mappings $factoryMethod = EntityManagerFactory::$metadataMapping[$metadataConfiguration->getType()]; // create the database configuration and initialize the entity manager $configuration = Setup::$factoryMethod($absolutePaths, $isDevMode, $proxyDir, null, $useSimpleAnnotationReader); // 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())); } // initialize the connection parameters with the mandatory driver $connectionParameters = array('driver' => $databaseNode->getDriver()->getNodeValue()->__toString()); // initialize the path/memory to the database when we use sqlite for example if ($pathNode = $databaseNode->getPath()) { $connectionParameters['path'] = $application->getWebappPath() . DIRECTORY_SEPARATOR . $pathNode->getNodeValue()->__toString(); } elseif ($memoryNode = $databaseNode->getMemory()) { $connectionParameters['memory'] = Boolean::valueOf(new String($memoryNode->getNodeValue()->__toString()))->booleanValue(); } else { // do nothing here, because there is NO option } // add username, if specified if ($userNode = $databaseNode->getUser()) { $connectionParameters['user'] = $userNode->getNodeValue()->__toString(); } // add password, if specified if ($passwordNode = $databaseNode->getPassword()) { $connectionParameters['password'] = $passwordNode->getNodeValue()->__toString(); } // add database name if using another PDO driver than sqlite if ($databaseNameNode = $databaseNode->getDatabaseName()) { $connectionParameters['dbname'] = $databaseNameNode->getNodeValue()->__toString(); } // add database host if using another PDO driver than sqlite if ($databaseHostNode = $databaseNode->getDatabaseHost()) { $connectionParameters['host'] = $databaseHostNode->getNodeValue()->__toString(); } // add charset, if specified if ($charsetNode = $databaseNode->getCharset()) { $connectionParameters['charset'] = $charsetNode->getNodeValue()->__toString(); } // add driver options, if specified if ($driverOptionsNode = $databaseNode->getDriverOptions()) { // explode the raw options separated with a semicolon $rawOptions = explode(';', $driverOptionsNode->getNodeValue()->__toString()); // prepare the array with the driver options key/value pair (separated with a =) $options = array(); foreach ($rawOptions as $rawOption) { list($key, $value) = explode('=', $rawOption); $options[$key] = $value; } // set the driver options $connectionParameters['driverOptions'] = $options; } // add driver options, if specified if ($unixSocketNode = $databaseNode->getUnixSocket()) { $connectionParameters['unix_socket'] = $unixSocketNode->getNodeValue()->__toString(); } // initialize and return a entity manager decorator instance return new DoctrineEntityManagerDecorator(EntityManager::create($connectionParameters, $configuration)); }
/** * Deploys the entity manager described by the passed XML node. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * @param \AppserverIo\Appserver\Core\Api\PersistenceUnitNodeInterface $persistenceUnitNode The XML node that describes the entity manager * * @return void */ public function registerEntityManager(ApplicationInterface $application, PersistenceUnitNodeInterface $persistenceUnitNode) { // initialize the the entity manager instance $this->entityManagers[$lookupName = $persistenceUnitNode->getName()] = $persistenceUnitNode; // bind the callback for the entity manager instance to the // naming directory => necessary for DI provider $application->getNamingDirectory()->bind(sprintf('php:global/%s/%s', $application->getUniqueName(), $lookupName), array(&$this, 'lookup'), array($lookupName)); }
/** * Clean up the the directories for the webapp, e. g. to delete cached stuff * that has to be recreated after a restart. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application to clean up the directories for * * @return void */ public function cleanUpFolders(ApplicationInterface $application) { // create the directory we want to store the sessions in $cleanUpFolders = array(new \SplFileInfo($application->getCacheDir())); // create the applications temporary directories foreach ($cleanUpFolders as $cleanUpFolder) { $this->cleanUpDir($cleanUpFolder); } }
/** * Has been automatically invoked by the container after the application * instance has been created. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * * @return void * @see \AppserverIo\Psr\Application\ManagerInterface::initialize() */ public function initialize(ApplicationInterface $application) { // build up META-INF directory var $metaInfDir = $application->getWebappPath() . DIRECTORY_SEPARATOR . 'META-INF'; // check if we've found a valid directory if (is_dir($metaInfDir) === false) { return; } // load the timer service executor and timer factories $timerFactory = $this->getTimerFactory(); $calendarTimerFactory = $this->getCalendarTimerFactory(); $timerServiceExecutor = $this->getTimerServiceExecutor(); // load the service to iterate over application folders /** @var \AppserverIo\Appserver\Core\Api\DeploymentService $service */ $service = $application->newService('AppserverIo\\Appserver\\Core\\Api\\DeploymentService'); $phpFiles = $service->globDir($metaInfDir . DIRECTORY_SEPARATOR . '*.php'); // iterate all php files foreach ($phpFiles as $phpFile) { try { // cut off the META-INF directory and replace OS specific directory separators $relativePathToPhpFile = str_replace(DIRECTORY_SEPARATOR, '\\', str_replace($metaInfDir, '', $phpFile)); // now cut off the first directory, that will be '/classes' by default $pregResult = preg_replace('%^(\\\\*)[^\\\\]+%', '', $relativePathToPhpFile); $className = substr($pregResult, 0, -4); // create the reflection class instance $reflectionClass = new \ReflectionClass($className); // initialize the timed object instance with the data from the reflection class $timedObject = TimedObject::fromPhpReflectionClass($reflectionClass); // check if we have a bean with a @Stateless, @Singleton or @MessageDriven annotation if ($timedObject->hasAnnotation(Stateless::ANNOTATION) === false && $timedObject->hasAnnotation(Singleton::ANNOTATION) === false && $timedObject->hasAnnotation(MessageDriven::ANNOTATION) === false) { continue; // if not, we don't care here! } // initialize the stackable for the timeout methods $timeoutMethods = new StackableStorage(); // create the timed object invoker $timedObjectInvoker = new TimedObjectInvoker(); $timedObjectInvoker->injectApplication($application); $timedObjectInvoker->injectTimedObject($timedObject); $timedObjectInvoker->injectTimeoutMethods($timeoutMethods); $timedObjectInvoker->start(PTHREADS_INHERIT_NONE | PTHREADS_INHERIT_CONSTANTS); // initialize the stackable for the timers $timers = new StackableStorage(); // initialize the timer service $timerService = new TimerService(); $timerService->injectTimers($timers); $timerService->injectTimerFactory($timerFactory); $timerService->injectTimedObjectInvoker($timedObjectInvoker); $timerService->injectCalendarTimerFactory($calendarTimerFactory); $timerService->injectTimerServiceExecutor($timerServiceExecutor); $timerService->start(PTHREADS_INHERIT_NONE | PTHREADS_INHERIT_CONSTANTS); // register the initialized timer service $this->register($timerService); // log a message that the timer service has been registered $application->getInitialContext()->getSystemLogger()->info(sprintf('Successfully registered timer service for bean %s', $reflectionClass->getName())); // if class can not be reflected continue with next class } catch (\Exception $e) { // log an error message $application->getInitialContext()->getSystemLogger()->error($e->__toString()); // proceed with the next bean continue; } } }
/** * Initializes the session manager. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * * @return void * @see \AppserverIo\Psr\Application\ManagerInterface::initialize() */ public function initialize(ApplicationInterface $application) { // load the servlet manager with the session settings configured in web.xml /** @var \AppserverIo\Psr\Servlet\ServletContextInterface|\AppserverIo\Psr\Application\ManagerInterface $servletManager */ $servletManager = $application->search('ServletContextInterface'); // load the settings, set the default session save path $sessionSettings = $this->getSessionSettings(); $sessionSettings->setSessionSavePath($application->getSessionDir()); // if we've session parameters defined in our servlet context if ($servletManager->hasSessionParameters()) { // we want to merge the session settings from the servlet context $sessionSettings->mergeServletContext($servletManager); } // initialize the garbage collector and the persistence manager $this->getGarbageCollector()->initialize(); $this->getPersistenceManager()->initialize(); }
/** * Deploys the message queues. * * @param \AppserverIo\Psr\Application\ApplicationInterface|\AppserverIo\Psr\Naming\NamingDirectoryInterface $application The application instance * * @return void */ protected function registerMessageQueues(ApplicationInterface $application) { // build up META-INF directory var $metaInfDir = $this->getWebappPath() . DIRECTORY_SEPARATOR . 'META-INF'; // check if we've found a valid directory if (is_dir($metaInfDir) === false) { return; } // check META-INF + subdirectories for XML files with MQ definitions /** @var \AppserverIo\Appserver\Core\Api\DeploymentService $service */ $service = $application->newService('AppserverIo\\Appserver\\Core\\Api\\DeploymentService'); $xmlFiles = $service->globDir($metaInfDir . DIRECTORY_SEPARATOR . 'message-queues.xml'); // initialize the array for the creating the subdirectories $this->directories = new GenericStackable(); $this->directories[] = $application->getNamingDirectory(); // gather all the deployed web applications foreach ($xmlFiles as $file) { try { // try to initialize a SimpleXMLElement $sxe = new \SimpleXMLElement($file, null, true); $sxe->registerXPathNamespace('a', 'http://www.appserver.io/appserver'); // lookup the MessageQueue's defined in the passed XML node if (($nodes = $sxe->xpath('/a:message-queues/a:message-queue')) === false) { continue; } // validate the file here, if it is not valid we can skip further steps try { /** @var \AppserverIo\Appserver\Core\Api\ConfigurationService $configurationService */ $configurationService = $application->newService('AppserverIo\\Appserver\\Core\\Api\\ConfigurationService'); $configurationService->validateFile($file, null, true); } catch (InvalidConfigurationException $e) { /** @var \Psr\Log\LoggerInterface $systemLogger */ $systemLogger = $this->getApplication()->getInitialContext()->getSystemLogger(); $systemLogger->error($e->getMessage()); $systemLogger->critical(sprintf('Message queue configuration file %s is invalid, needed queues might be missing.', $file)); return; } // iterate over all found queues and initialize them foreach ($nodes as $node) { $this->registeMessageQueue($node); } // if class can not be reflected continue with next class } catch (\Exception $e) { // log an error message $application->getInitialContext()->getSystemLogger()->error($e->__toString()); // proceed with the next queue continue; } } }
/** * Visitor method that adds a initialized class loader to the passed application. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * @param \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNodeInterface $configuration The class loader configuration node * * @return void */ public static function visit(ApplicationInterface $application, ClassLoaderNodeInterface $configuration = null) { $application->addClassLoader(SplClassLoader::factory()); }
/** * Will initialize an existing app node from a given application * * @param ApplicationInterface $application The application to init from * * @return null */ public function initFromApplication(ApplicationInterface $application) { $this->setNodeName(self::NODE_NAME); $this->name = $application->getName(); $this->webappPath = $application->getWebappPath(); $this->setUuid($this->newUuid()); }
/** * Initializes the session manager. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * * @return void * @see \AppserverIo\Psr\Application\ManagerInterface::initialize() */ public function initialize(ApplicationInterface $application) { // load the servlet manager with the session settings configured in web.xml /** @var \AppserverIo\Psr\Servlet\ServletContextInterface|\AppserverIo\Psr\Application\ManagerInterface $servletManager */ $servletManager = $application->search(ServletContextInterface::IDENTIFIER); // load the settings, set the default session save path $sessionSettings = $this->getSessionSettings(); $sessionSettings->setSessionSavePath($application->getSessionDir()); // if we've session parameters defined in our servlet context if ($servletManager->hasSessionParameters()) { // we want to merge the session settings from the servlet context $sessionSettings->mergeServletContext($servletManager); } }
/** * Append the deployed application to the deployment instance * and registers it in the system configuration. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application to append * * @return void */ public function addApplication(ApplicationInterface $application) { // register the application in this instance $this->applications[$application->getName()] = $application; // adds the application to the system configuration $this->addApplicationToSystemConfiguration($application); }
/** * Deploys the message queues. * * @param \AppserverIo\Psr\Application\ApplicationInterface|\AppserverIo\Psr\Naming\NamingDirectoryInterface $application The application instance * * @return void */ protected function registerMessageQueues(ApplicationInterface $application) { // build up META-INF directory var $metaInfDir = $this->getWebappPath() . DIRECTORY_SEPARATOR . 'META-INF'; // check if we've found a valid directory if (is_dir($metaInfDir) === false) { return; } // initialize the array for the creating the subdirectories $this->directories = new GenericStackable(); $this->directories[] = $application->getNamingDirectory(); // check META-INF + subdirectories for XML files with MQ definitions /** @var \AppserverIo\Appserver\Core\Api\DeploymentService $service */ $service = $application->newService('AppserverIo\\Appserver\\Core\\Api\\DeploymentService'); $xmlFiles = $service->globDir(AppEnvironmentHelper::getEnvironmentAwareGlobPattern($this->getWebappPath(), 'META-INF' . DIRECTORY_SEPARATOR . 'message-queues')); // load the configuration service instance /** @var \AppserverIo\Appserver\Core\Api\ConfigurationService $configurationService */ $configurationService = $application->newService('AppserverIo\\Appserver\\Core\\Api\\ConfigurationService'); // load the container node to initialize the system properties /** @var \AppserverIo\Appserver\Core\Api\Node\ContainerNodeInterface $containerNode */ $containerNode = $application->getContainer()->getContainerNode(); // gather all the deployed web applications foreach ($xmlFiles as $file) { try { // validate the file here, but skip if the validation fails $configurationService->validateFile($file, null, true); // load the system properties $properties = $service->getSystemProperties($containerNode); // append the application specific properties $properties->add(SystemPropertyKeys::WEBAPP, $webappPath = $application->getWebappPath()); $properties->add(SystemPropertyKeys::WEBAPP_NAME, basename($webappPath)); $properties->add(SystemPropertyKeys::WEBAPP_CACHE, $application->getCacheDir()); $properties->add(SystemPropertyKeys::WEBAPP_SESSION, $application->getSessionDir()); // create a new message queue node instance and replace the properties $messageQueuesNode = new MessageQueuesNode(); $messageQueuesNode->initFromFile($file); $messageQueuesNode->replaceProperties($properties); // register the entity managers found in the configuration foreach ($messageQueuesNode->getMessageQueues() as $messageQueueNode) { $this->registeMessageQueue($messageQueueNode); } } catch (InvalidConfigurationException $e) { // try to load the system logger instance /** @var \Psr\Log\LoggerInterface $systemLogger */ if ($systemLogger = $this->getApplication()->getInitialContext()->getSystemLogger()) { $systemLogger->error($e->getMessage()); $systemLogger->critical(sprintf('Persistence configuration file %s is invalid, needed queues might be missing.', $file)); } } catch (\Exception $e) { // try to load the system logger instance /** @var \Psr\Log\LoggerInterface $systemLogger */ if ($systemLogger = $this->getApplication()->getInitialContext()->getSystemLogger()) { $systemLogger->error($e->__toString()); } } } }
/** * Registers aspects written within source files which we might encounter * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * * @return void */ public function registerAspectXml(ApplicationInterface $application) { /** @var \AppserverIo\Appserver\Core\Api\ConfigurationService $configurationService */ $configurationService = $application->newService('AppserverIo\\Appserver\\Core\\Api\\ConfigurationService'); // check if we even have a XMl file to read from $xmlPaths = $configurationService->globDir($this->getWebappPath() . DIRECTORY_SEPARATOR . '{WEB-INF,META-INF,common}' . DIRECTORY_SEPARATOR . self::CONFIG_FILE, GLOB_BRACE); foreach ($xmlPaths as $xmlPath) { // iterate all XML configuration files we found if (is_readable($xmlPath)) { // validate the file here, if it is not valid we can skip further steps try { $configurationService->validateFile($xmlPath, null, true); } catch (InvalidConfigurationException $e) { /** @var \Psr\Log\LoggerInterface $systemLogger */ $systemLogger = $this->getApplication()->getInitialContext()->getSystemLogger(); $systemLogger->error($e->getMessage()); $systemLogger->critical(sprintf('Pointcuts configuration file %s is invalid, AOP functionality might not work as expected.', $xmlPath)); continue; } // load the aop config $config = new \SimpleXMLElement(file_get_contents($xmlPath)); $config->registerXPathNamespace('a', 'http://www.appserver.io/appserver'); // create us an aspect // name of the aspect will be the application name $aspect = new Aspect(); $aspect->setName($xmlPath); // check if we got some pointcuts foreach ($config->xpath('/a:pointcuts/a:pointcut') as $pointcutConfiguration) { // build up the pointcut and add it to the collection $pointcut = new Pointcut(); $pointcut->setAspectName($aspect->getName()); $pointcut->setName((string) $pointcutConfiguration->{'pointcut-name'}); $pointcut->setPointcutExpression(new PointcutExpression((string) $pointcutConfiguration->{'pointcut-pattern'})); $aspect->getPointcuts()->add($pointcut); } // check if we got some advices foreach ($config->xpath('/a:pointcuts/a:advice') as $adviceConfiguration) { // build up the advice and add it to the aspect $advice = new Advice(); $advice->setAspectName((string) $adviceConfiguration->{'advice-aspect'}); $advice->setName($advice->getAspectName() . '->' . (string) $adviceConfiguration->{'advice-name'}); $advice->setCodeHook((string) $adviceConfiguration->{'advice-type'}); $pointcutPointcut = $this->generatePointcutPointcut((array) $adviceConfiguration->{'advice-pointcuts'}->{'pointcut-name'}, $aspect); $advice->getPointcuts()->add($pointcutPointcut); // finally add the advice to our aspect (we will also add it without pointcuts of its own) $aspect->getAdvices()->add($advice); } // if the aspect contains pointcuts or advices it can be used if ($aspect->getPointcuts()->count() > 0 || $aspect->getAdvices()->count() > 0) { $this->getAspectRegister()->set($aspect->getName(), $aspect); } } } }
/** * 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)); }