1 15 package org.apache.hivemind.lib.pipeline; 16 17 import java.lang.reflect.Constructor ; 18 import java.lang.reflect.Modifier ; 19 import java.util.ArrayList ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 23 import org.apache.hivemind.ApplicationRuntimeException; 24 import org.apache.hivemind.ErrorLog; 25 import org.apache.hivemind.service.BodyBuilder; 26 import org.apache.hivemind.service.ClassFab; 27 import org.apache.hivemind.service.ClassFabUtils; 28 import org.apache.hivemind.service.ClassFactory; 29 import org.apache.hivemind.service.MethodIterator; 30 import org.apache.hivemind.service.MethodSignature; 31 32 38 class BridgeBuilder 39 { 40 private ErrorLog _errorLog; 41 42 private String _serviceId; 43 44 private Class _serviceInterface; 45 46 private Class _filterInterface; 47 48 private ClassFab _classFab; 49 50 private FilterMethodAnalyzer _filterMethodAnalyzer; 51 52 private Constructor _constructor; 53 54 BridgeBuilder(ErrorLog errorLog, String serviceId, Class serviceInterface, 55 Class filterInterface, ClassFactory classFactory) 56 { 57 _errorLog = errorLog; 58 _serviceId = serviceId; 59 _serviceInterface = serviceInterface; 60 _filterInterface = filterInterface; 61 62 String name = ClassFabUtils.generateClassName(_serviceInterface); 63 64 _classFab = classFactory.newClass(name, Object .class); 65 66 _filterMethodAnalyzer = new FilterMethodAnalyzer(serviceInterface); 67 } 68 69 private void createClass() 70 { 71 List serviceMethods = new ArrayList (); 72 List filterMethods = new ArrayList (); 73 74 createInfrastructure(); 75 76 MethodIterator mi = new MethodIterator(_serviceInterface); 77 78 while (mi.hasNext()) 79 { 80 serviceMethods.add(mi.next()); 81 } 82 83 boolean toStringMethodExists = mi.getToString(); 84 85 mi = new MethodIterator(_filterInterface); 86 87 while (mi.hasNext()) 88 { 89 filterMethods.add(mi.next()); 90 } 91 92 while (!serviceMethods.isEmpty()) 93 { 94 MethodSignature ms = (MethodSignature) serviceMethods.remove(0); 95 96 addBridgeMethod(ms, filterMethods); 97 } 98 99 reportExtraFilterMethods(filterMethods); 100 101 if (!toStringMethodExists) 102 ClassFabUtils.addToStringMethod(_classFab, PipelineMessages.bridgeInstanceDescription( 103 _serviceId, 104 _serviceInterface)); 105 106 Class bridgeClass = _classFab.createClass(); 107 108 _constructor = bridgeClass.getConstructors()[0]; 109 } 110 111 private void createInfrastructure() 112 { 113 _classFab.addField("_next", _serviceInterface); 114 _classFab.addField("_filter", _filterInterface); 115 116 _classFab.addConstructor(new Class [] 117 { _serviceInterface, _filterInterface }, null, "{ _next = $1; _filter = $2; }"); 118 119 _classFab.addInterface(_serviceInterface); 120 } 121 122 130 public Object instantiateBridge(Object nextBridge, Object filter) 131 { 132 if (_constructor == null) 133 createClass(); 134 135 try 136 { 137 return _constructor.newInstance(new Object [] 138 { nextBridge, filter }); 139 } 140 catch (Exception ex) 141 { 142 throw new ApplicationRuntimeException(ex); 143 } 144 } 145 146 private void reportExtraFilterMethods(List filterMethods) 147 { 148 Iterator i = filterMethods.iterator(); 149 150 while (i.hasNext()) 151 { 152 MethodSignature ms = (MethodSignature) i.next(); 153 154 _errorLog.error(PipelineMessages.extraFilterMethod( 155 ms, 156 _filterInterface, 157 _serviceInterface, 158 _serviceId), null, null); 159 } 160 } 161 162 170 private void addBridgeMethod(MethodSignature ms, List filterMethods) 171 { 172 Iterator i = filterMethods.iterator(); 173 174 while (i.hasNext()) 175 { 176 MethodSignature fms = (MethodSignature) i.next(); 177 178 int position = _filterMethodAnalyzer.findServiceInterfacePosition(ms, fms); 179 180 if (position >= 0) 181 { 182 addBridgeMethod(position, ms, fms); 183 i.remove(); 184 return; 185 } 186 } 187 188 String message = PipelineMessages.unmatchedServiceMethod(ms, _filterInterface); 189 190 _errorLog.error(message, null, null); 191 192 BodyBuilder b = new BodyBuilder(); 193 194 b.add("throw new org.apache.hivemind.ApplicationRuntimeException("); 195 b.addQuoted(message); 196 b.addln(");"); 197 198 _classFab.addMethod(Modifier.PUBLIC, ms, b.toString()); 199 } 200 201 206 private void addBridgeMethod(int position, MethodSignature ms, MethodSignature fms) 207 { 208 StringBuffer buffer = new StringBuffer (100); 209 210 if (ms.getReturnType() != void.class) 211 buffer.append("return "); 212 213 buffer.append("_filter."); 214 buffer.append(ms.getName()); 215 buffer.append("("); 216 217 boolean comma = false; 218 int filterParameterCount = fms.getParameterTypes().length; 219 220 for (int i = 0; i < position; i++) 221 { 222 if (comma) 223 buffer.append(", "); 224 225 buffer.append("$"); 226 buffer.append(i + 1); 229 230 comma = true; 231 } 232 233 if (comma) 234 buffer.append(", "); 235 236 240 buffer.append("_next"); 241 242 for (int i = position + 1; i < filterParameterCount; i++) 243 { 244 buffer.append(", $"); 245 buffer.append(i); 246 } 247 248 buffer.append(");"); 249 250 253 _classFab.addMethod(Modifier.PUBLIC, ms, buffer.toString()); 254 } 255 256 } | Popular Tags |