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.xml;
018:
019: import java.io.IOException;
020: import java.io.InputStream;
021: import java.util.ArrayList;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026:
027: import javax.xml.parsers.DocumentBuilderFactory;
028: import javax.xml.parsers.FactoryConfigurationError;
029: import javax.xml.parsers.ParserConfigurationException;
030:
031: import org.apache.commons.lang.StringUtils;
032: import org.apache.log4j.Logger;
033: import org.jdom.Document;
034: import org.jdom.Element;
035: import org.jdom.JDOMException;
036: import org.jdom.input.DOMBuilder;
037: import org.kuali.workflow.workgroup.BaseWorkgroupExtension;
038: import org.kuali.workflow.workgroup.BaseWorkgroupExtensionData;
039: import org.kuali.workflow.workgroup.WorkgroupType;
040: import org.kuali.workflow.workgroup.WorkgroupTypeAttribute;
041: import org.xml.sax.SAXException;
042:
043: import edu.iu.uis.eden.EdenConstants;
044: import edu.iu.uis.eden.KEWServiceLocator;
045: import edu.iu.uis.eden.exception.InvalidXmlException;
046: import edu.iu.uis.eden.exception.WorkflowRuntimeException;
047: import edu.iu.uis.eden.routetemplate.RuleAttribute;
048: import edu.iu.uis.eden.user.AuthenticationUserId;
049: import edu.iu.uis.eden.user.EmplId;
050: import edu.iu.uis.eden.user.UuId;
051: import edu.iu.uis.eden.user.WorkflowUser;
052: import edu.iu.uis.eden.user.WorkflowUserId;
053: import edu.iu.uis.eden.workgroup.BaseWorkgroup;
054: import edu.iu.uis.eden.workgroup.BaseWorkgroupMember;
055: import edu.iu.uis.eden.workgroup.GroupNameId;
056: import edu.iu.uis.eden.workgroup.Workgroup;
057: import edu.iu.uis.eden.workgroup.WorkgroupService;
058:
059: /**
060: * Parses {@link Workgroup}s from XML.
061: *
062: * @see Workgroup
063: *
064: * @author rkirkend
065: */
066: public class WorkgroupXmlHandler implements XmlConstants,
067: WorkgroupXmlConstants {
068:
069: private static final Logger LOG = Logger
070: .getLogger(WorkgroupXmlHandler.class);
071:
072: private List workgroups = new ArrayList();
073:
074: public List parseWorkgroupEntries(InputStream file)
075: throws JDOMException, SAXException, IOException,
076: ParserConfigurationException, FactoryConfigurationError {
077: org.w3c.dom.Document w3cDocument = DocumentBuilderFactory
078: .newInstance().newDocumentBuilder().parse(file);
079:
080: Document document = new DOMBuilder().build(w3cDocument);
081: Element root = document.getRootElement();
082:
083: Map<String, BaseWorkgroup> workgroupMap = new HashMap<String, BaseWorkgroup>();
084:
085: try {
086: for (Iterator workgroupsIt = root.getChildren(WORKGROUPS,
087: WORKGROUP_NAMESPACE).iterator(); workgroupsIt
088: .hasNext();) {
089: Element workgroupsElement = (Element) workgroupsIt
090: .next();
091: for (Iterator workgroupIter = workgroupsElement
092: .getChildren(WORKGROUP, WORKGROUP_NAMESPACE)
093: .iterator(); workgroupIter.hasNext();) {
094: Element workgroupElement = (Element) workgroupIter
095: .next();
096: List members = new ArrayList();
097:
098: BaseWorkgroup workgroup = (BaseWorkgroup) getWorkgroupService()
099: .getBlankWorkgroup();
100: workgroup.setDocumentId(new Long(-1));
101: workgroup.setActiveInd(Boolean.TRUE);
102: String workgroupName = workgroupElement
103: .getChildTextTrim(WORKGROUP_NAME,
104: WORKGROUP_NAMESPACE);
105: if (StringUtils.isEmpty(workgroupName)) {
106: throw new RuntimeException(WORKGROUP_NAME
107: + " must be non-empty.");
108: }
109: checkForDuplicateWorkgroup(workgroupName);
110: workgroup.setGroupNameId(new GroupNameId(
111: workgroupName));
112: workgroup.setDescription(workgroupElement
113: .getChildTextTrim(DESCRIPTION,
114: WORKGROUP_NAMESPACE));
115: String type = workgroupElement.getChildTextTrim(
116: WORKGROUP_TYPE, WORKGROUP_NAMESPACE);
117: WorkgroupType workgroupType = null;
118: // if there are not using the default workgroup type
119: if (!(StringUtils.isEmpty(type) || type
120: .equals(EdenConstants.LEGACY_DEFAULT_WORKGROUP_TYPE))) {
121: workgroup.setWorkgroupType(type);
122: workgroupType = KEWServiceLocator
123: .getWorkgroupTypeService().findByName(
124: type);
125: if (workgroupType == null) {
126: throw new InvalidXmlException(
127: "Could not locate Workgroup Type with the given name '"
128: + type + "'");
129: }
130: }
131: workgroup.setCurrentInd(Boolean.TRUE);
132: workgroup.setActiveInd(Boolean.TRUE);
133: String activeInd = workgroupElement
134: .getChildTextTrim(ACTIVE_IND,
135: WORKGROUP_NAMESPACE);
136: if (activeInd != null) {
137: workgroup.setActiveInd(new Boolean(activeInd));
138: }
139:
140: Element extsElement = workgroupElement.getChild(
141: EXTENSIONS, WORKGROUP_NAMESPACE);
142: if (extsElement != null) {
143: if (workgroupType == null) {
144: throw new InvalidXmlException(
145: "Extensions were defined on a workgorup without a proper Workgroup Type defined.");
146: }
147: for (Iterator extsIter = extsElement
148: .getChildren().iterator(); extsIter
149: .hasNext();) {
150: BaseWorkgroupExtension workgroupExtension = new BaseWorkgroupExtension();
151: Element extElement = (Element) extsIter
152: .next();
153: String attributeName = extElement
154: .getAttributeValue(ATTRIBUTE);
155: if (StringUtils.isBlank(attributeName)) {
156: throw new InvalidXmlException(
157: "An attribute was not defined on the workgroup extension for workgroup '"
158: + workgroupName + "'");
159: }
160: RuleAttribute ruleAttribute = KEWServiceLocator
161: .getRuleAttributeService()
162: .findByName(attributeName);
163: if (ruleAttribute == null) {
164: throw new InvalidXmlException(
165: "Could not find attribute with the given name '"
166: + attributeName + "'");
167: }
168: boolean attributeFound = false;
169: for (WorkgroupTypeAttribute workgroupTypeAttribute : workgroupType
170: .getActiveAttributes()) {
171: if (workgroupTypeAttribute
172: .getAttribute()
173: .getRuleAttributeId()
174: .equals(
175: ruleAttribute
176: .getRuleAttributeId())) {
177: workgroupExtension
178: .setWorkgroupTypeAttribute(workgroupTypeAttribute);
179: attributeFound = true;
180: break;
181: }
182: }
183: if (!attributeFound) {
184: throw new InvalidXmlException(
185: "Attribute '"
186: + attributeName
187: + "' not found on Workgroup Type '"
188: + workgroupType
189: .getName()
190: + "'");
191: }
192: workgroupExtension.setWorkgroup(workgroup);
193:
194: List dataElements = extElement.getChildren(
195: DATA, WORKGROUP_NAMESPACE);
196: if (dataElements == null
197: || dataElements.isEmpty()) {
198: throw new InvalidXmlException(
199: "No extension data defined for extension '"
200: + attributeName
201: + "' on workgroup '"
202: + workgroupName + "'");
203: }
204: for (Iterator dataIt = dataElements
205: .iterator(); dataIt.hasNext();) {
206: Element dataElement = (Element) dataIt
207: .next();
208: String key = dataElement
209: .getAttributeValue(KEY);
210: if (StringUtils.isBlank(key)) {
211: throw new InvalidXmlException(
212: "Found an empty or non-existent key on extension data for workgroup '"
213: + workgroupName
214: + "'");
215: }
216: String value = dataElement.getValue();
217: BaseWorkgroupExtensionData data = new BaseWorkgroupExtensionData();
218: data.setKey(key);
219: data.setValue(value);
220: data
221: .setWorkgroupExtension(workgroupExtension);
222: workgroupExtension.getData().add(data);
223: }
224: workgroup.getExtensions().add(
225: workgroupExtension);
226: }
227: }
228:
229: for (Iterator memberIter = workgroupElement
230: .getChild(MEMBERS, WORKGROUP_NAMESPACE)
231: .getChildren().iterator(); memberIter
232: .hasNext();) {
233: Element memberElement = (Element) memberIter
234: .next();
235: BaseWorkgroupMember member = new BaseWorkgroupMember();
236: WorkflowUser workflowUser = null;
237: Workgroup nestedWorkgroup = null;
238: if (memberElement.getName().equals(WORKFLOW_ID)) {
239: workflowUser = KEWServiceLocator
240: .getUserService()
241: .getWorkflowUser(
242: new WorkflowUserId(
243: memberElement
244: .getText()));
245: } else if (memberElement.getName().equals(
246: AUTHENTICATION_ID)) {
247: workflowUser = KEWServiceLocator
248: .getUserService()
249: .getWorkflowUser(
250: new AuthenticationUserId(
251: memberElement
252: .getText()));
253: } else if (memberElement.getName()
254: .equals(UU_ID)) {
255: workflowUser = KEWServiceLocator
256: .getUserService().getWorkflowUser(
257: new UuId(memberElement
258: .getText()));
259: } else if (memberElement.getName().equals(
260: EMPL_ID)) {
261: workflowUser = KEWServiceLocator
262: .getUserService().getWorkflowUser(
263: new EmplId(memberElement
264: .getText()));
265: } else if (memberElement.getName().equals(
266: WORKGROUP_NAME)) {
267: if (workgroupMap.containsKey(memberElement
268: .getText())) {
269: nestedWorkgroup = workgroupMap
270: .get(memberElement.getText());
271: } else {
272: nestedWorkgroup = KEWServiceLocator
273: .getWorkgroupService()
274: .getWorkgroup(
275: new GroupNameId(
276: memberElement
277: .getText()));
278: }
279: } else {
280: LOG.error("Unknown member element: "
281: + memberElement.getName());
282: }
283: if (workflowUser != null) {
284: member.setWorkflowId(workflowUser
285: .getWorkflowId());
286: member
287: .setMemberType(EdenConstants.ACTION_REQUEST_USER_RECIPIENT_CD);
288: } else if (nestedWorkgroup != null) {
289: member.setWorkflowId(nestedWorkgroup
290: .getWorkflowGroupId().getGroupId()
291: .toString());
292: member
293: .setMemberType(EdenConstants.ACTION_REQUEST_WORKGROUP_RECIPIENT_CD);
294: } else {
295: throw new Exception(
296: "A workflow user or nested workgroup cannot be found for "
297: + memberElement.getName()
298: + "="
299: + memberElement.getText()
300: + " on Workgroup "
301: + workgroup
302: .getWorkgroupName());
303: }
304: workgroup.getMembers().add(workflowUser);
305: member.setWorkgroup(workgroup);
306: member
307: .setWorkgroupVersionNumber(new Integer(
308: 0));
309: members.add(member);
310: }
311: workgroup.setWorkgroupMembers(members);
312: // need to save now in case this group is used as a nested group in any of the others in this xml document
313: KEWServiceLocator.getWorkgroupService().save(
314: workgroup);
315: workgroupMap.put(workgroup.getGroupNameId()
316: .getNameId(), workgroup);
317: workgroups.add(workgroup);
318: }
319: }
320: } catch (Exception e) {
321: LOG.error("Error parsing file", e);
322: throw new RuntimeException(
323: "Error parsing workgroup xml data set.", e);
324: }
325:
326: return workgroups;
327: }
328:
329: private void checkForDuplicateWorkgroup(String workgroupName) {
330: Workgroup workgroup = KEWServiceLocator.getWorkgroupService()
331: .getWorkgroup(new GroupNameId(workgroupName));
332: if (workgroup != null) {
333: throw new WorkflowRuntimeException(
334: "Workgroup '"
335: + workgroupName
336: + "' already exists! Cannot import over an existing workgroup.");
337: }
338: }
339:
340: public List getWorkgroups() {
341: return workgroups;
342: }
343:
344: public void setWorkgroups(List workgroups) {
345: this .workgroups = workgroups;
346: }
347:
348: private WorkgroupService getWorkgroupService() {
349: return KEWServiceLocator.getWorkgroupService();
350: }
351:
352: }
|