Coverage Report - org.kuali.rice.kew.rule.GenericWorkflowAttribute
 
Classes in this File Line Coverage Branch Coverage Complexity
GenericWorkflowAttribute
0%
0/40
0%
0/16
2.3
 
 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.kew.rule;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.Collections;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 
 23  
 import javax.xml.xpath.XPathExpressionException;
 24  
 
 25  
 import org.apache.commons.lang.ObjectUtils;
 26  
 import org.apache.log4j.Logger;
 27  
 import org.kuali.rice.kew.routeheader.DocumentContent;
 28  
 
 29  
 
 30  
 /**
 31  
  * Generic base class that implements common functionality to simplify implementing
 32  
  * a WorkflowAttribute.  This includes simplified template methods, as well as a generic
 33  
  * attribute content model.
 34  
  * 
 35  
  * <p>Control flow (for isMatch):</p>
 36  
  * 
 37  
  * <ol>
 38  
  *   <li>{@link #isMatch(DocumentContent, List)}
 39  
  *     <ol>
 40  
  *       <li>{@link #isMatch(List, List)}
 41  
  *         <ol>
 42  
  *           <li>{@link #isMatch(Map, List)}</li>
 43  
  *         </ol>
 44  
  *       </li>
 45  
  *     </ol>
 46  
  *   </li>
 47  
  * </ol>
 48  
  * 
 49  
  * The default matching algorithm will match:
 50  
  * <blockquote><i>if any single attribute's properties are a match for all rule extension values</i></blockquote>
 51  
  * This implementation does not (yet!) implement a generic internal map of properties, so it is up to subclasses
 52  
  * to expose specific named getters/setters to set data on an attribute of this ancestry.
 53  
  * 
 54  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 55  
  */
 56  
 public abstract class GenericWorkflowAttribute extends AbstractWorkflowAttribute {
 57  0
     protected final Logger log = Logger.getLogger(getClass());
 58  
     protected final String attributeName;
 59  
     protected final GenericAttributeContent content;
 60  
     
 61  
     public GenericWorkflowAttribute() {
 62  0
         this(null); // can't do getClass().getName() so we'll have to pass null...shame
 63  0
     }
 64  
 
 65  0
     public GenericWorkflowAttribute(String uniqueName) {
 66  0
         if (uniqueName != null) {
 67  0
             this.attributeName = uniqueName;
 68  
         } else {
 69  0
             this.attributeName = getClass().getName();
 70  
         }
 71  0
         content = new GenericAttributeContent(attributeName);
 72  0
     }
 73  
 
 74  
     /**
 75  
      * Template method for subclasses to override to expose attribute state
 76  
      * @return map exposing attribute state
 77  
      */
 78  
     public abstract Map<String, String> getProperties();
 79  
 
 80  
     /**
 81  
      * Simply defers to GenericAttributeContent to generate suitable XML content in a standard fashion
 82  
      */
 83  
     public String getDocContent() {
 84  0
         String dc = content.generateContent(getProperties());
 85  
         //log.info("Generating doc content: " + dc, new Exception("Dummy exception"));
 86  0
         return dc;
 87  
     }
 88  
 
 89  
     public boolean isMatch(DocumentContent docContent, List<RuleExtensionBo> ruleExtensions) {
 90  0
         log.info("isMatch: " + docContent + " " + ruleExtensions);
 91  
         try {
 92  
             // could be multiple attributes on the incoming doc content!
 93  0
             List<Map<String, String>> propertiesList = content.parseContent(docContent.getAttributeContent());
 94  
             
 95  0
             return isMatch(propertiesList, ruleExtensions);
 96  0
         } catch (XPathExpressionException xpee) {
 97  0
             String message = "Error parsing attribute '" + attributeName + "' content: " + docContent.getDocContent();
 98  0
             log.error(message, xpee);
 99  0
             throw new RuntimeException(xpee);
 100  
         }
 101  
     }
 102  
 
 103  
     /**
 104  
      * Returns true if any single incoming attribute's properties are a match for all rule extension values
 105  
      * @param propertiesList the list of incoming attributes' properties
 106  
      * @param ruleExtensions the rule extensions
 107  
      * @return true if any single attribute's properties are a match for all rule extension values
 108  
      */
 109  
     protected boolean isMatch(List<Map<String, String>> propertiesList, List<RuleExtensionBo> ruleExtensions) {
 110  0
         for (Map<String, String> properties: propertiesList) {
 111  0
             return isMatch(properties, ruleExtensions);
 112  
         }
 113  0
         return false;
 114  
     }
 115  
 
 116  
     /**
 117  
      * Returns true if all key/value pairs defined by the specified rule extensions are present in the incoming attribute's
 118  
      * properties
 119  
      * @param properties incoming attribute's properties
 120  
      * @param ruleExtensions list of rule extensions
 121  
      * @return true if all key/value pairs defined by the specified rule extensions are present in the incoming attribute's
 122  
      */
 123  
     protected boolean isMatch(Map<String, String> properties, List<RuleExtensionBo> ruleExtensions) {
 124  0
         for (RuleExtensionBo ruleExtension: ruleExtensions) {
 125  0
             for (RuleExtensionValue ruleExtensionValue: ruleExtension.getExtensionValues()) {
 126  0
                 if (!ObjectUtils.equals(ruleExtensionValue.getValue(), properties.get(ruleExtensionValue.getKey()))) {
 127  0
                     return false;
 128  
                 }
 129  
             }
 130  
         }
 131  0
         return true;
 132  
     }
 133  
 
 134  
     /**
 135  
      * These guys should probably be implemented to set the parameters on an internal member property map this attribute
 136  
      * should use to contain all properties set on it, like StandardGenericXmlAttribute.
 137  
      * @see #getProperties()
 138  
      * TODO: implement me!
 139  
      */
 140  
     public List validateRoutingData(Map paramMap) {
 141  0
         return Collections.EMPTY_LIST;
 142  
     }
 143  
     public List validateRuleData(Map paramMap) {
 144  0
         return Collections.EMPTY_LIST;
 145  
     }
 146  
 
 147  
     //public List validateClientRouting....
 148  
 
 149  
     /**
 150  
      * I think the job of this method is to marshal the current state of the attribute into a representative list of rule extension
 151  
      * values.  On that assumption, this method should simply create a list of RuleExtensionValues based on the the property map
 152  
      * this attribute uses to hold property values.
 153  
      * 
 154  
      * TODO: this is not fully implemented! e.g. generic property map like StandardGenericXmlAttribute
 155  
      */
 156  
     public List<RuleExtensionValue> getRuleExtensionValues() {
 157  0
         log.info("getRuleExtensionValues");
 158  0
         List<RuleExtensionValue> exts = new ArrayList<RuleExtensionValue>();
 159  0
         Map<String, String> props = getProperties();
 160  0
         if (props != null) {
 161  0
             for (Map.Entry<String, String> entry: props.entrySet()) {
 162  0
                 if (entry.getValue() != null) {
 163  0
                     RuleExtensionValue ruleVal = new RuleExtensionValue();
 164  0
                     ruleVal.setKey(entry.getKey());
 165  0
                     ruleVal.setValue(entry.getValue());
 166  0
                     exts.add(ruleVal);
 167  0
                 }
 168  
             }
 169  
         }
 170  0
         return exts;
 171  
     }
 172  
 }