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.sql.Timestamp;
022: import java.text.ParseException;
023: import java.util.ArrayList;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Vector;
027:
028: import javax.xml.parsers.ParserConfigurationException;
029:
030: import org.jdom.Attribute;
031: import org.jdom.Document;
032: import org.jdom.Element;
033: import org.jdom.JDOMException;
034: import org.xml.sax.SAXException;
035:
036: import edu.iu.uis.eden.EdenConstants;
037: import edu.iu.uis.eden.KEWServiceLocator;
038: import edu.iu.uis.eden.exception.InvalidXmlException;
039: import edu.iu.uis.eden.routetemplate.RuleAttribute;
040: import edu.iu.uis.eden.routetemplate.RuleBaseValues;
041: import edu.iu.uis.eden.routetemplate.RuleDelegation;
042: import edu.iu.uis.eden.routetemplate.RuleTemplate;
043: import edu.iu.uis.eden.routetemplate.RuleTemplateAttribute;
044: import edu.iu.uis.eden.util.Utilities;
045: import edu.iu.uis.eden.util.XmlHelper;
046:
047: /**
048: * Parses {@link RuleTemplate}s from XML.
049: *
050: * @see RuleTemplate
051: *
052: * @author ewestfal
053: * @author rkirkend
054: */
055: public class RuleTemplateXmlParser implements XmlConstants {
056:
057: private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
058: .getLogger(RuleTemplateXmlParser.class);
059:
060: /**
061: * By default make attributes defined without a <required> element
062: */
063: private static final boolean DEFAULT_ATTRIBUTE_REQUIRED = true;
064:
065: private int templateAttributeCounter = 0;
066:
067: public List parseRuleTemplates(InputStream input)
068: throws IOException, InvalidXmlException {
069:
070: try {
071: Document doc = XmlHelper.trimSAXXml(input);
072: Element root = doc.getRootElement();
073: return parseRuleTemplates(root);
074: } catch (JDOMException e) {
075: throw new InvalidXmlException("Parse error.", e);
076: } catch (SAXException e) {
077: throw new InvalidXmlException("Parse error.", e);
078: } catch (ParserConfigurationException e) {
079: throw new InvalidXmlException("Parse error.", e);
080: }
081: }
082:
083: public List parseRuleTemplates(Element element)
084: throws InvalidXmlException {
085: List ruleTemplates = new ArrayList();
086:
087: // iterate over any RULE_TEMPLATES elements
088: Vector ruleTemplatesElements = XmlHelper.findElements(element,
089: RULE_TEMPLATES);
090: Iterator ruleTemplatesIterator = ruleTemplatesElements
091: .iterator();
092: while (ruleTemplatesIterator.hasNext()) {
093: Element ruleTemplatesElement = (Element) ruleTemplatesIterator
094: .next();
095: Vector ruleTemplateElements = XmlHelper.findElements(
096: ruleTemplatesElement, RULE_TEMPLATE);
097: for (Iterator iterator = ruleTemplateElements.iterator(); iterator
098: .hasNext();) {
099: ruleTemplates.add(parseRuleTemplate((Element) iterator
100: .next(), ruleTemplates));
101: }
102: }
103: return ruleTemplates;
104: }
105:
106: private RuleTemplate parseRuleTemplate(Element element,
107: List ruleTemplates) throws InvalidXmlException {
108: String name = element.getChildText(NAME,
109: RULE_TEMPLATE_NAMESPACE);
110: String description = element.getChildText(DESCRIPTION,
111: RULE_TEMPLATE_NAMESPACE);
112: Attribute allowOverwriteAttrib = element
113: .getAttribute("allowOverwrite");
114: boolean allowOverwrite = false;
115: if (allowOverwriteAttrib != null) {
116: allowOverwrite = Boolean.valueOf(
117: allowOverwriteAttrib.getValue()).booleanValue();
118: }
119: if (Utilities.isEmpty(name)) {
120: throw new InvalidXmlException(
121: "RuleTemplate must have a name");
122: }
123: if (Utilities.isEmpty(description)) {
124: throw new InvalidXmlException(
125: "RuleTemplate must have a description");
126: }
127: RuleTemplate ruleTemplate = KEWServiceLocator
128: .getRuleTemplateService().findByRuleTemplateName(name);
129:
130: if (ruleTemplate == null) {
131: ruleTemplate = new RuleTemplate();
132: } else if (!allowOverwrite) {
133: throw new RuntimeException(
134: "Attempting to overwrite template " + name
135: + " without allowOverwrite set");
136: } else {
137: ruleTemplate.initializeOptions();
138: }
139:
140: ruleTemplate.setName(name);
141: ruleTemplate.setDescription(description);
142: String delegateTemplateName = element.getChildText(
143: DELEGATION_TEMPLATE, RULE_TEMPLATE_NAMESPACE);
144:
145: if (delegateTemplateName != null) {
146: RuleTemplate delegateTemplate = KEWServiceLocator
147: .getRuleTemplateService().findByRuleTemplateName(
148: delegateTemplateName);
149: if (delegateTemplate != null) {
150: ruleTemplate.setDelegationTemplateId(delegateTemplate
151: .getRuleTemplateId());
152: ruleTemplate.setDelegationTemplate(delegateTemplate);
153: } else {
154: boolean delegationTemplateFound = false;
155: for (Iterator ruleTemplateIter = ruleTemplates
156: .iterator(); ruleTemplateIter.hasNext();) {
157: RuleTemplate rt = (RuleTemplate) ruleTemplateIter
158: .next();
159: if (delegateTemplateName.equalsIgnoreCase(rt
160: .getName())) {
161: Long ruleTemplateId = KEWServiceLocator
162: .getRuleTemplateService()
163: .getNextRuleTemplateId();
164: rt.setRuleTemplateId(ruleTemplateId);
165: ruleTemplate
166: .setDelegationTemplateId(ruleTemplateId);
167: ruleTemplate.setDelegationTemplate(rt);
168: delegationTemplateFound = true;
169: break;
170: }
171: }
172: if (!delegationTemplateFound) {
173: throw new InvalidXmlException(
174: "Cannot find delegation template "
175: + delegateTemplateName);
176: }
177: }
178: }
179:
180: Element attributesElement = element.getChild(ATTRIBUTES,
181: RULE_TEMPLATE_NAMESPACE);
182: if (attributesElement != null) {
183: //remove all the associated attributes if we're in overwrite mode.
184: List attributes = parseRuleTemplateAttributes(
185: attributesElement, ruleTemplate);
186: for (Iterator iter = attributes.iterator(); iter.hasNext();) {
187: RuleTemplateAttribute ruleTemplateAttribute = (RuleTemplateAttribute) iter
188: .next();
189: if (!ruleTemplate
190: .containsRuleTemplateAttribute(ruleTemplateAttribute)) {
191: ruleTemplate.getRuleTemplateAttributes().add(
192: ruleTemplateAttribute);
193: }
194: }
195: }
196:
197: KEWServiceLocator.getRuleTemplateService().save(ruleTemplate);
198:
199: Element defaultsElement = element.getChild(RULE_DEFAULTS,
200: RULE_TEMPLATE_NAMESPACE);
201: if (defaultsElement != null) {
202: parseDefaults(defaultsElement, ruleTemplate);
203: // save again so that the rule template options get persisted
204: KEWServiceLocator.getRuleTemplateService().save(
205: ruleTemplate);
206: }
207: return ruleTemplate;
208: }
209:
210: private List parseRuleTemplateAttributes(Element element,
211: RuleTemplate ruleTemplate) throws InvalidXmlException {
212: List ruleTemplateAttributes = new ArrayList();
213: Vector attributeElements = XmlHelper.findElements(element,
214: ATTRIBUTE);
215: for (Iterator iterator = attributeElements.iterator(); iterator
216: .hasNext();) {
217: ruleTemplateAttributes.add(parseRuleTemplateAttribute(
218: (Element) iterator.next(), ruleTemplate));
219: }
220: return ruleTemplateAttributes;
221: }
222:
223: private RuleTemplateAttribute parseRuleTemplateAttribute(
224: Element element, RuleTemplate ruleTemplate)
225: throws InvalidXmlException {
226: String attributeName = element.getChildText(NAME,
227: RULE_TEMPLATE_NAMESPACE);
228: String requiredValue = element.getChildText(REQUIRED,
229: RULE_TEMPLATE_NAMESPACE);
230: if (Utilities.isEmpty(attributeName)) {
231: throw new InvalidXmlException(
232: "Attribute name must be non-empty");
233: }
234: boolean required = DEFAULT_ATTRIBUTE_REQUIRED;
235: if (requiredValue != null) {
236: required = Boolean.parseBoolean(requiredValue);
237: }
238: RuleAttribute ruleAttribute = KEWServiceLocator
239: .getRuleAttributeService().findByName(attributeName);
240: if (ruleAttribute == null) {
241: throw new InvalidXmlException(
242: "Could not locate rule attribute for name '"
243: + attributeName + "'");
244: }
245: RuleTemplateAttribute templateAttribute = new RuleTemplateAttribute();
246: templateAttribute.setRuleAttribute(ruleAttribute);
247: templateAttribute.setRuleAttributeId(ruleAttribute
248: .getRuleAttributeId());
249: templateAttribute.setRuleTemplate(ruleTemplate);
250: templateAttribute.setRequired(Boolean.valueOf(required));
251: templateAttribute.setDisplayOrder(new Integer(
252: templateAttributeCounter++));
253: return templateAttribute;
254: }
255:
256: /*
257: <element name="ruleInstructions" type="c:LongStringType"/>
258: <element name="description" type="c:LongStringType"/>
259: <element name="fromDate" type="c:ShortStringType" minOccurs="0"/>
260: <element name="toDate" type="c:ShortStringType" minOccurs="0"/>
261: <element name="ignorePrevious" type="boolean"/>
262: <element name="active" type="boolean"/>
263: <element name="defaultActionRequested" type="c:ShortStringType"/>
264: <element name="supportsComplete" type="boolean" default="true"/>
265: <element name="supportsApprove" type="boolean" default="true"/>
266: <element name="supportsAcknowledge" type="boolean" default="true"/>
267: <element name="supportsFYI" type="boolean" default="true"/>
268: */
269: /**
270: * Parses the defaults for this RuleTemplate.
271: */
272: private void parseDefaults(Element defaultsElement,
273: RuleTemplate ruleTemplate) throws InvalidXmlException {
274: // delete any existing defaults, we're going to replace them
275: if (ruleTemplate.getRuleTemplateId() != null) {
276: RuleBaseValues ruleDefaults = KEWServiceLocator
277: .getRuleService().findDefaultRuleByRuleTemplateId(
278: ruleTemplate.getRuleTemplateId());
279: if (ruleDefaults != null) {
280: List ruleDelegationDefaults = KEWServiceLocator
281: .getRuleDelegationService()
282: .findByDelegateRuleId(
283: ruleDefaults.getRuleBaseValuesId());
284: KEWServiceLocator.getRuleService().delete(
285: ruleDefaults.getRuleBaseValuesId());
286: for (Iterator iterator = ruleDelegationDefaults
287: .iterator(); iterator.hasNext();) {
288: RuleDelegation ruleDelegation = (RuleDelegation) iterator
289: .next();
290: KEWServiceLocator.getRuleDelegationService()
291: .delete(
292: ruleDelegation
293: .getRuleDelegationId());
294: }
295: }
296: if (ruleTemplate.getAcknowledge().getRuleTemplateOptionId() != null) {
297: KEWServiceLocator.getRuleTemplateService()
298: .deleteRuleTemplateOption(
299: ruleTemplate.getAcknowledge()
300: .getRuleTemplateOptionId());
301: }
302: if (ruleTemplate.getApprove().getRuleTemplateOptionId() != null) {
303: KEWServiceLocator.getRuleTemplateService()
304: .deleteRuleTemplateOption(
305: ruleTemplate.getApprove()
306: .getRuleTemplateOptionId());
307: }
308: if (ruleTemplate.getComplete().getRuleTemplateOptionId() != null) {
309: KEWServiceLocator.getRuleTemplateService()
310: .deleteRuleTemplateOption(
311: ruleTemplate.getComplete()
312: .getRuleTemplateOptionId());
313: }
314: if (ruleTemplate.getFyi().getRuleTemplateOptionId() != null) {
315: KEWServiceLocator.getRuleTemplateService()
316: .deleteRuleTemplateOption(
317: ruleTemplate.getFyi()
318: .getRuleTemplateOptionId());
319: }
320: if (ruleTemplate.getDefaultActionRequestValue()
321: .getRuleTemplateOptionId() != null) {
322: KEWServiceLocator.getRuleTemplateService()
323: .deleteRuleTemplateOption(
324: ruleTemplate
325: .getDefaultActionRequestValue()
326: .getRuleTemplateOptionId());
327: }
328:
329: }
330: // now create the defaults
331: String delegationType = defaultsElement.getChildText(
332: DELEGATION_TYPE, RULE_TEMPLATE_NAMESPACE);
333: boolean isDelegation = !Utilities.isEmpty(delegationType);
334: if (isDelegation
335: && !EdenConstants.DELEGATION_PRIMARY
336: .equals(delegationType)
337: && !EdenConstants.DELEGATION_SECONDARY
338: .equals(delegationType)) {
339: throw new InvalidXmlException("Invalid delegation type '"
340: + delegationType + "'." + " Expected one of: "
341: + EdenConstants.DELEGATION_PRIMARY + ","
342: + EdenConstants.DELEGATION_SECONDARY);
343: }
344: RuleBaseValues ruleDefaults = new RuleBaseValues();
345:
346: // set up the default values
347: ruleDefaults.setRuleTemplate(ruleTemplate);
348: ruleDefaults.setDocTypeName("dummyDocumentType");
349: ruleDefaults.setTemplateRuleInd(Boolean.TRUE);
350: ruleDefaults.setCurrentInd(Boolean.TRUE);
351: ruleDefaults.setVersionNbr(new Integer(0));
352: try {
353: ruleDefaults.setDeactivationDate(new Timestamp(
354: EdenConstants.getDefaultDateFormat().parse(
355: "01/01/2100").getTime()));
356: if (ruleDefaults.getActivationDate() == null) {
357: ruleDefaults.setActivationDate(new Timestamp(System
358: .currentTimeMillis()));
359: }
360: } catch (ParseException e) {
361: }
362:
363: String ruleInstructions = defaultsElement.getChildText(
364: RULE_INSTRUCTIONS, RULE_TEMPLATE_NAMESPACE);
365: String description = defaultsElement.getChildText(DESCRIPTION,
366: RULE_TEMPLATE_NAMESPACE);
367: String fromDate = defaultsElement.getChildText(FROM_DATE,
368: RULE_TEMPLATE_NAMESPACE);
369: String toDate = defaultsElement.getChildText(TO_DATE,
370: RULE_TEMPLATE_NAMESPACE);
371: Boolean ignorePrevious = Boolean
372: .valueOf(defaultsElement.getChildText(IGNORE_PREVIOUS,
373: RULE_TEMPLATE_NAMESPACE));
374: Boolean active = Boolean.valueOf(defaultsElement.getChildText(
375: ACTIVE, RULE_TEMPLATE_NAMESPACE));
376: String defaultActionRequested = defaultsElement.getChildText(
377: DEFAULT_ACTION_REQUESTED, RULE_TEMPLATE_NAMESPACE);
378: Boolean supportsComplete = Boolean.valueOf(defaultsElement
379: .getChildText(SUPPORTS_COMPLETE,
380: RULE_TEMPLATE_NAMESPACE));
381: Boolean supportsApprove = Boolean
382: .valueOf(defaultsElement.getChildText(SUPPORTS_APPROVE,
383: RULE_TEMPLATE_NAMESPACE));
384: Boolean supportsAcknowledge = Boolean.valueOf(defaultsElement
385: .getChildText(SUPPORTS_ACKNOWLEDGE,
386: RULE_TEMPLATE_NAMESPACE));
387: Boolean supportsFYI = Boolean.valueOf(defaultsElement
388: .getChildText(SUPPORTS_FYI, RULE_TEMPLATE_NAMESPACE));
389:
390: RuleDelegation ruleDelegationDefaults = null;
391: if (isDelegation) {
392: ruleDelegationDefaults = new RuleDelegation();
393: ruleDelegationDefaults
394: .setDelegationRuleBaseValues(ruleDefaults);
395: ruleDelegationDefaults.setDelegationType(delegationType);
396: ruleDelegationDefaults
397: .setRuleResponsibilityId(new Long(-1));
398: } else {
399: ruleTemplate.getDefaultActionRequestValue().setValue(
400: defaultActionRequested);
401: ruleTemplate.getComplete().setValue(
402: supportsComplete.toString());
403: ruleTemplate.getApprove().setValue(
404: supportsApprove.toString());
405: ruleTemplate.getAcknowledge().setValue(
406: supportsAcknowledge.toString());
407: ruleTemplate.getFyi().setValue(supportsFYI.toString());
408: }
409: ruleTemplate.getInstructions().setValue(ruleInstructions);
410: ruleDefaults.setDescription(description);
411: if (Utilities.isEmpty(fromDate)) {
412: ruleDefaults.setFromDate(new Timestamp(System
413: .currentTimeMillis()));
414: } else {
415: ruleDefaults.setFromDateString(fromDate);
416: }
417: if (Utilities.isEmpty(toDate)) {
418: try {
419: ruleDefaults.setToDate(new Timestamp(EdenConstants
420: .getDefaultDateFormat().parse("01/01/2100")
421: .getTime()));
422: } catch (ParseException e) {
423: }
424: } else {
425: ruleDefaults.setToDateString(toDate);
426: }
427: ruleDefaults.setIgnorePrevious(ignorePrevious);
428: ruleDefaults.setActiveInd(active);
429:
430: KEWServiceLocator.getRuleTemplateService().save(
431: ruleDelegationDefaults, ruleDefaults);
432: }
433:
434: }
|