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 }