View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    * 
4    * 
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    * 
9    * http://www.opensource.org/licenses/ecl2.php
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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   * Creates EDL controllers.  Contains a cache of parsed EDL configurations.  The parsed config is a definition name related to 
42   * a Map containing config element and their associated class.
43   * 
44   * @author Kuali Rice Team (rice.collab@kuali.org)
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  	//private static Map edlConfigCache = new HashMap();
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  			// get the data node and import it into our default DOM
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 			// these are classes mapped to the conf element from the edlconfig.
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 //			edlConfigCache.put(edlAssociation.getDefinition(), configProcessorMappings);
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"); // this is a
175 		// throwback
176 		// to some
177 		// original
178 		// madness
179 		// to get EDL routing over a year ago we need to look into this being
180 		// eliminated.
181 		dom.appendChild(rootElement);
182 		Element edlContentElement = EDLXmlUtils.getEDLContent(dom, true);
183 		EDLXmlUtils.getDataFromEDLDocument(edlContentElement, true);
184 		
185 		// get the data element that was just created ***jitrue***
186 		Element edlData = EDLXmlUtils.getChildElement(edlContentElement, EDLXmlUtils.DATA_E);
187 		// set edlName attribute on data element of default DOM ***jitrue***
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 //		edlConfigCache.remove(defName);
196 	}
197 	
198 	public static void flushDefinitionCache() {
199 		KsbApiServiceLocator.getCacheAdministrator().flushGroup(CONFIG_CACHE_GROUP_NAME);
200 	}
201 }