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