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 }