AppserverIo\Appserver\Core\Api\Node\ContextNode::merge PHP Method

merge() public method

This method merges the installation steps of the passed provisioning node into the steps of this instance. If a installation node with the same type already exists, the one of this instance will be overwritten.
public merge ( ContextNode $contextNode ) : void
$contextNode ContextNode The node with the installation steps we want to merge
return void
    public function merge(ContextNode $contextNode)
    {
        // merge the application type
        if ($type = $contextNode->getType()) {
            $this->setType($type);
        }
        // merge the application factory class name
        if ($factory = $contextNode->getFactory()) {
            $this->setFactory($factory);
        }
        // merge the application webapp path
        if ($webappPath = $contextNode->getWebappPath()) {
            $this->setWebappPath($webappPath);
        }
        // load the params defined in this context
        $localParams = $this->getParams();
        // merge them with the passed ones
        foreach ($contextNode->getParams() as $paramToMerge) {
            $isMerged = false;
            /** @var \AppserverIo\Appserver\Core\Api\Node\ParamNode $param */
            foreach ($localParams as $key => $param) {
                if ($param->getName() == $paramToMerge->getName()) {
                    $localParams[$key] = $paramToMerge;
                    $isMerged = true;
                }
            }
            if ($isMerged === false) {
                $localParams[$paramToMerge->getUuid()] = $paramToMerge;
            }
        }
        // set the params back to the context
        $this->setParams($localParams);
        // load the managers defined of this context
        $localManagers = $this->getManagers();
        // merge them with the passed ones
        /**  @var \AppserverIo\Appserver\Core\Api\Node\ManagerNode $managerToMerge */
        foreach ($contextNode->getManagers() as $managerToMerge) {
            $isMerged = false;
            /** @var \AppserverIo\Appserver\Core\Api\Node\ManagerNode $manager */
            foreach ($localManagers as $key => $manager) {
                if ($manager->getName() === $managerToMerge->getName()) {
                    $manager->merge($managerToMerge);
                    $localManagers[$key] = $manager;
                    $isMerged = true;
                }
            }
            if ($isMerged === false) {
                $localManagers[$managerToMerge->getUuid()] = $managerToMerge;
            }
        }
        // set the managers back to the context
        $this->setManagers($localManagers);
        // load the class loaders of this context
        $localClassLoaders = $this->getClassLoaders();
        // merge them with the passed ones
        /** @var \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNode $classLoaderToMerge */
        foreach ($contextNode->getClassLoaders() as $classLoaderToMerge) {
            $isMerged = false;
            /** @var \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNode $classLoader */
            foreach ($localClassLoaders as $key => $classLoader) {
                if ($classLoader->getName() === $classLoaderToMerge->getName()) {
                    $localClassLoaders[$key] = $classLoaderToMerge;
                    $isMerged = true;
                }
            }
            if ($isMerged === false) {
                $localClassLoaders[$classLoaderToMerge->getUuid()] = $classLoaderToMerge;
            }
        }
        // set the class loaders back to the context
        $this->setClassLoaders($localClassLoaders);
        // load the loggers of this context
        $localLoggers = $this->getLoggers();
        // merge them with the passed ones (DO override already registered loggers)
        /** @var \AppserverIo\Appserver\Core\Api\Node\LoggerNode $loggerToMerge */
        foreach ($contextNode->getLoggers() as $loggerToMerge) {
            $localLoggers[$loggerToMerge->getName()] = $loggerToMerge;
        }
        // set the loggers back to the context
        $this->setLoggers($localLoggers);
    }

Usage Example

 /**
  * Initializes the context instance for the passed webapp path.
  *
  * @param \AppserverIo\Appserver\Core\Api\Node\ContainerNodeInterface $containerNode The container to load the context for
  * @param string                                                      $webappPath    The path to the web application
  *
  * @return \AppserverIo\Appserver\Core\Api\Node\ContextNode The initialized context instance
  */
 public function loadContextInstance(ContainerNodeInterface $containerNode, $webappPath)
 {
     // prepare the context path
     $contextPath = basename($webappPath);
     // load the system properties
     $properties = $this->getSystemProperties($containerNode);
     // append the application specific properties
     $properties->add(SystemPropertyKeys::WEBAPP, $webappPath);
     $properties->add(SystemPropertyKeys::WEBAPP_NAME, $contextPath);
     // validate the base context file
     /** @var \AppserverIo\Appserver\Core\Api\ConfigurationService $configurationService */
     $configurationService = $this->newService('AppserverIo\\Appserver\\Core\\Api\\ConfigurationService');
     $configurationService->validateFile($baseContextPath = $this->getConfdDir('context.xml'), null);
     //load it as default if validation succeeds
     $context = new ContextNode();
     $context->initFromFile($baseContextPath);
     $context->replaceProperties($properties);
     // set the context webapp path
     $context->setWebappPath($webappPath);
     // try to load a context configuration (from appserver.xml) for the context path
     if ($contextToMerge = $containerNode->getHost()->getContext($contextPath)) {
         $contextToMerge->replaceProperties($properties);
         $context->merge($contextToMerge);
     }
     // iterate through all context configurations (context.xml), validate and merge them
     foreach ($this->globDir(AppEnvironmentHelper::getEnvironmentAwareGlobPattern($webappPath, 'META-INF/context')) as $contextFile) {
         try {
             // validate the application specific context
             $configurationService->validateFile($contextFile, null);
             // create a new context node instance and replace the properties
             $contextInstance = new ContextNode();
             $contextInstance->initFromFile($contextFile);
             $contextInstance->replaceProperties($properties);
             // merge it into the default configuration
             $context->merge($contextInstance);
         } 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 app specific context file %s, configuration might be faulty.', $contextFile));
         }
     }
     // set the real context name
     $context->setName($contextPath);
     $context->setEnvironmentName(AppEnvironmentHelper::getEnvironmentModifier($webappPath));
     // return the initialized context instance
     return $context;
 }