Coverage Report - org.kuali.rice.krms.api.engine.Term
 
Classes in this File Line Coverage Branch Coverage Complexity
Term
0%
0/36
0%
0/22
5
Term$1
N/A
N/A
5
Term$TreeMapComparator
0%
0/31
0%
0/30
5
 
 1  
 package org.kuali.rice.krms.api.engine;
 2  
 
 3  
 import java.io.Serializable;
 4  
 import java.util.Collections;
 5  
 import java.util.Comparator;
 6  
 import java.util.Iterator;
 7  
 import java.util.Map;
 8  
 import java.util.Map.Entry;
 9  
 import java.util.TreeMap;
 10  
 
 11  
 import org.springframework.util.CollectionUtils;
 12  
 
 13  
 /**
 14  
  * Identifies a (hopefully) resolvable {@link Term}.  For resolution in the {@link TermResolutionEngine}, The appropriate 
 15  
  * {@link TermResolver} will be selected by matching the {@link TermSpecification} and parameters of the {@link Term} with 
 16  
  * the output and parameter names of the {@link TermResolver}. 
 17  
  * @author gilesp
 18  
  *
 19  
  */
 20  0
 public final class Term implements Comparable<Term> {
 21  
 
 22  
         private final TermSpecification specification;
 23  
         
 24  
         private final Map<String, String> parameters;
 25  
         
 26  0
         private static final TreeMapComparator<String,String> treeMapComparator = new TreeMapComparator<String, String>();
 27  
 
 28  
         public Term(TermSpecification specification) {
 29  0
                 this(specification, null);
 30  0
         }        
 31  
         
 32  
         /**
 33  
          * This constructs a Term, which is a named piece of data that is usually obtainable 
 34  
          * through the {@link TermResolutionEngine}
 35  
          * 
 36  
          * @param specification the specification (which maps a Term to a resolver) for this Term
 37  
          * @param parameters an optional map of properties that may be used to allow a single TermResolver to resolve multiple Terms
 38  
          */
 39  0
         public Term(TermSpecification specification, Map<String, String> parameters) {
 40  0
                 this.specification = specification;
 41  0
                 if (parameters == null) {
 42  0
                         this.parameters = Collections.emptyMap();
 43  
                 } else {
 44  
                         // using TreeMap for ordered iteration since we're comparable
 45  0
                         this.parameters = Collections.unmodifiableMap(new TreeMap<String, String>(parameters));
 46  
                 }
 47  0
         }
 48  
         
 49  0
         public TermSpecification getSpecification() { return this.specification; }
 50  0
         public Map<String, String> getProperties() { return parameters; }
 51  
 
 52  
         /* (non-Javadoc)
 53  
          * @see java.lang.Object#hashCode()
 54  
          */
 55  
         @Override
 56  
         public int hashCode() {
 57  0
                 final int prime = 31;
 58  0
                 int result = 1;
 59  0
                 result = prime * result + ((specification == null) ? 0 : specification.hashCode());
 60  0
                 result = prime * result + ((parameters == null) ? 0 : parameters.hashCode());
 61  0
                 return result;
 62  
         }
 63  
 
 64  
         /* (non-Javadoc)
 65  
          * @see java.lang.Object#equals(java.lang.Object)
 66  
          */
 67  
         @Override
 68  
         public boolean equals(Object obj) {
 69  0
                 if (this == obj)
 70  0
                         return true;
 71  0
                 if (obj == null)
 72  0
                         return false;
 73  0
                 if (getClass() != obj.getClass())
 74  0
                         return false;
 75  0
                 Term other = (Term) obj;
 76  0
                 return this.compareTo(other) == 0;
 77  
         }
 78  
 
 79  
         @Override
 80  
         public int compareTo(Term o) {
 81  0
                 if (o == null) return 1;
 82  0
                 if (this == o) return 0;
 83  0
                 return (treeMapComparator.compare(this.parameters, o.parameters));
 84  
         }
 85  
         
 86  
         /**
 87  
          * @return an unmodifiable Map of parameters specified on this Term.  Guaranteed non-null.
 88  
          */
 89  
         public Map<String, String> getParameters() {
 90  0
                 return Collections.unmodifiableMap(parameters);
 91  
         }
 92  
 
 93  
         @Override
 94  
         public String toString() {
 95  
                 // TODO make this pretty
 96  0
                 StringBuilder sb = new StringBuilder();
 97  0
                 if (parameters != null) for (Entry<String,String> parameter : parameters.entrySet()) {
 98  0
                         sb.append(", ");
 99  0
                         sb.append(parameter.getKey());
 100  0
                         sb.append("=");
 101  0
                         sb.append(parameter.getValue());
 102  
                 }
 103  0
                 return getClass().getSimpleName()+"("+specification.toString() + sb.toString() + ")";
 104  
         }
 105  
         
 106  0
         @SuppressWarnings("rawtypes")
 107  0
         private static class TreeMapComparator<T extends Comparable, V extends Comparable> implements Comparator<Map<T,V>>, Serializable {
 108  
                 
 109  
                 private static final long serialVersionUID = 1L;
 110  
 
 111  
                 /**
 112  
                  * This overridden method compares two {@link TreeMap}s whose keys and elements are both {@link Comparable}
 113  
                  * 
 114  
                  * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
 115  
                  */
 116  
                 @SuppressWarnings("unchecked")
 117  
                 public int compare(Map<T,V> o1, Map<T,V> o2) {
 118  0
                         if (CollectionUtils.isEmpty(o1)) {
 119  0
                                 if (CollectionUtils.isEmpty(o2)) return 0;
 120  0
                                 return -1;
 121  0
                         } else if (CollectionUtils.isEmpty(o2)) {
 122  0
                                 return 1;
 123  
                         }
 124  
                         
 125  
                         // neither one is empty.  Iterate through both.
 126  
 
 127  0
                         Iterator<Entry<T,V>> o1Iter = o1.entrySet().iterator();
 128  0
                         Iterator<Entry<T,V>> o2Iter = o2.entrySet().iterator();
 129  
                         
 130  0
                         while (o1Iter.hasNext() && o2Iter.hasNext()) {
 131  0
                                 Entry<T,V> o1Elem = o1Iter.next(); 
 132  0
                                 Entry<T,V> o2Elem = o2Iter.next();
 133  0
                                 if (o1Elem == null) {
 134  0
                                         if (o2Elem == null) continue;
 135  0
                                         return -1;
 136  
                                 } 
 137  
                                 
 138  0
                                 T o1ElemKey = o1Elem.getKey();
 139  0
                                 T o2ElemKey = o2Elem.getKey();
 140  0
                                 if (o1ElemKey == null) {
 141  0
                                         if (o2ElemKey != null) return -1;
 142  
                                         // if they're both null, fall through
 143  
                                 } else {
 144  0
                                         int elemKeyCompare = o1ElemKey.compareTo(o2ElemKey);
 145  0
                                         if (elemKeyCompare != 0) return elemKeyCompare;
 146  
                                 }
 147  
                                 
 148  0
                                 V o1ElemValue = o1Elem.getValue();
 149  0
                                 V o2ElemValue = o2Elem.getValue();
 150  0
                                 if (o1ElemValue == null) {
 151  0
                                         if (o2ElemValue != null) return -1;
 152  
                                         // if they're both null, fall through
 153  
                                 } else {
 154  0
                                         int elemValueCompare = o1ElemValue.compareTo(o2ElemValue);
 155  0
                                         if (elemValueCompare != 0) return elemValueCompare;
 156  
                                 }
 157  0
                         }
 158  
                         
 159  0
                         if (o1Iter.hasNext()) return 1;
 160  0
                         if (o2Iter.hasNext()) return -1;
 161  0
                         return 0;
 162  
                 }
 163  
 
 164  
         }
 165  
 
 166  
         
 167  
 }