View Javadoc

1   /**
2    * Copyright 2005-2011 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.w3c.dom.Document;
27  import org.w3c.dom.Element;
28  import org.w3c.dom.Node;
29  import org.w3c.dom.NodeList;
30  
31  import javax.xml.parsers.DocumentBuilderFactory;
32  import javax.xml.transform.Templates;
33  import java.util.Iterator;
34  import java.util.LinkedHashMap;
35  import java.util.Map;
36  
37  
38  /**
39   * Creates EDL controllers.  The parsed config is a definition name related to
40   * a Map containing config element and their associated class.
41   * 
42   * @author Kuali Rice Team (rice.collab@kuali.org)
43   *
44   */
45  public final class EDLControllerFactory {
46  
47      private EDLControllerFactory() {
48          throw new UnsupportedOperationException("do not call");
49      }
50  
51  	private static final Logger LOG = Logger.getLogger(EDLControllerFactory.class);
52  
53  	public static EDLController createEDLController(EDocLiteAssociation edlAssociation, EDLGlobalConfig edlGlobalConfig) {
54          EDLController edlController = new EDLController();
55  		edlController.setEdocLiteAssociation(edlAssociation);
56  
57  		try {
58  			edlController.setEdlGlobalConfig(edlGlobalConfig);
59  			edlController.setDefaultDOM(getDefaultDOM(edlAssociation));
60  			loadConfigProcessors(edlController, edlGlobalConfig);
61  			loadPreProcessors(edlController, edlGlobalConfig);
62  			loadPostProcessor(edlController, edlGlobalConfig);
63  			loadStateComponents(edlController, edlGlobalConfig);
64  			loadStyle(edlController);
65  			
66  		} catch (Exception e) {
67              String edl = null;
68              if (edlAssociation != null) {
69                  edl = edlAssociation.getEdlName();
70              }
71              String message = "Error creating controller for EDL" + (edl == null ? "" : ": " + edl);
72              LOG.error(message, e);
73  			throw new WorkflowRuntimeException("Problems creating controller for EDL: " + edl, e);
74  		}
75  
76  		return edlController;
77  	}
78  
79  	public static EDLController createEDLController(EDocLiteAssociation edlAssociation, EDLGlobalConfig edlGlobalConfig, DocumentRouteHeaderValue document) {
80  		EDLController edlController = createEDLController(edlAssociation, edlGlobalConfig);
81  		try {
82  			Document defaultDom = edlController.getDefaultDOM();
83  			Document documentDom = XmlHelper.readXml(document.getDocContent());
84  			// get the data node and import it into our default DOM
85  			Element documentData = (Element) documentDom.getElementsByTagName(EDLXmlUtils.DATA_E).item(0);
86  			if (documentData != null) {
87  				Element defaultDomEDL = EDLXmlUtils.getEDLContent(defaultDom, false);
88  				Element defaultDomData = (Element) defaultDomEDL.getElementsByTagName(EDLXmlUtils.DATA_E).item(0);
89  				defaultDomEDL.replaceChild(defaultDom.importNode(documentData, true), defaultDomData);
90  			}
91  			if (LOG.isDebugEnabled()) {
92  				LOG.debug("Created default Node from document id " + document.getDocumentId() + " content " + XmlJotter.jotNode(defaultDom));
93  			}
94  		} catch (Exception e) {
95  			throw new WorkflowRuntimeException("Problems creating controller for EDL " + edlAssociation.getEdlName() + " document " + document.getDocumentId(), e);
96  		}
97  		return edlController;
98  	}
99  
100 	private static synchronized void loadStyle(EDLController edlController) throws Exception {
101 		EDocLiteService edlService = getEDLService();
102 		final Templates styleSheet = edlService.getStyleAsTranslet(edlController.getEdocLiteAssociation().getStyle());
103 		edlController.setStyle(styleSheet);
104 	}
105 	
106 	private static synchronized void loadPreProcessors(EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
107 		edlController.setPreProcessors(cloneConfigMap(edlGlobalConfig.getPreProcessors(), edlController.getDefaultDOM()));
108 	}
109 	
110 	private static synchronized void loadPostProcessor(EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
111 		edlController.setPostProcessors(cloneConfigMap(edlGlobalConfig.getPostProcessors(), edlController.getDefaultDOM()));
112 	}
113 	
114 	private static synchronized void loadStateComponents(EDLController edlController, EDLGlobalConfig edlGlobalConfig) {
115 		edlController.setStateComponents(cloneConfigMap(edlGlobalConfig.getStateComponents(), edlController.getDefaultDOM()));
116 	}
117 
118 	private static synchronized void loadConfigProcessors(final EDLController edlController, final EDLGlobalConfig edlGlobalConfig) throws Exception {
119 		EDocLiteAssociation edlAssociation = edlController.getEdocLiteAssociation();
120         // these are classes mapped to the conf element from the edlconfig.
121         Document document = getEDLService().getDefinitionXml(edlAssociation);
122         Element definitionElement = (Element) document.getFirstChild();
123 
124         Map configProcessorMappings = new LinkedHashMap();
125         edlController.setEdlGlobalConfig(edlGlobalConfig);
126         NodeList edlDefinitionNodes = definitionElement.getChildNodes();
127         for (int i = 0; i < edlDefinitionNodes.getLength(); i++) {
128             Node definitionNode = edlDefinitionNodes.item(i);
129             Class configProcessorClass = edlGlobalConfig.getConfigProcessor(definitionNode);
130             if (configProcessorClass != null) {
131                 configProcessorMappings.put(definitionNode, configProcessorClass);
132             }
133         }
134         edlController.setConfigProcessors(cloneConfigMap(configProcessorMappings, edlController.getDefaultDOM()));
135 	}
136 	
137 	private static synchronized Map cloneConfigMap(Map configMap, Document defaultDom) {
138 		Map tempConfigProcessors = new LinkedHashMap();
139 		for (Iterator iter = configMap.entrySet().iterator(); iter.hasNext();) {
140 			Map.Entry configProcessorMapping = (Map.Entry) iter.next();
141 			tempConfigProcessors.put(defaultDom.importNode((Node)configProcessorMapping.getKey(), true), configProcessorMapping.getValue());
142 		}
143 		return tempConfigProcessors;
144 	}
145 
146 	private static EDocLiteService getEDLService() {
147 		return EdlServiceLocator.getEDocLiteService();
148 	}
149 
150 	private static Document getDefaultDOM(EDocLiteAssociation edlAssociation) throws Exception {
151 		Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
152 		Element rootElement = dom.createElement("documentContent"); // this is a
153 		// throwback
154 		// to some
155 		// original
156 		// madness
157 		// to get EDL routing over a year ago we need to look into this being
158 		// eliminated.
159 		dom.appendChild(rootElement);
160 		Element edlContentElement = EDLXmlUtils.getEDLContent(dom, true);
161 		EDLXmlUtils.getDataFromEDLDocument(edlContentElement, true);
162 		
163 		// get the data element that was just created ***jitrue***
164 		Element edlData = EDLXmlUtils.getChildElement(edlContentElement, EDLXmlUtils.DATA_E);
165 		// set edlName attribute on data element of default DOM ***jitrue***
166 		edlData.setAttribute("edlName", edlAssociation.getEdlName());
167 		
168 		return dom;
169 	}
170 }