1 package org.objectweb.fractal.julia.factory; 2 3 import org.objectweb.fractal.api.Component; 4 import org.objectweb.fractal.api.Type; 5 import org.objectweb.fractal.api.factory.GenericFactory; 6 import org.objectweb.fractal.api.factory.InstantiationException; 7 import org.objectweb.fractal.api.type.ComponentType; 8 import org.objectweb.fractal.api.type.InterfaceType; 9 import org.objectweb.fractal.julia.loader.Initializable; 10 import org.objectweb.fractal.julia.loader.Tree; 11 12 import java.lang.reflect.Method ; 13 import java.lang.reflect.Modifier ; 14 import java.util.HashMap ; 15 import java.util.Map ; 16 17 29 30 public abstract class CheckGenericFactoryMixin 31 implements GenericFactory, Initializable 32 { 33 34 38 private CheckGenericFactoryMixin () { 39 } 40 41 45 private boolean useContextClassLoader; 46 47 54 55 public void initialize (final Tree args) throws Exception { 56 Tree t = args.getValue("use-context-class-loader"); 57 if (t != null && t.equals("true")) { 58 useContextClassLoader = true; 59 } 60 } 61 62 78 79 public Component newFcInstance ( 80 final Type type, 81 final Object controllerDesc, 82 final Object contentDesc) throws InstantiationException 83 { 84 ClassLoader loader = null; 85 if (controllerDesc instanceof Object []) { 86 loader = (ClassLoader )((Object [])controllerDesc)[0]; 87 } 88 loader = (ClassLoader )getFcLoader(loader); 89 90 checkFcType(type, loader); 91 92 Object content = contentDesc; 93 if (content instanceof Object []) { 94 content = ((Object [])content)[1]; 97 } 98 if (content instanceof String ) { 99 checkFcContentClass(type, (String )content, loader); 100 } 101 return _super_newFcInstance(type, controllerDesc, contentDesc); 102 } 103 104 public Object getFcLoader (final Object loader) { 105 if (loader == null) { 106 if (useContextClassLoader) { 107 return Thread.currentThread().getContextClassLoader(); 108 } else { 109 return getClass().getClassLoader(); 110 } 111 } else { 112 return _super_getFcLoader(loader); 113 } 114 } 115 116 123 124 public void checkFcType (final Type type, final ClassLoader loader) 125 throws InstantiationException 126 { 127 if (type instanceof ComponentType) { 128 InterfaceType[] itfTypes = ((ComponentType)type).getFcInterfaceTypes(); 129 for (int i = 0; i < itfTypes.length; ++i) { 130 InterfaceType itfType = itfTypes[i]; 131 String name = itfType.getFcItfName(); 132 String signature = itfType.getFcItfSignature(); 133 Class itf; 135 try { 136 itf = loader.loadClass(signature); 137 } catch (ClassNotFoundException e) { 138 throw new ChainedInstantiationException( 139 e, null, "No such interface: " + signature); 140 } 141 if (!(itf.isInterface() && Modifier.isPublic(itf.getModifiers()))) { 143 throw new ChainedInstantiationException( 144 null, null, signature + " is not a public interface"); 145 } 146 if (name.equals("attribute-controller")) { 147 Class ac; 149 try { 150 ac = loader.loadClass( 151 "org.objectweb.fractal.api.control.AttributeController"); 152 } catch (ClassNotFoundException e) { 153 throw new ChainedInstantiationException( 154 e, null, "Cannot check this operation"); 155 } 156 if (ac.isAssignableFrom(itf)) { 157 if (!checkFcAttributeControllerInterface(itf)) { 158 throw new ChainedInstantiationException( 159 null, 160 null, 161 signature + " is not a valid attribute controller interface"); 162 } 163 } 164 } 165 } 166 } 167 } 168 169 176 177 public boolean checkFcAttributeControllerInterface (final Class itf) { 178 Map types = new HashMap (); 179 Method [] meths = itf.getMethods(); 180 for (int i = 0; i < meths.length; ++i) { 182 Method m = meths[i]; 183 String name = m.getName(); 184 Class [] formals = m.getParameterTypes(); 185 Class result = m.getReturnType(); 186 if (name.startsWith("get")) { 187 if (formals.length == 0 && !result.equals(Void.TYPE)) { 188 types.put(name, result); 189 continue; 190 } 191 } else if (name.startsWith("set")) { 192 if (formals.length == 1 && result.equals(Void.TYPE)) { 193 types.put(name, formals[0]); 194 continue; 195 } 196 } 197 return false; 198 } 199 for (int i = 0; i < meths.length; ++i) { 202 Method m = meths[i]; 203 String name = m.getName(); 204 if (name.startsWith("get")) { 205 Class type = (Class )types.get("set" + name.substring(3)); 206 if (type == null || m.getReturnType().equals(type)) { 207 continue; 208 } 209 } else { 210 Class type = (Class )types.get("get" + name.substring(3)); 211 if (type == null || m.getParameterTypes()[0].equals(type)) { 212 continue; 213 } 214 } 215 return false; 216 } 217 return true; 218 } 219 220 233 234 public void checkFcContentClass ( 235 final Type type, 236 final String content, 237 final ClassLoader loader) throws InstantiationException 238 { 239 Class contentClass; 240 try { 242 contentClass = loader.loadClass(content); 243 } catch (ClassNotFoundException e) { 244 throw new ChainedInstantiationException( 245 e, 246 null, 247 "Cannot find the component implementation class '" + content + "'"); 248 } 249 int mods = contentClass.getModifiers(); 251 if (!Modifier.isPublic(mods) || 252 Modifier.isAbstract(mods) || 253 Modifier.isInterface(mods)) 254 { 255 throw new ChainedInstantiationException( 256 null, 257 null, 258 "The component implementation class '" + content + 259 "' is a not public, non abstract class"); 260 } 261 try { 263 contentClass.getConstructor(new Class [0]); 264 } catch (final NoSuchMethodException e) { 265 throw new ChainedInstantiationException( 266 null, 267 null, 268 "The component implementation class '" + content + 269 "' does not have a default public constructor"); 270 } 271 boolean hasDependencies = false; 273 ComponentType compType = (ComponentType)type; 274 InterfaceType[] itfTypes = compType.getFcInterfaceTypes(); 275 for (int i = 0; i < itfTypes.length; i++) { 276 InterfaceType itfType = itfTypes[i]; 277 if (itfType.isFcClientItf()) { 278 hasDependencies = true; 279 } 280 } 281 if (hasDependencies) { 282 Class bc; 283 try { 284 bc = loader.loadClass( 285 "org.objectweb.fractal.api.control.BindingController"); 286 } catch (ClassNotFoundException e) { 287 throw new ChainedInstantiationException( 288 e, null, "Cannot find the BindingController class"); 289 } 290 if (!bc.isAssignableFrom(contentClass)) { 291 throw new ChainedInstantiationException( 292 null, 293 null, 294 "The component implementation class '" + content + 295 "' must implement the BindingController interface, " + 296 "since the component type contains client interfaces"); 297 } 298 } 299 for (int i = 0; i < itfTypes.length; ++i) { 301 InterfaceType itfType = itfTypes[i]; 302 String itfName = itfType.getFcItfName(); 303 if (!itfType.isFcClientItf() && 304 !itfType.isFcOptionalItf() && 305 !(itfName.equals("component") ||itfName.endsWith("-controller"))) 306 { 307 Class itf; 308 try { 309 itf = loader.loadClass(itfType.getFcItfSignature()); 310 } catch (ClassNotFoundException e) { 311 throw new ChainedInstantiationException( 312 e, 313 null, 314 "Cannot find the Java interface '" + itfType.getFcItfSignature() + 315 "' declared in the component type"); 316 } 317 if (!itf.isAssignableFrom(contentClass)) { 318 throw new ChainedInstantiationException( 319 null, 320 null, 321 "The component implementation class '" + content + 322 "' does not implement the '" + itf.getName() + 323 "' server interface declared in the component type"); 324 } 325 } 326 } 327 } 328 329 333 341 342 public abstract void _super_initialize (Tree args) throws Exception ; 343 344 360 361 public abstract Component _super_newFcInstance ( 362 Type type, 363 Object controllerDesc, 364 Object contentDesc) throws InstantiationException ; 365 366 public abstract Object _super_getFcLoader (Object loader); 367 } 368 | Popular Tags |