Coverage Report - org.galagosearch.core.retrieval.query.NodeType
 
Classes in this File Line Coverage Branch Coverage Complexity
NodeType
80%
35/44
69%
22/32
0
 
 1  
 // BSD License (http://www.galagosearch.org/license)
 2  
 
 3  
 package org.galagosearch.core.retrieval.query;
 4  
 
 5  
 import java.lang.reflect.Constructor;
 6  
 import org.galagosearch.core.retrieval.structured.StructuredIterator;
 7  
 import org.galagosearch.tupleflow.Parameters;
 8  
 
 9  
 /**
 10  
  * <p>A NodeType describes the class type and input types of an iterator.</p>
 11  
  * 
 12  
  * <p>Traversals that modify a tree may want to know what type of iterator will be generated
 13  
  * when a Node is converted into a StructuredIterator.  For instance, a Node with a
 14  
  * "counts" operator will turn into a ExtentListIterator.  This is important to know because
 15  
  * a ScoreCombinationIterator can't take an ExtentListIterator as an argument; it needs an
 16  
  * iterator between them to convert extents into scores.  A Traversal can check the types
 17  
  * of "counts" and "combine", notice the type mismatch, and add a "#feature" node between
 18  
  * them so that the types match.</p>
 19  
  * 
 20  
  * @author trevor
 21  
  */
 22  
 public class NodeType {
 23  
     private Class<? extends StructuredIterator> nodeClass;
 24  
 
 25  76
     public NodeType(Class<? extends StructuredIterator> nodeClass) {
 26  76
         this.nodeClass = nodeClass;
 27  76
     }
 28  
     
 29  
     public Class<? extends StructuredIterator> getIteratorClass() {
 30  24
         return nodeClass;
 31  
     }
 32  
     
 33  
     public Class[] getInputs() throws Exception {
 34  24
         Constructor constructor = null;
 35  
         try {
 36  24
             constructor = getConstructor();
 37  0
         } catch(Exception e) {
 38  0
             return new Class[0];
 39  24
         }
 40  24
         return constructor.getParameterTypes();
 41  
     }
 42  
     
 43  
     public Class[] getParameterTypes(int length) throws Exception {
 44  20
         Class[] inputs = getInputs();
 45  20
         if (inputs == null) return new Class[0];
 46  20
         if (inputs.length == 0) return new Class[0];
 47  20
         if (inputs[inputs.length-1].isArray()) {
 48  12
             if (length < inputs.length-1) {
 49  
                 // Not enough parameters.
 50  0
                 return null;
 51  
             } else {
 52  12
                 Class[] result = new Class[length];
 53  
                 // Copy in classes for the first few parameters.
 54  28
                 for (int i = 0; i < inputs.length-1; ++i) {
 55  16
                     result[i] = inputs[i];
 56  
                 }
 57  
                 // Apply the array class type to the remaining slots.
 58  36
                 for (int i = inputs.length-1; i < result.length; ++i) {
 59  24
                     result[i] = inputs[inputs.length-1].getComponentType();
 60  
                 }
 61  12
                 return result;
 62  
             }
 63  
         } else {
 64  8
             if (length != inputs.length) {
 65  0
                 return null;
 66  
             } else {
 67  8
                 return inputs;
 68  
             }
 69  
         }
 70  
     }
 71  
     
 72  
     public boolean isStructuredIteratorOrArray(Class c) {
 73  76
         if (c.isArray() && StructuredIterator.class.isAssignableFrom(c.getComponentType()))
 74  32
             return true;
 75  44
         if (StructuredIterator.class.isAssignableFrom(c))
 76  36
             return true;
 77  8
         return false;
 78  
     }
 79  
     
 80  
     public Constructor getConstructor() throws Exception {
 81  44
         for (Constructor constructor : nodeClass.getConstructors()) {
 82  44
             Class[] types = constructor.getParameterTypes();
 83  
          
 84  
             // The constructor needs at least one parameter.
 85  44
             if (types.length < 1)
 86  0
                 continue;
 87  
             // The first class needs to be a Parameters object.
 88  44
             if (!Parameters.class.isAssignableFrom(types[0]))
 89  0
                 continue;
 90  
             // Check arguments for valid argument types.
 91  44
             boolean validTypes = true;
 92  100
             for (int i = 1; i < types.length; ++i) {
 93  56
                 if (!isStructuredIteratorOrArray(types[i])) {
 94  0
                     validTypes = false;
 95  0
                     break;
 96  
                 }
 97  
             }
 98  
             // If everything looks good, return this constructor.
 99  44
             if (validTypes) {
 100  44
                 return constructor;
 101  
             }
 102  
         }
 103  
         
 104  0
         throw new Exception("No reasonable constructors were found for " + nodeClass.toString());
 105  
     }
 106  
 }