1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  package org.kuali.rice.edl.impl;
18  
19  import org.apache.log4j.Logger;
20  import org.kuali.rice.core.api.util.xml.XmlHelper;
21  import org.kuali.rice.core.api.util.xml.XmlJotter;
22  import org.kuali.rice.edl.impl.bo.EDocLiteAssociation;
23  import org.kuali.rice.edl.impl.service.EDocLiteService;
24  import org.kuali.rice.edl.impl.service.EdlServiceLocator;
25  import org.kuali.rice.kew.api.WorkflowRuntimeException;
26  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
27  import org.kuali.rice.ksb.api.KsbApiServiceLocator;
28  import org.w3c.dom.Document;
29  import org.w3c.dom.Element;
30  import org.w3c.dom.Node;
31  import org.w3c.dom.NodeList;
32  
33  import javax.xml.parsers.DocumentBuilderFactory;
34  import javax.xml.transform.Templates;
35  import java.util.Iterator;
36  import java.util.LinkedHashMap;
37  import java.util.Map;
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  public class EDLControllerFactory {
48  
49  	private static final Logger LOG = Logger.getLogger(EDLControllerFactory.class);
50  	
51  	private static final String CONFIG_CACHE_GROUP_NAME = "EDLConfig";
52  
53  	
54  
55  	public static EDLController createEDLController(EDocLiteAssociation edlAssociation, EDLGlobalConfig edlGlobalConfig) {
56          EDLController edlController = new EDLController();
57  		edlController.setEdocLiteAssociation(edlAssociation);
58  
59  		try {
60  			edlController.setEdlGlobalConfig(edlGlobalConfig);
61  			edlController.setDefaultDOM(getDefaultDOM(edlAssociation));
62  			loadConfigProcessors(edlController, edlGlobalConfig);
63  			loadPreProcessors(edlController, edlGlobalConfig);
64  			loadPostProcessor(edlController, edlGlobalConfig);
65  			loadStateComponents(edlController, edlGlobalConfig);
66  			loadStyle(edlController);
67  			
68  		} catch (Exception e) {
69              String edl = null;
70              if (edlAssociation != null) {
71                  edl = edlAssociation.getEdlName();
72              }
73              String message = "Error creating controller for EDL" + (edl == null ? "" : ": " + edl);
74              LOG.error(message, e);
75  			throw new WorkflowRuntimeException("Problems creating controller for EDL: " + edl, e);
76  		}
77  
78  		return edlController;
79  	}
80  
81  	public static EDLController createEDLController(EDocLiteAssociation edlAssociation, EDLGlobalConfig edlGlobalConfig, DocumentRouteHeaderValue document) {
82  		EDLController edlController = createEDLController(edlAssociation, edlGlobalConfig);
83  		try {
84  			Document defaultDom = edlController.getDefaultDOM();
85  			Document documentDom = XmlHelper.readXml(document.getDocContent());
86  			
87  			Element documentData = (Element) documentDom.getElementsByTagName(EDLXmlUtils.DATA_E).item(0);
88  			if (documentData != null) {
89  				Element defaultDomEDL = EDLXmlUtils.getEDLContent(defaultDom, false);
90  				Element defaultDomData = (Element) defaultDomEDL.getElementsByTagName(EDLXmlUtils.DATA_E).item(0);
91  				defaultDomEDL.replaceChild(defaultDom.importNode(documentData, true), defaultDomData);
92  			}
93  			if (LOG.isDebugEnabled()) {
94  				LOG.debug("Created default Node from document id " + document.getDocumentId() + " content " + XmlJotter.jotNode(defaultDom));
95  			}
96  		} catch (Exception e) {
97  			throw new WorkflowRuntimeException("Problems creating controller for EDL " + edlAssociation.getEdlName() + " document " + document.getDocumentId(), e);
98  		}
99  		return edlController;
100 	}
101 
102 	private synchronized static void loadStyle(EDLController edlController) throws Exception {
103 		EDocLiteService edlService = getEDLService();
104 		Templates styleSheet = null;
105 		styleSheet = edlService.getStyleAsTranslet(edlController.getEdocLiteAssociation().getStyle());
106 		edlController.setStyle(styleSheet);
107 	}
108 	
109 	private synchronized static void loadPreProcessors(EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
110 		edlController.setPreProcessors(cloneConfigMap(edlGlobalConfig.getPreProcessors(), edlController.getDefaultDOM()));
111 	}
112 	
113 	private synchronized static void loadPostProcessor(EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
114 		edlController.setPostProcessors(cloneConfigMap(edlGlobalConfig.getPostProcessors(), edlController.getDefaultDOM()));
115 	}
116 	
117 	private synchronized static void loadStateComponents(EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
118 		edlController.setStateComponents(cloneConfigMap(edlGlobalConfig.getStateComponents(), edlController.getDefaultDOM()));
119 	}
120 
121 	private synchronized static void loadConfigProcessors(EDLController edlController, EDLGlobalConfig edlGlobalConfig) throws Exception {
122 		EDocLiteAssociation edlAssociation = edlController.getEdocLiteAssociation();
123 		Map configProcessorMappings = fetchConfigFromCache(edlAssociation.getDefinition());
124 		if (configProcessorMappings != null) {
125 			edlController.setConfigProcessors(cloneConfigMap(configProcessorMappings, edlController.getDefaultDOM()));
126 		} else {
127 			
128 			Document document = getEDLService().getDefinitionXml(edlAssociation);
129 			Element definitionElement = (Element) document.getFirstChild();
130 
131 			configProcessorMappings = new LinkedHashMap();
132 			edlController.setEdlGlobalConfig(edlGlobalConfig);
133 			NodeList edlDefinitionNodes = definitionElement.getChildNodes();
134 			for (int i = 0; i < edlDefinitionNodes.getLength(); i++) {
135 				Node definitionNode = edlDefinitionNodes.item(i);
136 				Class configProcessorClass = edlGlobalConfig.getConfigProcessor(definitionNode);
137 				if (configProcessorClass != null) {
138 					configProcessorMappings.put(definitionNode, configProcessorClass);
139 				}
140 			}
141 			putConfigInCache(edlAssociation.getDefinition(), configProcessorMappings);
142 
143 			loadConfigProcessors(edlController, edlGlobalConfig);
144 		}
145 	}
146 	
147 	protected synchronized static Map fetchConfigFromCache(String definition) {
148 		return (Map) KsbApiServiceLocator.getCacheAdministrator().getFromCache(getConfigCacheKey(definition));
149 	}
150 	
151 	private synchronized static void putConfigInCache(String definition, Map configProcessorMappings) {
152 		KsbApiServiceLocator.getCacheAdministrator().putInCache(getConfigCacheKey(definition), configProcessorMappings, CONFIG_CACHE_GROUP_NAME);
153 	}
154 	
155 	private static String getConfigCacheKey(String definition) {
156 		return CONFIG_CACHE_GROUP_NAME + ":" + definition;
157 	}
158 	
159 	private synchronized static Map cloneConfigMap(Map configMap, Document defaultDom) {
160 		Map tempConfigProcessors = new LinkedHashMap();
161 		for (Iterator iter = configMap.entrySet().iterator(); iter.hasNext();) {
162 			Map.Entry configProcessorMapping = (Map.Entry) iter.next();
163 			tempConfigProcessors.put(defaultDom.importNode((Node)configProcessorMapping.getKey(), true), configProcessorMapping.getValue());
164 		}
165 		return tempConfigProcessors;
166 	}
167 
168 	private static EDocLiteService getEDLService() {
169 		return EdlServiceLocator.getEDocLiteService();
170 	}
171 
172 	private static Document getDefaultDOM(EDocLiteAssociation edlAssociation) throws Exception {
173 		Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
174 		Element rootElement = dom.createElement("documentContent"); 
175 		
176 		
177 		
178 		
179 		
180 		
181 		dom.appendChild(rootElement);
182 		Element edlContentElement = EDLXmlUtils.getEDLContent(dom, true);
183 		EDLXmlUtils.getDataFromEDLDocument(edlContentElement, true);
184 		
185 		
186 		Element edlData = EDLXmlUtils.getChildElement(edlContentElement, EDLXmlUtils.DATA_E);
187 		
188 		edlData.setAttribute("edlName", edlAssociation.getEdlName());
189 		
190 		return dom;
191 	}
192 
193 	public static void flushDefinitionFromConfigCache(String definition) {
194 		KsbApiServiceLocator.getCacheAdministrator().flushEntry(getConfigCacheKey(definition));
195 
196 	}
197 	
198 	public static void flushDefinitionCache() {
199 		KsbApiServiceLocator.getCacheAdministrator().flushGroup(CONFIG_CACHE_GROUP_NAME);
200 	}
201 }