001: /*
002: * Copyright 2005-2006 The Kuali Foundation.
003: *
004: *
005: * Licensed under the Educational Community License, Version 1.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.opensource.org/licenses/ecl1.php
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package edu.iu.uis.eden.edl;
018:
019: import java.util.Iterator;
020: import java.util.LinkedHashMap;
021: import java.util.Map;
022:
023: import javax.xml.parsers.DocumentBuilderFactory;
024: import javax.xml.transform.Templates;
025:
026: import org.apache.log4j.Logger;
027: import org.w3c.dom.Document;
028: import org.w3c.dom.Element;
029: import org.w3c.dom.Node;
030: import org.w3c.dom.NodeList;
031:
032: import edu.iu.uis.eden.KEWServiceLocator;
033: import edu.iu.uis.eden.exception.WorkflowRuntimeException;
034: import edu.iu.uis.eden.routeheader.DocumentRouteHeaderValue;
035: import edu.iu.uis.eden.util.XmlHelper;
036:
037: /**
038: * Creates EDL controllers. Contains a cache of parsed EDL configurations. The parsed config is a definition name related to
039: * a Map containing config element and their associated class.
040: *
041: * @author rkirkend
042: *
043: */
044: public class EDLControllerFactory {
045:
046: private static final Logger LOG = Logger
047: .getLogger(EDLControllerFactory.class);
048:
049: private static final String CONFIG_CACHE_GROUP_NAME = "EDLConfig";
050:
051: //private static Map edlConfigCache = new HashMap();
052:
053: public static EDLController createEDLController(
054: EDocLiteAssociation edlAssociation,
055: EDLGlobalConfig edlGlobalConfig) {
056: EDLController edlController = new EDLController();
057: edlController.setEdocLiteAssociation(edlAssociation);
058:
059: try {
060: edlController.setEdlGlobalConfig(edlGlobalConfig);
061: edlController.setDefaultDOM(getDefaultDOM(edlAssociation));
062: loadConfigProcessors(edlController, edlGlobalConfig);
063: loadPreProcessors(edlController, edlGlobalConfig);
064: loadPostProcessor(edlController, edlGlobalConfig);
065: loadStateComponents(edlController, edlGlobalConfig);
066: loadStyle(edlController);
067:
068: } catch (Exception e) {
069: String edl = null;
070: if (edlAssociation != null) {
071: edl = edlAssociation.getEdlName();
072: }
073: String message = "Error creating controller for EDL"
074: + (edl == null ? "" : ": " + edl);
075: LOG.error(message, e);
076: throw new WorkflowRuntimeException(
077: "Problems creating controller for EDL: " + edl, e);
078: }
079:
080: return edlController;
081: }
082:
083: public static EDLController createEDLController(
084: EDocLiteAssociation edlAssociation,
085: EDLGlobalConfig edlGlobalConfig,
086: DocumentRouteHeaderValue document) {
087: EDLController edlController = createEDLController(
088: edlAssociation, edlGlobalConfig);
089: try {
090: Document defaultDom = edlController.getDefaultDOM();
091: Document documentDom = XmlHelper.readXml(document
092: .getDocContent());
093: // get the data node and import it into our default DOM
094: Element documentData = (Element) documentDom
095: .getElementsByTagName(EDLXmlUtils.DATA_E).item(0);
096: if (documentData != null) {
097: Element defaultDomEDL = EDLXmlUtils.getEDLContent(
098: defaultDom, false);
099: Element defaultDomData = (Element) defaultDomEDL
100: .getElementsByTagName(EDLXmlUtils.DATA_E).item(
101: 0);
102: defaultDomEDL.replaceChild(defaultDom.importNode(
103: documentData, true), defaultDomData);
104: }
105: if (LOG.isDebugEnabled()) {
106: LOG.debug("Created default Node from document id "
107: + document.getRouteHeaderId() + " content "
108: + XmlHelper.jotNode(defaultDom));
109: }
110: } catch (Exception e) {
111: throw new WorkflowRuntimeException(
112: "Problems creating controller for EDL "
113: + edlAssociation.getEdlName()
114: + " document "
115: + document.getRouteHeaderId(), e);
116: }
117: return edlController;
118: }
119:
120: private synchronized static void loadStyle(
121: EDLController edlController) throws Exception {
122: EDocLiteService edlService = getEDLService();
123: Templates styleSheet = null;
124: styleSheet = edlService.getStyleAsTranslet(edlController
125: .getEdocLiteAssociation().getStyle());
126: edlController.setStyle(styleSheet);
127: }
128:
129: private synchronized static void loadPreProcessors(
130: EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
131: edlController.setPreProcessors(cloneConfigMap(edlGlobalConfig
132: .getPreProcessors(), edlController.getDefaultDOM()));
133: }
134:
135: private synchronized static void loadPostProcessor(
136: EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
137: edlController.setPostProcessors(cloneConfigMap(edlGlobalConfig
138: .getPostProcessors(), edlController.getDefaultDOM()));
139: }
140:
141: private synchronized static void loadStateComponents(
142: EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
143: edlController.setStateComponents(cloneConfigMap(edlGlobalConfig
144: .getStateComponents(), edlController.getDefaultDOM()));
145: }
146:
147: private synchronized static void loadConfigProcessors(
148: EDLController edlController, EDLGlobalConfig edlGlobalConfig)
149: throws Exception {
150: EDocLiteAssociation edlAssociation = edlController
151: .getEdocLiteAssociation();
152: Map configProcessorMappings = fetchConfigFromCache(edlAssociation
153: .getDefinition());
154: if (configProcessorMappings != null) {
155: edlController.setConfigProcessors(cloneConfigMap(
156: configProcessorMappings, edlController
157: .getDefaultDOM()));
158: } else {
159: // these are classes mapped to the conf element from the edlconfig.
160: Document document = getEDLService().getDefinitionXml(
161: edlAssociation);
162: Element definitionElement = (Element) document
163: .getFirstChild();
164:
165: configProcessorMappings = new LinkedHashMap();
166: edlController.setEdlGlobalConfig(edlGlobalConfig);
167: NodeList edlDefinitionNodes = definitionElement
168: .getChildNodes();
169: for (int i = 0; i < edlDefinitionNodes.getLength(); i++) {
170: Node definitionNode = edlDefinitionNodes.item(i);
171: Class configProcessorClass = edlGlobalConfig
172: .getConfigProcessor(definitionNode);
173: if (configProcessorClass != null) {
174: configProcessorMappings.put(definitionNode,
175: configProcessorClass);
176: }
177: }
178: putConfigInCache(edlAssociation.getDefinition(),
179: configProcessorMappings);
180: // edlConfigCache.put(edlAssociation.getDefinition(), configProcessorMappings);
181: loadConfigProcessors(edlController, edlGlobalConfig);
182: }
183: }
184:
185: protected synchronized static Map fetchConfigFromCache(
186: String definition) {
187: return (Map) KEWServiceLocator.getCacheAdministrator()
188: .getFromCache(getConfigCacheKey(definition));
189: }
190:
191: private synchronized static void putConfigInCache(
192: String definition, Map configProcessorMappings) {
193: KEWServiceLocator.getCacheAdministrator().putInCache(
194: getConfigCacheKey(definition), configProcessorMappings,
195: CONFIG_CACHE_GROUP_NAME);
196: }
197:
198: private static String getConfigCacheKey(String definition) {
199: return CONFIG_CACHE_GROUP_NAME + ":" + definition;
200: }
201:
202: private synchronized static Map cloneConfigMap(Map configMap,
203: Document defaultDom) {
204: Map tempConfigProcessors = new LinkedHashMap();
205: for (Iterator iter = configMap.entrySet().iterator(); iter
206: .hasNext();) {
207: Map.Entry configProcessorMapping = (Map.Entry) iter.next();
208: tempConfigProcessors.put(defaultDom.importNode(
209: (Node) configProcessorMapping.getKey(), true),
210: configProcessorMapping.getValue());
211: }
212: return tempConfigProcessors;
213: }
214:
215: private static EDocLiteService getEDLService() {
216: return KEWServiceLocator.getEDocLiteService();
217: }
218:
219: private static Document getDefaultDOM(
220: EDocLiteAssociation edlAssociation) throws Exception {
221: Document dom = DocumentBuilderFactory.newInstance()
222: .newDocumentBuilder().newDocument();
223: Element rootElement = dom.createElement("documentContent"); // this is a
224: // throwback
225: // to some
226: // original
227: // madness
228: // to get EDL routing over a year ago we need to look into this being
229: // eliminated.
230: dom.appendChild(rootElement);
231: Element edlContentElement = EDLXmlUtils
232: .getEDLContent(dom, true);
233: EDLXmlUtils.getDataFromEDLDocument(edlContentElement, true);
234:
235: // get the data element that was just created ***jitrue***
236: Element edlData = EDLXmlUtils.getChildElement(
237: edlContentElement, EDLXmlUtils.DATA_E);
238: // set edlName attribute on data element of default DOM ***jitrue***
239: edlData.setAttribute("edlName", edlAssociation.getEdlName());
240:
241: return dom;
242: }
243:
244: public static void flushDefinitionFromConfigCache(String definition) {
245: KEWServiceLocator.getCacheAdministrator().flushEntry(
246: getConfigCacheKey(definition));
247: // edlConfigCache.remove(defName);
248: }
249:
250: public static void flushDefinitionCache() {
251: KEWServiceLocator.getCacheAdministrator().flushGroup(
252: CONFIG_CACHE_GROUP_NAME);
253: }
254: }
|