View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.edl.impl;
17  
18  import org.apache.log4j.Logger;
19  import org.kuali.rice.core.api.util.xml.XmlHelper;
20  import org.kuali.rice.core.api.util.xml.XmlJotter;
21  import org.kuali.rice.edl.impl.bo.EDocLiteAssociation;
22  import org.kuali.rice.edl.impl.service.EDocLiteService;
23  import org.kuali.rice.edl.impl.service.EdlServiceLocator;
24  import org.kuali.rice.kew.api.WorkflowRuntimeException;
25  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
26  import org.kuali.rice.krad.util.GlobalVariables;
27  import org.w3c.dom.Document;
28  import org.w3c.dom.Element;
29  import org.w3c.dom.Node;
30  import org.w3c.dom.NodeList;
31  
32  import javax.xml.parsers.DocumentBuilderFactory;
33  import javax.xml.transform.Templates;
34  import javax.xml.xpath.XPathFactory;
35  import java.util.Iterator;
36  import java.util.LinkedHashMap;
37  import java.util.Map;
38  
39  
40  /**
41   * Creates EDL controllers.  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 final class EDLControllerFactory {
48  
49      private EDLControllerFactory() {
50          throw new UnsupportedOperationException("do not call");
51      }
52  
53  	private static final Logger LOG = Logger.getLogger(EDLControllerFactory.class);
54  
55  	public static EDLController createEDLController(EDocLiteAssociation edlAssociation, EDLGlobalConfig edlGlobalConfig) {
56          EDLController edlController = new EDLController();
57  		edlController.setEdocLiteAssociation(edlAssociation);
58          edlController.setEdlContext(getPreEDLContext(edlController));
59  
60          try {
61  			edlController.setEdlGlobalConfig(edlGlobalConfig);
62  			edlController.setDefaultDOM(getDefaultDOM(edlAssociation));
63  			loadConfigProcessors(edlController, edlGlobalConfig);
64  			loadPreProcessors(edlController, edlGlobalConfig);
65  			loadPostProcessor(edlController, edlGlobalConfig);
66  			loadStateComponents(edlController, edlGlobalConfig);
67  			loadStyle(edlController);
68  			
69  		} catch (Exception e) {
70              String edl = null;
71              if (edlAssociation != null) {
72                  edl = edlAssociation.getEdlName();
73              }
74              String message = "Error creating controller for EDL" + (edl == null ? "" : ": " + edl);
75              LOG.error(message, e);
76  			throw new WorkflowRuntimeException("Problems creating controller for EDL: " + edl, e);
77  		}
78  
79  		return edlController;
80  	}
81  
82  	public static EDLController createEDLController(EDocLiteAssociation edlAssociation, EDLGlobalConfig edlGlobalConfig, DocumentRouteHeaderValue document) {
83  		EDLController edlController = createEDLController(edlAssociation, edlGlobalConfig);
84  		try {
85  			Document defaultDom = edlController.getDefaultDOM();
86  			Document documentDom = XmlHelper.readXml(document.getDocContent());
87  			// get the data node and import it into our default DOM
88  			Element documentData = (Element) documentDom.getElementsByTagName(EDLXmlUtils.DATA_E).item(0);
89  			if (documentData != null) {
90  				Element defaultDomEDL = EDLXmlUtils.getEDLContent(defaultDom, false);
91  				Element defaultDomData = (Element) defaultDomEDL.getElementsByTagName(EDLXmlUtils.DATA_E).item(0);
92  				defaultDomEDL.replaceChild(defaultDom.importNode(documentData, true), defaultDomData);
93  			}
94  			if (LOG.isDebugEnabled()) {
95  				LOG.debug("Created default Node from document id " + document.getDocumentId() + " content " + XmlJotter.jotNode(defaultDom));
96  			}
97  		} catch (Exception e) {
98  			throw new WorkflowRuntimeException("Problems creating controller for EDL " + edlAssociation.getEdlName() + " document " + document.getDocumentId(), e);
99  		}
100 		return edlController;
101 	}
102 
103 	private static synchronized void loadStyle(EDLController edlController) throws Exception {
104 		EDocLiteService edlService = getEDLService();
105 		final Templates styleSheet = edlService.getStyleAsTranslet(edlController.getEdocLiteAssociation().getStyle());
106 		edlController.setStyle(styleSheet);
107 	}
108 	
109 	private static synchronized void loadPreProcessors(EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
110 		edlController.setPreProcessors(cloneConfigMap(edlGlobalConfig.getPreProcessors(), edlController.getDefaultDOM()));
111 	}
112 	
113 	private static synchronized void loadPostProcessor(EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
114 		edlController.setPostProcessors(cloneConfigMap(edlGlobalConfig.getPostProcessors(), edlController.getDefaultDOM()));
115 	}
116 	
117 	private static synchronized void loadStateComponents(EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
118 		edlController.setStateComponents(cloneConfigMap(edlGlobalConfig.getStateComponents(), edlController.getDefaultDOM()));
119 	}
120 
121 	private static synchronized void loadConfigProcessors(final EDLController edlController, final EDLGlobalConfig edlGlobalConfig) throws Exception {
122 		EDocLiteAssociation edlAssociation = edlController.getEdocLiteAssociation();
123         // these are classes mapped to the conf element from the edlconfig.
124         Document document = getEDLService().getDefinitionXml(edlAssociation);
125         Element definitionElement = (Element) document.getFirstChild();
126 
127         Map configProcessorMappings = new LinkedHashMap();
128         edlController.setEdlGlobalConfig(edlGlobalConfig);
129         NodeList edlDefinitionNodes = definitionElement.getChildNodes();
130         for (int i = 0; i < edlDefinitionNodes.getLength(); i++) {
131             Node definitionNode = edlDefinitionNodes.item(i);
132             Class configProcessorClass = edlGlobalConfig.getConfigProcessor(definitionNode, edlController.getEdlContext());
133             if (configProcessorClass != null) {
134                 configProcessorMappings.put(definitionNode, configProcessorClass);
135             }
136         }
137         edlController.setConfigProcessors(cloneConfigMap(configProcessorMappings, edlController.getDefaultDOM()));
138 	}
139 	
140 	private static synchronized Map cloneConfigMap(Map configMap, Document defaultDom) {
141 		Map tempConfigProcessors = new LinkedHashMap();
142 		for (Iterator iter = configMap.entrySet().iterator(); iter.hasNext();) {
143 			Map.Entry configProcessorMapping = (Map.Entry) iter.next();
144 			tempConfigProcessors.put(defaultDom.importNode((Node)configProcessorMapping.getKey(), true), configProcessorMapping.getValue());
145 		}
146 		return tempConfigProcessors;
147 	}
148 
149 	private static EDocLiteService getEDLService() {
150 		return EdlServiceLocator.getEDocLiteService();
151 	}
152 
153 	private static Document getDefaultDOM(EDocLiteAssociation edlAssociation) throws Exception {
154 		Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
155 		Element rootElement = dom.createElement("documentContent"); // this is a
156 		// throwback
157 		// to some
158 		// original
159 		// madness
160 		// to get EDL routing over a year ago we need to look into this being
161 		// eliminated.
162 		dom.appendChild(rootElement);
163 		Element edlContentElement = EDLXmlUtils.getEDLContent(dom, true);
164 		EDLXmlUtils.getDataFromEDLDocument(edlContentElement, true);
165 		
166 		// get the data element that was just created ***jitrue***
167 		Element edlData = EDLXmlUtils.getChildElement(edlContentElement, EDLXmlUtils.DATA_E);
168 		// set edlName attribute on data element of default DOM ***jitrue***
169 		edlData.setAttribute("edlName", edlAssociation.getEdlName());
170 		
171 		return dom;
172 	}
173 
174     public static EDLContext getPreEDLContext(EDLController edlController) {
175         EDLContext edlContext = new EDLContext();
176         edlContext.setEdocLiteAssociation(edlController.getEdocLiteAssociation());
177         edlContext.setUserSession(GlobalVariables.getUserSession());
178         edlContext.setXpath(XPathFactory.newInstance().newXPath());
179         return edlContext;
180     }
181 }