001/* 002 * Copyright 2012 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.core.engine; 017 018import java.util.HashMap; 019import java.util.Map; 020 021import org.apache.avalon.framework.CascadingRuntimeException; 022import org.apache.avalon.framework.component.WrapperComponentManager; 023import org.apache.avalon.framework.logger.Logger; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.cocoon.Processor; 026import org.apache.cocoon.components.CocoonComponentManager; 027import org.apache.cocoon.environment.Context; 028import org.apache.cocoon.environment.commandline.AbstractCommandLineEnvironment; 029import org.apache.commons.text.CharacterPredicates; 030import org.apache.commons.text.RandomStringGenerator; 031 032/** 033 * Abstract class for work run in a separate thread. 034 */ 035public final class BackgroundEngineHelper 036{ 037 private static RandomStringGenerator _randomStringGenerator = new RandomStringGenerator.Builder().withinRange('0', 'z').filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS).build(); 038 039 private BackgroundEngineHelper() 040 { 041 // Hides the default constructor. 042 } 043 044 /** 045 * Test if cocoon is currently in an environment. 046 * @return true if cocoon is currently in an environment, false otherwise. 047 */ 048 public static boolean environmentExists() 049 { 050 return CocoonComponentManager.getCurrentEnvironment() != null; 051 } 052 053 /** 054 * Create and enter a cocoon environment specific to the engine. 055 * @param manager the avalon service manager. 056 * @param context the cocoon environment context. 057 * @param logger the class logger. 058 * @return a Map with the environment information. 059 */ 060 public static Map<String, Object> createAndEnterEngineEnvironment(ServiceManager manager, Context context, Logger logger) 061 { 062 BackgroundEnvironment environment; 063 Processor processor; 064 065 // Création de l'environnement cocoon particulier 066 try 067 { 068 environment = new BackgroundEnvironment(logger, context); 069 processor = (Processor) manager.lookup(Processor.ROLE); 070 } 071 catch (Exception e) 072 { 073 throw new CascadingRuntimeException("Error during environment's setup.", e); 074 } 075 076 // Random request ID: used by AbstractCachingPipeline to implement pipeline locking. 077 String requestId = _randomStringGenerator.generate(8); 078 environment.getObjectModel().put(AbstractCommandLineEnvironment.CLI_REQUEST_ID, requestId); 079 080 Object processingKey = CocoonComponentManager.startProcessing(environment); 081 int environmentDepth = CocoonComponentManager.markEnvironment(); 082 083 CocoonComponentManager.enterEnvironment(environment, new WrapperComponentManager(manager), processor); 084 085 BackgroundEngineHookExtensionPoint backgroundEngineHookEP; 086 try 087 { 088 backgroundEngineHookEP = (BackgroundEngineHookExtensionPoint) manager.lookup(BackgroundEngineHookExtensionPoint.ROLE); 089 } 090 catch (Exception e) 091 { 092 throw new CascadingRuntimeException("Error during environment's setup.", e); 093 } 094 095 Map<String, Object> result = new HashMap<>(); 096 097 result.put("manager", manager); 098 result.put("logger", logger); 099 result.put("environment", environment); 100 result.put("processor", processor); 101 result.put("processingKey", processingKey); 102 result.put("environmentDepth", Integer.valueOf(environmentDepth)); 103 result.put("hookEP", backgroundEngineHookEP); 104 105 // on enter hooks 106 for (String hookId : backgroundEngineHookEP.getExtensionsIds()) 107 { 108 BackgroundEngineHook hook = backgroundEngineHookEP.getExtension(hookId); 109 hook.onEnteringEnvironment(result); 110 } 111 112 return result; 113 } 114 115 /** 116 * Leave the cocoon environment. 117 * @param environmentInformation the environment information. 118 */ 119 public static void leaveEngineEnvironment(Map<String, Object> environmentInformation) 120 { 121 if (environmentInformation == null) 122 { 123 return; 124 } 125 126 BackgroundEnvironment environment = (BackgroundEnvironment) environmentInformation.get("environment"); 127 Processor processor = (Processor) environmentInformation.get("processor"); 128 Object processingKey = environmentInformation.get("processingKey"); 129 int environmentDepth = ((Integer) environmentInformation.get("environmentDepth")).intValue(); 130 ServiceManager manager = (ServiceManager) environmentInformation.get("manager"); 131 Logger logger = (Logger) environmentInformation.get("logger"); 132 BackgroundEngineHookExtensionPoint backgroundEngineHookEP = (BackgroundEngineHookExtensionPoint) environmentInformation.get("hookEP"); 133 134 // on leave hooks 135 for (String hookId : backgroundEngineHookEP.getExtensionsIds()) 136 { 137 BackgroundEngineHook hook = backgroundEngineHookEP.getExtension(hookId); 138 hook.onLeavingEnvironment(environmentInformation); 139 } 140 141 CocoonComponentManager.leaveEnvironment(); 142 CocoonComponentManager.endProcessing(environment, processingKey); 143 144 try 145 { 146 CocoonComponentManager.checkEnvironment(environmentDepth, logger); 147 } 148 catch (Exception e) 149 { 150 throw new CascadingRuntimeException("Error checking the environment", e); 151 } 152 153 manager.release(backgroundEngineHookEP); 154 manager.release(processor); 155 } 156}