001 /*
002 * Copyright 2005-2007 The Kuali Foundation
003 *
004 *
005 * Licensed under the Educational Community License, Version 2.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/ecl2.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 org.kuali.rice.kew.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.apache.commons.lang.BooleanUtils;
031 import org.apache.commons.lang.StringUtils;
032 import org.jdom.Attribute;
033 import org.jdom.Document;
034 import org.jdom.Element;
035 import org.jdom.JDOMException;
036 import org.kuali.rice.core.util.RiceConstants;
037 import org.kuali.rice.kew.exception.InvalidXmlException;
038 import org.kuali.rice.kew.rule.RuleBaseValues;
039 import org.kuali.rice.kew.rule.RuleDelegation;
040 import org.kuali.rice.kew.rule.RuleTemplateOption;
041 import org.kuali.rice.kew.rule.bo.RuleAttribute;
042 import org.kuali.rice.kew.rule.bo.RuleTemplate;
043 import org.kuali.rice.kew.rule.bo.RuleTemplateAttribute;
044 import org.kuali.rice.kew.service.KEWServiceLocator;
045 import org.kuali.rice.kew.util.KEWConstants;
046 import org.kuali.rice.kew.util.Utilities;
047 import org.kuali.rice.kew.util.XmlHelper;
048 import org.xml.sax.SAXException;
049
050
051 /**
052 * Parses {@link RuleTemplate}s from XML.
053 *
054 * @see RuleTemplate
055 *
056 * @author Kuali Rice Team (rice.collab@kuali.org)
057 */
058 public class RuleTemplateXmlParser implements XmlConstants {
059
060 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RuleTemplateXmlParser.class);
061
062 /**
063 * By default make attributes defined without a <required> element
064 */
065 private static final boolean DEFAULT_ATTRIBUTE_REQUIRED = true;
066 private static final boolean DEFAULT_ATTRIBUTE_ACTIVE = true;
067
068 /**
069 * A dummy document type used in the default rule
070 */
071 private static final String DUMMY_DOCUMENT_TYPE = "dummyDocumentType";
072
073 /**
074 * Used to set the display order of attributes encountered in parsing runs during the lifetime of this object
075 */
076 private int templateAttributeCounter = 0;
077
078 public List<RuleTemplate> parseRuleTemplates(InputStream input) throws IOException, InvalidXmlException {
079
080 try {
081 Document doc = XmlHelper.trimSAXXml(input);
082 Element root = doc.getRootElement();
083 return parseRuleTemplates(root);
084 } catch (JDOMException e) {
085 throw new InvalidXmlException("Parse error.", e);
086 } catch (SAXException e) {
087 throw new InvalidXmlException("Parse error.", e);
088 } catch (ParserConfigurationException e) {
089 throw new InvalidXmlException("Parse error.", e);
090 }
091 }
092
093 public List<RuleTemplate> parseRuleTemplates(Element element) throws InvalidXmlException {
094 List<RuleTemplate> ruleTemplates = new ArrayList<RuleTemplate>();
095
096 // iterate over any RULE_TEMPLATES elements
097 Vector ruleTemplatesElements = XmlHelper.findElements(element, RULE_TEMPLATES);
098 Iterator ruleTemplatesIterator = ruleTemplatesElements.iterator();
099 while (ruleTemplatesIterator.hasNext()) {
100 Element ruleTemplatesElement = (Element) ruleTemplatesIterator.next();
101 Vector ruleTemplateElements = XmlHelper.findElements(ruleTemplatesElement, RULE_TEMPLATE);
102 for (Iterator iterator = ruleTemplateElements.iterator(); iterator.hasNext();) {
103 ruleTemplates.add(parseRuleTemplate((Element) iterator.next(), ruleTemplates));
104 }
105 }
106 return ruleTemplates;
107 }
108
109 private RuleTemplate parseRuleTemplate(Element element, List<RuleTemplate> ruleTemplates) throws InvalidXmlException {
110 String name = element.getChildText(NAME, RULE_TEMPLATE_NAMESPACE);
111 String description = element.getChildText(DESCRIPTION, RULE_TEMPLATE_NAMESPACE);
112 Attribute allowOverwriteAttrib = element.getAttribute("allowOverwrite");
113
114 boolean allowOverwrite = false;
115 if (allowOverwriteAttrib != null) {
116 allowOverwrite = Boolean.valueOf(allowOverwriteAttrib.getValue()).booleanValue();
117 }
118 if (Utilities.isEmpty(name)) {
119 throw new InvalidXmlException("RuleTemplate must have a name");
120 }
121 if (Utilities.isEmpty(description)) {
122 throw new InvalidXmlException("RuleTemplate must have a description");
123 }
124
125 // look up the rule template by name first
126 RuleTemplate ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(name);
127
128 if (ruleTemplate == null) {
129 // if it does not exist create a new one
130 ruleTemplate = new RuleTemplate();
131 } else {
132 // if it does exist, update it, only if allowOverwrite is set
133 if (!allowOverwrite) {
134 throw new RuntimeException("Attempting to overwrite template " + name + " without allowOverwrite set");
135 }
136
137 // the name should be equal if one was actually found
138 assert(name.equals(ruleTemplate.getName())) : "Existing template definition name does not match incoming definition name";
139 }
140
141 // overwrite simple properties
142 ruleTemplate.setName(name);
143 ruleTemplate.setDescription(description);
144
145 // update the delegation template
146 updateDelegationTemplate(element, ruleTemplate, ruleTemplates);
147
148 // update the attribute relationships
149 updateRuleTemplateAttributes(element, ruleTemplate);
150
151 // save the rule template first so that the default/template rule that is generated
152 // in the process of setting defaults is associated properly with this rule template
153 KEWServiceLocator.getRuleTemplateService().save(ruleTemplate);
154
155 // update the default options
156 updateRuleTemplateDefaultOptions(element, ruleTemplate);
157
158 KEWServiceLocator.getRuleTemplateService().save(ruleTemplate);
159
160 return ruleTemplate;
161 }
162
163 /**
164 * Updates the rule template default options. Updates any existing options, removes any omitted ones.
165 * @param ruleTemplateElement the rule template XML element
166 * @param updatedRuleTemplate the RuleTemplate being updated
167 * @throws InvalidXmlException
168 */
169 /*
170 <element name="description" type="c:LongStringType"/>
171 <element name="fromDate" type="c:ShortStringType" minOccurs="0"/>
172 <element name="toDate" type="c:ShortStringType" minOccurs="0"/>
173 <element name="forceAction" type="boolean"/>
174 <element name="active" type="boolean"/>
175 <element name="defaultActionRequested" type="c:ShortStringType"/>
176 <element name="supportsComplete" type="boolean" default="true"/>
177 <element name="supportsApprove" type="boolean" default="true"/>
178 <element name="supportsAcknowledge" type="boolean" default="true"/>
179 <element name="supportsFYI" type="boolean" default="true"/>
180 */
181 protected void updateRuleTemplateDefaultOptions(Element ruleTemplateElement, RuleTemplate updatedRuleTemplate) throws InvalidXmlException {
182 Element defaultsElement = ruleTemplateElement.getChild(RULE_DEFAULTS, RULE_TEMPLATE_NAMESPACE);
183
184 // update the rule defaults; this yields whether or not this is a delegation rule template
185 boolean isDelegation = updateRuleDefaults(defaultsElement, updatedRuleTemplate);
186
187 // update the rule template options
188 updateRuleTemplateOptions(defaultsElement, updatedRuleTemplate, isDelegation);
189
190 }
191
192 /**
193 * Updates the rule template defaults options with those in the defaults element
194 * @param defaultsElement the ruleDefaults element
195 * @param updatedRuleTemplate the Rule Template being updated
196 */
197 protected void updateRuleTemplateOptions(Element defaultsElement, RuleTemplate updatedRuleTemplate, boolean isDelegation) throws InvalidXmlException {
198 // the possible defaults options
199 // NOTE: the current implementation will remove any existing RuleTemplateOption records for any values which are null, i.e. not set in the incoming XML.
200 // to pro-actively set default values for omitted options, simply set those values here, and records will be added if not present
201 String defaultActionRequested = null;
202 Boolean supportsComplete = null;
203 Boolean supportsApprove = null;
204 Boolean supportsAcknowledge = null;
205 Boolean supportsFYI = null;
206
207 // remove any RuleTemplateOptions the template may have but that we know we aren't going to update/reset
208 // (not sure if this case even exists...does anything else set rule template options?)
209 updatedRuleTemplate.removeNonDefaultOptions();
210
211 // read in new settings
212 if (defaultsElement != null) {
213
214 defaultActionRequested = defaultsElement.getChildText(DEFAULT_ACTION_REQUESTED, RULE_TEMPLATE_NAMESPACE);
215 supportsComplete = BooleanUtils.toBooleanObject(defaultsElement.getChildText(SUPPORTS_COMPLETE, RULE_TEMPLATE_NAMESPACE));
216 supportsApprove = BooleanUtils.toBooleanObject(defaultsElement.getChildText(SUPPORTS_APPROVE, RULE_TEMPLATE_NAMESPACE));
217 supportsAcknowledge = BooleanUtils.toBooleanObject(defaultsElement.getChildText(SUPPORTS_ACKNOWLEDGE, RULE_TEMPLATE_NAMESPACE));
218 supportsFYI = BooleanUtils.toBooleanObject(defaultsElement.getChildText(SUPPORTS_FYI, RULE_TEMPLATE_NAMESPACE));
219 }
220
221 if (!isDelegation) {
222 // if this is not a delegation template, store the template options that govern rule action constraints
223 // in the RuleTemplateOptions of the template
224 // we have two options for this behavior:
225 // 1) conditionally parse above, and then unconditionally set/unset the properties; this will have the effect of REMOVING
226 // any of these previously specified rule template options (and is arguably the right thing to do)
227 // 2) unconditionally parse above, and then conditionally set/unset the properties; this will have the effect of PRESERVING
228 // the existing rule template options on this template if it is a delegation template (which of course will be overwritten
229 // by this very same code if they subsequently upload without the delegation flag)
230 // This is a minor point, but the second implementation is chosen as it preserved the current behavior
231 updateOrDeleteRuleTemplateOption(updatedRuleTemplate, KEWConstants.ACTION_REQUEST_DEFAULT_CD, defaultActionRequested);
232 updateOrDeleteRuleTemplateOption(updatedRuleTemplate, KEWConstants.ACTION_REQUEST_APPROVE_REQ, supportsApprove);
233 updateOrDeleteRuleTemplateOption(updatedRuleTemplate, KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, supportsAcknowledge);
234 updateOrDeleteRuleTemplateOption(updatedRuleTemplate, KEWConstants.ACTION_REQUEST_FYI_REQ, supportsFYI);
235 updateOrDeleteRuleTemplateOption(updatedRuleTemplate, KEWConstants.ACTION_REQUEST_COMPLETE_REQ, supportsComplete);
236 }
237
238 }
239
240 /**
241 *
242 * Updates the default/template rule options with those in the defaults element
243 * @param defaultsElement the ruleDefaults element
244 * @param updatedRuleTemplate the Rule Template being updated
245 * @return whether this is a delegation rule template
246 */
247 protected boolean updateRuleDefaults(Element defaultsElement, RuleTemplate updatedRuleTemplate) throws InvalidXmlException {
248 // NOTE: implementation detail: in contrast with the other options, the delegate template, and the rule attributes,
249 // we unconditionally blow away the default rule and re-create it (we don't update the existing one, if there is one)
250 if (updatedRuleTemplate.getRuleTemplateId() != null) {
251 RuleBaseValues ruleDefaults = KEWServiceLocator.getRuleService().findDefaultRuleByRuleTemplateId(updatedRuleTemplate.getRuleTemplateId());
252 if (ruleDefaults != null) {
253 List ruleDelegationDefaults = KEWServiceLocator.getRuleDelegationService().findByDelegateRuleId(ruleDefaults.getRuleBaseValuesId());
254 // delete the rule
255 KEWServiceLocator.getRuleService().delete(ruleDefaults.getRuleBaseValuesId());
256 // delete the associated rule delegation defaults
257 for (Iterator iterator = ruleDelegationDefaults.iterator(); iterator.hasNext();) {
258 RuleDelegation ruleDelegation = (RuleDelegation) iterator.next();
259 KEWServiceLocator.getRuleDelegationService().delete(ruleDelegation.getRuleDelegationId());
260 }
261 }
262 }
263
264 boolean isDelegation = false;
265
266 if (defaultsElement != null) {
267 String delegationType = defaultsElement.getChildText(DELEGATION_TYPE, RULE_TEMPLATE_NAMESPACE);
268 isDelegation = !Utilities.isEmpty(delegationType);
269
270 String description = defaultsElement.getChildText(DESCRIPTION, RULE_TEMPLATE_NAMESPACE);
271
272 // would normally be validated via schema but might not be present if invoking RuleXmlParser directly
273 if (description == null) {
274 throw new InvalidXmlException("Description must be specified in rule defaults");
275 }
276
277 String fromDate = defaultsElement.getChildText(FROM_DATE, RULE_TEMPLATE_NAMESPACE);
278 String toDate = defaultsElement.getChildText(TO_DATE, RULE_TEMPLATE_NAMESPACE);
279 // toBooleanObject ensures that if the value is null (not set) that the Boolean object will likewise be null (will not default to a value)
280 Boolean forceAction = BooleanUtils.toBooleanObject(defaultsElement.getChildText(FORCE_ACTION, RULE_TEMPLATE_NAMESPACE));
281 Boolean active = BooleanUtils.toBooleanObject(defaultsElement.getChildText(ACTIVE, RULE_TEMPLATE_NAMESPACE));
282
283 if (isDelegation && !KEWConstants.DELEGATION_PRIMARY.equals(delegationType) && !KEWConstants.DELEGATION_SECONDARY.equals(delegationType)) {
284 throw new InvalidXmlException("Invalid delegation type '" + delegationType + "'." + " Expected one of: "
285 + KEWConstants.DELEGATION_PRIMARY + "," + KEWConstants.DELEGATION_SECONDARY);
286 }
287
288 // create our "default rule" which encapsulates the defaults for the rule
289 RuleBaseValues ruleDefaults = new RuleBaseValues();
290
291 // set simple values
292 ruleDefaults.setRuleTemplate(updatedRuleTemplate);
293 ruleDefaults.setDocTypeName(DUMMY_DOCUMENT_TYPE);
294 ruleDefaults.setTemplateRuleInd(Boolean.TRUE);
295 ruleDefaults.setCurrentInd(Boolean.TRUE);
296 ruleDefaults.setVersionNbr(new Integer(0));
297 ruleDefaults.setDescription(description);
298
299 // these are non-nullable fields, so default them if they were not set in the defaults section
300 ruleDefaults.setForceAction(Boolean.valueOf(BooleanUtils.isTrue(forceAction)));
301 ruleDefaults.setActiveInd(Boolean.valueOf(BooleanUtils.isTrue(active)));
302
303 if (ruleDefaults.getActivationDate() == null) {
304 ruleDefaults.setActivationDate(new Timestamp(System.currentTimeMillis()));
305 }
306
307 ruleDefaults.setFromDate(formatDate("fromDate",fromDate));
308 ruleDefaults.setToDate(formatDate("toDate", toDate));
309
310 // ok, if this is a "Delegate Template", then we need to set this other RuleDelegation object which contains
311 // some delegation-related info
312 RuleDelegation ruleDelegationDefaults = null;
313 if (isDelegation) {
314 ruleDelegationDefaults = new RuleDelegation();
315 ruleDelegationDefaults.setDelegationRuleBaseValues(ruleDefaults);
316 ruleDelegationDefaults.setDelegationType(delegationType);
317 ruleDelegationDefaults.setResponsibilityId(new Long(-1));
318 }
319
320 // explicitly save the new rule delegation defaults and default rule
321 KEWServiceLocator.getRuleTemplateService().saveRuleDefaults(ruleDelegationDefaults, ruleDefaults);
322 } else {
323 // do nothing, rule defaults will be deleted if ruleDefaults element is omitted
324 }
325
326 return isDelegation;
327 }
328
329
330 /**
331 * Updates or deletes a specified rule template option on the rule template
332 * @param updatedRuleTemplate the RuleTemplate being updated
333 * @param key the option key
334 * @param value the option value
335 */
336 protected void updateOrDeleteRuleTemplateOption(RuleTemplate updatedRuleTemplate, String key, Object value) {
337 if (value != null) {
338 // if the option exists and the incoming value is non-null (it's set), update it
339 RuleTemplateOption option = updatedRuleTemplate.getRuleTemplateOption(key);
340 if (option != null) {
341 option.setValue(value.toString());
342 } else {
343 updatedRuleTemplate.getRuleTemplateOptions().add(new RuleTemplateOption(key, value.toString()));
344 }
345 } else {
346 // otherwise if the incoming value IS null (not set), then explicitly remove the entry (if it exists)
347 Iterator<RuleTemplateOption> options = updatedRuleTemplate.getRuleTemplateOptions().iterator();
348 while (options.hasNext()) {
349 RuleTemplateOption opt = options.next();
350 if (key.equals(opt.getKey())) {
351 options.remove();
352 break;
353 }
354 }
355 }
356 }
357
358 /**
359 * Updates the rule template delegation template with the one specified in the XML (if any)
360 * @param ruleTemplateElement the XML ruleTemplate element
361 * @param updatedRuleTemplate the rule template to update
362 * @param parsedRuleTemplates the rule templates parsed in this parsing run
363 * @throws InvalidXmlException if a delegation template was specified but could not be found
364 */
365 protected void updateDelegationTemplate(Element ruleTemplateElement, RuleTemplate updatedRuleTemplate, List<RuleTemplate> parsedRuleTemplates) throws InvalidXmlException {
366 String delegateTemplateName = ruleTemplateElement.getChildText(DELEGATION_TEMPLATE, RULE_TEMPLATE_NAMESPACE);
367
368 if (delegateTemplateName != null) {
369 // if a delegateTemplate was set in the XML, then look it up and set it on the RuleTemplate object
370 // first try looking up an existing delegateTemplate in the system
371 RuleTemplate delegateTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(delegateTemplateName);
372
373 // if not found, try the list of templates currently parsed
374 if (delegateTemplate == null) {
375 for (RuleTemplate rt: parsedRuleTemplates) {
376 if (delegateTemplateName.equalsIgnoreCase(rt.getName())) {
377 // set the expected next rule template id on the target delegateTemplate
378 Long ruleTemplateId = KEWServiceLocator.getRuleTemplateService().getNextRuleTemplateId();
379 rt.setRuleTemplateId(ruleTemplateId);
380 delegateTemplate = rt;
381 break;
382 }
383 }
384 }
385
386 if (delegateTemplate == null) {
387 throw new InvalidXmlException("Cannot find delegation template " + delegateTemplateName);
388 }
389
390 updatedRuleTemplate.setDelegationTemplateId(delegateTemplate.getDelegationTemplateId());
391 updatedRuleTemplate.setDelegationTemplate(delegateTemplate);
392 } else {
393 // the previously referenced template is left in the system
394 }
395 }
396
397 /**
398 * Updates the attributes set on the RuleTemplate
399 * @param ruleTemplateElement the XML ruleTemplate element
400 * @param updatedRuleTemplate the RuleTemplate being updated
401 * @throws InvalidXmlException if there was a problem parsing the rule template attributes
402 */
403 protected void updateRuleTemplateAttributes(Element ruleTemplateElement, RuleTemplate updatedRuleTemplate) throws InvalidXmlException {
404 // add any newly defined rule template attributes to the rule template,
405 // update the active and required flags of any existing ones.
406 // if this is an update of an existing rule template, related attribute objects will be present in this rule template object,
407 // otherwise none will be present (so they'll all be new)
408
409 Element attributesElement = ruleTemplateElement.getChild(ATTRIBUTES, RULE_TEMPLATE_NAMESPACE);
410 List<RuleTemplateAttribute> incomingAttributes = new ArrayList<RuleTemplateAttribute>();
411 if (attributesElement != null) {
412 incomingAttributes.addAll(parseRuleTemplateAttributes(attributesElement, updatedRuleTemplate));
413 }
414
415 // inactivate all current attributes
416 for (RuleTemplateAttribute currentRuleTemplateAttribute: updatedRuleTemplate.getRuleTemplateAttributes()) {
417 String ruleAttributeName = (currentRuleTemplateAttribute.getRuleAttribute() != null) ? currentRuleTemplateAttribute.getRuleAttribute().getName() : "(null)";
418 LOG.debug("Inactivating rule template attribute with id " + currentRuleTemplateAttribute.getRuleTemplateAttributeId() + " and rule attribute with name " + ruleAttributeName);
419 currentRuleTemplateAttribute.setActive(Boolean.FALSE);
420 }
421 // NOTE: attributes are deactivated, not removed
422
423 // add/update any new attributes
424 for (RuleTemplateAttribute ruleTemplateAttribute: incomingAttributes) {
425 RuleTemplateAttribute potentialExistingTemplateAttribute = updatedRuleTemplate.getRuleTemplateAttribute(ruleTemplateAttribute);
426 if (potentialExistingTemplateAttribute != null) {
427 // template attribute exists on rule template already; update the options
428 potentialExistingTemplateAttribute.setActive(ruleTemplateAttribute.getActive());
429 potentialExistingTemplateAttribute.setRequired(ruleTemplateAttribute.getRequired());
430 } else {
431 // template attribute does not yet exist on template so add it
432 updatedRuleTemplate.getRuleTemplateAttributes().add(ruleTemplateAttribute);
433 }
434 }
435 }
436
437 /**
438 * Parses the RuleTemplateAttributes defined on the rule template element
439 * @param attributesElement the jdom Element object for the Rule Template attributes
440 * @param ruleTemplate the RuleTemplate object
441 * @return the RuleTemplateAttributes defined on the rule template element
442 * @throws InvalidXmlException
443 */
444 private List<RuleTemplateAttribute> parseRuleTemplateAttributes(Element attributesElement, RuleTemplate ruleTemplate) throws InvalidXmlException {
445 List<RuleTemplateAttribute> ruleTemplateAttributes = new ArrayList<RuleTemplateAttribute>();
446 Vector attributeElements = XmlHelper.findElements(attributesElement, ATTRIBUTE);
447 for (Iterator iterator = attributeElements.iterator(); iterator.hasNext();) {
448 ruleTemplateAttributes.add(parseRuleTemplateAttribute((Element) iterator.next(), ruleTemplate));
449 }
450 return ruleTemplateAttributes;
451 }
452
453 /**
454 * Parses a rule template attribute
455 * @param element the attribute XML element
456 * @param ruleTemplate the ruleTemplate to update
457 * @return a parsed rule template attribute
458 * @throws InvalidXmlException if the attribute does not exist
459 */
460 private RuleTemplateAttribute parseRuleTemplateAttribute(Element element, RuleTemplate ruleTemplate) throws InvalidXmlException {
461 String attributeName = element.getChildText(NAME, RULE_TEMPLATE_NAMESPACE);
462 String requiredValue = element.getChildText(REQUIRED, RULE_TEMPLATE_NAMESPACE);
463 String activeValue = element.getChildText(ACTIVE, RULE_TEMPLATE_NAMESPACE);
464 if (Utilities.isEmpty(attributeName)) {
465 throw new InvalidXmlException("Attribute name must be non-empty");
466 }
467 boolean required = DEFAULT_ATTRIBUTE_REQUIRED;
468 if (requiredValue != null) {
469 required = Boolean.parseBoolean(requiredValue);
470 }
471 boolean active = DEFAULT_ATTRIBUTE_ACTIVE;
472 if (activeValue != null) {
473 active = Boolean.parseBoolean(activeValue);
474 }
475 RuleAttribute ruleAttribute = KEWServiceLocator.getRuleAttributeService().findByName(attributeName);
476 if (ruleAttribute == null) {
477 throw new InvalidXmlException("Could not locate rule attribute for name '" + attributeName + "'");
478 }
479 RuleTemplateAttribute templateAttribute = new RuleTemplateAttribute();
480 templateAttribute.setRuleAttribute(ruleAttribute);
481 templateAttribute.setRuleAttributeId(ruleAttribute.getRuleAttributeId());
482 templateAttribute.setRuleTemplate(ruleTemplate);
483 templateAttribute.setRequired(Boolean.valueOf(required));
484 templateAttribute.setActive(Boolean.valueOf(active));
485 templateAttribute.setDisplayOrder(new Integer(templateAttributeCounter++));
486 return templateAttribute;
487 }
488
489 public Timestamp formatDate(String dateLabel, String dateString) throws InvalidXmlException {
490 if (StringUtils.isBlank(dateString)) {
491 return null;
492 }
493 try {
494 return new Timestamp(RiceConstants.getDefaultDateFormat().parse(dateString).getTime());
495 } catch (ParseException e) {
496 throw new InvalidXmlException(dateLabel + " is not in the proper format. Should have been: " + RiceConstants.DEFAULT_DATE_FORMAT_PATTERN);
497 }
498 }
499
500 }