1 15 package org.apache.hivemind.lib.strategy; 16 17 import java.lang.reflect.Constructor ; 18 import java.lang.reflect.Modifier ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 22 import org.apache.hivemind.ApplicationRuntimeException; 23 import org.apache.hivemind.HiveMind; 24 import org.apache.hivemind.ServiceImplementationFactory; 25 import org.apache.hivemind.ServiceImplementationFactoryParameters; 26 import org.apache.hivemind.lib.util.StrategyRegistry; 27 import org.apache.hivemind.lib.util.StrategyRegistryImpl; 28 import org.apache.hivemind.service.ClassFab; 29 import org.apache.hivemind.service.ClassFabUtils; 30 import org.apache.hivemind.service.ClassFactory; 31 import org.apache.hivemind.service.MethodIterator; 32 import org.apache.hivemind.service.MethodSignature; 33 34 47 public class StrategyFactory implements ServiceImplementationFactory 48 { 49 private ClassFactory _classFactory; 50 51 public Object createCoreServiceImplementation( 52 ServiceImplementationFactoryParameters factoryParameters) 53 { 54 StrategyRegistry ar = new StrategyRegistryImpl(); 55 56 buildRegistry(factoryParameters, ar); 57 58 Class implClass = buildImplementationClass(factoryParameters); 59 60 try 61 { 62 Constructor c = implClass.getConstructors()[0]; 63 64 return c.newInstance(new Object [] 65 { ar }); 66 } 67 catch (Exception ex) 68 { 69 throw new ApplicationRuntimeException(ex.getMessage(), HiveMind 70 .getLocation(factoryParameters.getFirstParameter()), ex); 71 } 72 73 } 74 75 77 void buildRegistry(ServiceImplementationFactoryParameters factoryParameters, StrategyRegistry ar) 78 { 79 Class serviceInterface = factoryParameters.getServiceInterface(); 80 81 StrategyParameter p = (StrategyParameter) factoryParameters.getFirstParameter(); 82 83 List contributions = p.getContributions(); 84 85 Iterator i = contributions.iterator(); 86 87 while (i.hasNext()) 88 { 89 StrategyContribution c = (StrategyContribution) i.next(); 90 91 try 92 { 93 Object adapter = c.getStrategy(); 94 95 if (!serviceInterface.isAssignableFrom(adapter.getClass())) 96 throw new ClassCastException (StrategyMessages.strategyWrongInterface(adapter, c 97 .getRegisterClass(), serviceInterface)); 98 99 ar.register(c.getRegisterClass(), adapter); 100 } 101 catch (Exception ex) 102 { 103 factoryParameters.getErrorLog().error(ex.getMessage(), c.getLocation(), ex); 104 } 105 106 } 107 108 } 109 110 112 private Class buildImplementationClass(ServiceImplementationFactoryParameters factoryParameters) 113 { 114 String name = ClassFabUtils.generateClassName(factoryParameters.getServiceInterface()); 115 116 return buildImplementationClass(factoryParameters, name); 117 } 118 119 121 Class buildImplementationClass(ServiceImplementationFactoryParameters factoryParameters, 122 String name) 123 { 124 Class serviceInterface = factoryParameters.getServiceInterface(); 125 126 ClassFab cf = _classFactory.newClass(name, Object .class); 127 128 cf.addInterface(serviceInterface); 129 130 cf.addField("_registry", StrategyRegistry.class); 131 132 cf.addConstructor(new Class [] 133 { StrategyRegistry.class }, null, "_registry = $1;"); 134 135 137 cf.addMethod(Modifier.PRIVATE, new MethodSignature(serviceInterface, "_getStrategy", 138 new Class [] 139 { Object .class }, null), "return (" + serviceInterface.getName() 140 + ") _registry.getStrategy($1.getClass());"); 141 142 MethodIterator i = new MethodIterator(serviceInterface); 143 144 while (i.hasNext()) 145 { 146 MethodSignature sig = i.next(); 147 148 if (proper(sig)) 149 { 150 addAdaptedMethod(cf, sig); 151 } 152 else 153 { 154 ClassFabUtils.addNoOpMethod(cf, sig); 155 156 factoryParameters.getErrorLog().error( 157 StrategyMessages.improperServiceMethod(sig), 158 HiveMind.getLocation(factoryParameters.getFirstParameter()), 159 null); 160 } 161 162 } 163 164 if (!i.getToString()) 165 ClassFabUtils.addToStringMethod(cf, StrategyMessages.toString(factoryParameters 166 .getServiceId(), serviceInterface)); 167 168 return cf.createClass(); 169 } 170 171 private void addAdaptedMethod(ClassFab cf, MethodSignature sig) 172 { 173 String body = "return ($r) _getStrategy($1)." + sig.getName() + "($$);"; 174 175 cf.addMethod(Modifier.PUBLIC, sig, body); 176 } 177 178 182 183 private boolean proper(MethodSignature sig) 184 { 185 Class [] parameterTypes = sig.getParameterTypes(); 186 187 return parameterTypes != null && parameterTypes.length > 0 188 && !parameterTypes[0].isPrimitive(); 189 } 190 191 public void setClassFactory(ClassFactory classFactory) 192 { 193 _classFactory = classFactory; 194 } 195 } | Popular Tags |