Coverage Report - org.galagosearch.tupleflow.Linkage
 
Classes in this File Line Coverage Branch Coverage Complexity
Linkage
15%
8/53
3%
1/30
0
 
 1  
 // BSD License (http://www.galagosearch.org/license)
 2  
 package org.galagosearch.tupleflow;
 3  
 
 4  
 import java.io.IOException;
 5  
 import java.lang.reflect.Constructor;
 6  
 import java.lang.reflect.Field;
 7  
 import java.lang.reflect.InvocationTargetException;
 8  
 import java.lang.reflect.Method;
 9  
 
 10  
 /**
 11  
  *
 12  
  * @author trevor
 13  
  */
 14  0
 public class Linkage {
 15  
     public static void link(Step source, Step stage, String fieldName) throws IncompatibleProcessorException {
 16  
         try {
 17  4
             Class sourceClass = source.getClass();
 18  4
             Field processorField = sourceClass.getField(fieldName);
 19  4
             Class fieldClass = processorField.getType();
 20  
 
 21  
             // are they directly compatible?  if so, finish quickly
 22  4
             if (fieldClass.isInstance(stage)) {
 23  4
                 processorField.set(source, stage);
 24  4
                 return;
 25  
             }
 26  
 
 27  
             // try to determine the kind of thing that the stage is
 28  0
             Class stageClass = stage.getClass();
 29  
 
 30  0
             for (Class sourceInterfaceClass : sourceClass.getInterfaces()) {
 31  0
                 String interfaceName = sourceInterfaceClass.getName();
 32  
                 String typeName;
 33  0
                 Object adapted = null;
 34  
 
 35  
                 try {
 36  0
                     if ((typeName = Utility.strip(interfaceName, "$Source")) != null) {
 37  
                         // does the stage object have a ShreddedProcessor interface?
 38  
                         done:
 39  0
                         for (Class stageInterfaceClass : stageClass.getInterfaces()) {
 40  0
                             String stageInterfaceName = stageInterfaceClass.getName();
 41  
 
 42  0
                             if (stageInterfaceName.startsWith(typeName) &&
 43  
                                     stageInterfaceName.endsWith("$ShreddedProcessor")) {
 44  0
                                 String stageOrderName = Utility.strip(stageInterfaceName,
 45  
                                                                       "$ShreddedProcessor");
 46  0
                                 Constructor[] constructors = Class.forName(
 47  
                                         stageOrderName + "$TupleShredder").getConstructors();
 48  
 
 49  0
                                 for (Constructor c : constructors) {
 50  0
                                     Class[] types = c.getParameterTypes();
 51  
 
 52  0
                                     if (types.length == 1 && types[0].isInstance(stage)) {
 53  0
                                         adapted = c.newInstance(stage);
 54  0
                                         break done;
 55  
                                     }
 56  
                                 }
 57  
                             }
 58  
                         }
 59  0
                     } else if ((typeName = Utility.strip(interfaceName, "$ShreddedSource")) != null) {
 60  0
                         Constructor[] constructors = Class.forName(typeName + "$TupleUnshredder").
 61  
                                 getConstructors();
 62  
 
 63  0
                         for (Constructor c : constructors) {
 64  0
                             Class[] types = c.getParameterTypes();
 65  
 
 66  0
                             if (types.length == 1 && types[0].isInstance(stage)) {
 67  0
                                 adapted = c.newInstance(stage);
 68  0
                                 break;
 69  
                             }
 70  
                         }
 71  
                     }
 72  0
                 } catch (Exception e) {
 73  
                     // we're just checking to see if anything works, so exceptions here don't mean anything to us
 74  0
                     continue;
 75  0
                 }
 76  
 
 77  0
                 if (adapted != null && fieldClass.isInstance(adapted)) {
 78  0
                     processorField.set(source, adapted);
 79  0
                     return;
 80  
                 }
 81  
             }
 82  
 
 83  0
             throw new IncompatibleProcessorException("Stage of type '" + stage.getClass().getName() + "' cannot process the objects that '" + sourceClass.
 84  
                                                      getName() + "' produces.");
 85  0
         } catch (NoSuchFieldException e) {
 86  0
             throw new IncompatibleProcessorException(
 87  
                     "Stage of type '" + source.getClass().getName() + "' has no field called '" + fieldName + "' that can hold a processor object (or maybe it's just not public).");
 88  0
         } catch (IllegalAccessException e) {
 89  0
             throw new IncompatibleProcessorException(
 90  
                     "Stage of type '" + source.getClass().getName() + "' has a field called '" + fieldName + "', but " +
 91  
                     "it is private or protected and can't be modified by link().");
 92  
         }
 93  
     }
 94  
 
 95  
     public static void link(Step source, Step stage) throws IncompatibleProcessorException {
 96  4
         link(source, stage, "processor");
 97  4
     }
 98  
 
 99  
     public static void close(Step stage) throws IOException {
 100  
         Method close;
 101  
 
 102  
         try {
 103  0
             close = stage.getClass().getMethod("close");
 104  0
         } catch (NoSuchMethodException e) {
 105  0
             return;
 106  0
         }
 107  
 
 108  
         try {
 109  0
             close.invoke(stage);
 110  0
         } catch (IllegalAccessException e) {
 111  0
             throw (IOException) new IOException(
 112  
                     "Couldn't access close method (should declare it public)").initCause(e);
 113  0
         } catch (InvocationTargetException e) {
 114  0
             throw (IOException) new IOException("Problem when calling close method").initCause(e);
 115  0
         }
 116  0
     }
 117  
 }