private static TemplateRenderer tryToCompile(String source, Map<String, String> expressions) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException { ClassPool cp = ClassPool.getDefault(); CtClass sup = cp.get(Object.class.getCanonicalName()); CtClass cls = cp.makeClass("RapidoidTemplate" + ID_GEN.incrementAndGet(), sup); cls.addInterface(cp.get(TemplateRenderer.class.getCanonicalName())); cls.addConstructor(CtNewConstructor.defaultConstructor(cls)); for (Map.Entry<String, String> expr : expressions.entrySet()) { String fld = "private static final org.rapidoid.render.retriever.ValueRetriever %s = org.rapidoid.render.retriever.Retriever.of(%s);"; String retrieverId = retrieverId(expr.getKey()); String prop = expr.getValue(); String field = U.frmt(fld, retrieverId, prop); cls.addField(CtField.make(field, cls)); } CtClass[] params = {cp.get(RenderCtx.class.getCanonicalName())}; CtClass clsVoid = cp.get(void.class.getCanonicalName()); cls.addMethod( CtNewMethod.make(Modifier.PUBLIC, clsVoid, "render", params, new CtClass[0], source, cls)); return (TemplateRenderer) cls.toClass().newInstance(); }
protected void buildConstructor() throws CannotCompileException, NotFoundException { // Constructor(Class targetClass, Template[] templates) CtConstructor newCtCons = CtNewConstructor.make( new CtClass[] { director.getCtClass(Class.class.getName()), director.getCtClass(Template.class.getName() + "[]") }, new CtClass[0], tmplCtClass); tmplCtClass.addConstructor(newCtCons); }
private Invoker generateInvoker(final CtClass ctClass, final StringBuilder methodSrc) { try { ctClass.addMethod(CtMethod.make(methodSrc.toString(), ctClass)); ctClass.addConstructor(CtNewConstructor.defaultConstructor(ctClass)); final Class generatedClass = ctClass.toClass(); return (Invoker) generatedClass.newInstance(); } catch (CannotCompileException e) { throw new RuntimeException("Unable to compile generated source: " + methodSrc, e); } catch (InstantiationException e) { throw new RuntimeException("Unable to compile generated source: " + methodSrc, e); } catch (IllegalAccessException e) { throw new RuntimeException("Unable to compile generated source: " + methodSrc, e); } }
public void onWrite(ClassPool pool, String className) throws NotFoundException, CannotCompileException { CtClass cc = pool.get(className); try { if (isPersistent(className)) { CtClass base = cc.getSuperclass(); CtConstructor cons = new CtConstructor(constructorParams, cc); if (base.subclassOf(persistent) || base == object) { cons.setBody(null); cc.addConstructor(cons); if (base == object) { cc.setSuperclass(persistent); } } else { if (!isPersistent(base.getName())) { throw new NotFoundException( "Base class " + base.getName() + " was not declared as persistent"); } cons.setBody("super($0);"); cc.addConstructor(cons); } preprocessMethods(cc, true, true); if (base == persistent || base == object) { CtMethod m = new CtMethod(isRecursive, cc, null); m.setBody("return false;"); cc.addMethod(m); addSerializeMethods(cc, false); } else if (base.subtypeOf(serializable)) { addSerializeMethods(cc, true); } if ((cc.getModifiers() & Modifier.PRIVATE) == 0) { CtClass f = pool.makeClass(className + "LoadFactory"); f.addInterface(factory); CtMethod c = new CtMethod(create, f, null); c.setBody("return new " + className + "($1);"); f.addMethod(c); CtNewConstructor.defaultConstructor(f); } } else { preprocessMethods( cc, cc.subtypeOf(persistent) && cc != persistent, !className.startsWith("org.nachodb")); } } catch (Exception x) { x.printStackTrace(); } }
/** * @param pool The AOPClassPool to create the optimized invocation class in * @param makeInnerClass If true creates the new class as an inner class of className * @param outerClass The class to create the invocation class as an inner class of if * makeInnerClass==true * @param className The full class name (including package info) of the invocation class to be * created * @param superInvocation The super class of this invocation * @return The created invocation class */ public static CtClass makeInvocationClass( AOPClassPool pool, boolean makeInnerClass, CtClass outerClass, String className, CtClass superInvocation) throws CannotCompileException, NotFoundException { CtClass invocation = makeInvocationClassNoCtors(pool, makeInnerClass, outerClass, className, superInvocation); // Add the invocation constructor CtConstructor[] cons = superInvocation.getDeclaredConstructors(); for (int i = 0; i < cons.length; i++) { CtConstructor conTemplate = superInvocation.getDeclaredConstructors()[i]; CtConstructor icon = CtNewConstructor.make( conTemplate.getParameterTypes(), conTemplate.getExceptionTypes(), invocation); invocation.addConstructor(icon); } return invocation; }
@Override public void enhanceThisClass(ApplicationClass applicationClass) throws Exception { final CtClass ctClass = makeClass(applicationClass); if (ctClass.isInterface()) { return; } if (ctClass.getName().endsWith(".package")) { return; } // Add a default constructor if needed try { boolean hasDefaultConstructor = false; for (CtConstructor constructor : ctClass.getDeclaredConstructors()) { if (constructor.getParameterTypes().length == 0) { hasDefaultConstructor = true; break; } } if (!hasDefaultConstructor && !ctClass.isInterface()) { CtConstructor defaultConstructor = CtNewConstructor.make("public " + ctClass.getSimpleName() + "() {}", ctClass); ctClass.addConstructor(defaultConstructor); } } catch (Exception e) { Logger.error(e, "Error in PropertiesEnhancer"); throw new UnexpectedException("Error in PropertiesEnhancer", e); } if (isScala(applicationClass)) { // Temporary hack for Scala. Done. applicationClass.enhancedByteCode = ctClass.toBytecode(); ctClass.defrost(); return; } for (CtField ctField : ctClass.getDeclaredFields()) { try { if (isProperty(ctField)) { // Property name String propertyName = ctField.getName().substring(0, 1).toUpperCase() + ctField.getName().substring(1); String getter = "get" + propertyName; String setter = "set" + propertyName; try { CtMethod ctMethod = ctClass.getDeclaredMethod(getter); if (ctMethod.getParameterTypes().length > 0 || Modifier.isStatic(ctMethod.getModifiers())) { throw new NotFoundException("it's not a getter !"); } } catch (NotFoundException noGetter) { // Créé le getter String code = "public " + ctField.getType().getName() + " " + getter + "() { return this." + ctField.getName() + "; }"; CtMethod getMethod = CtMethod.make(code, ctClass); getMethod.setModifiers(getMethod.getModifiers() | AccessFlag.SYNTHETIC); ctClass.addMethod(getMethod); } if (!isFinal(ctField)) { try { CtMethod ctMethod = ctClass.getDeclaredMethod(setter); if (ctMethod.getParameterTypes().length != 1 || !ctMethod.getParameterTypes()[0].equals(ctField.getType()) || Modifier.isStatic(ctMethod.getModifiers())) { throw new NotFoundException("it's not a setter !"); } } catch (NotFoundException noSetter) { // Créé le setter CtMethod setMethod = CtMethod.make( "public void " + setter + "(" + ctField.getType().getName() + " value) { this." + ctField.getName() + " = value; }", ctClass); setMethod.setModifiers(setMethod.getModifiers() | AccessFlag.SYNTHETIC); ctClass.addMethod(setMethod); createAnnotation(getAnnotations(setMethod), PlayPropertyAccessor.class); } } } } catch (Exception e) { Logger.error(e, "Error in PropertiesEnhancer"); throw new UnexpectedException("Error in PropertiesEnhancer", e); } } // Add a default constructor if needed try { boolean hasDefaultConstructor = false; for (CtConstructor constructor : ctClass.getDeclaredConstructors()) { if (constructor.getParameterTypes().length == 0) { hasDefaultConstructor = true; break; } } if (!hasDefaultConstructor) { CtConstructor defaultConstructor = CtNewConstructor.defaultConstructor(ctClass); ctClass.addConstructor(defaultConstructor); } } catch (Exception e) { Logger.error(e, "Error in PropertiesEnhancer"); throw new UnexpectedException("Error in PropertiesEnhancer", e); } // Intercept all fields access for (final CtBehavior ctMethod : ctClass.getDeclaredBehaviors()) { ctMethod.instrument( new ExprEditor() { @Override public void edit(FieldAccess fieldAccess) throws CannotCompileException { try { // Acces à une property ? if (isProperty(fieldAccess.getField())) { // TODO : vérifier que c'est bien un champ d'une classe de l'application // (fieldAccess.getClassName()) // Si c'est un getter ou un setter String propertyName = null; if (fieldAccess .getField() .getDeclaringClass() .equals(ctMethod.getDeclaringClass()) || ctMethod .getDeclaringClass() .subclassOf(fieldAccess.getField().getDeclaringClass())) { if ((ctMethod.getName().startsWith("get") || (!isFinal(fieldAccess.getField()) && ctMethod.getName().startsWith("set"))) && ctMethod.getName().length() > 3) { propertyName = ctMethod.getName().substring(3); propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1); } } // On n'intercepte pas le getter de sa propre property if (propertyName == null || !propertyName.equals(fieldAccess.getFieldName())) { String invocationPoint = ctClass.getName() + "." + ctMethod.getName() + ", line " + fieldAccess.getLineNumber(); if (fieldAccess.isReader()) { // Réécris l'accés en lecture à la property fieldAccess.replace( "$_ = ($r)play.classloading.enhancers.PropertiesEnhancer.FieldAccessor.invokeReadProperty($0, \"" + fieldAccess.getFieldName() + "\", \"" + fieldAccess.getClassName() + "\", \"" + invocationPoint + "\");"); } else if (!isFinal(fieldAccess.getField()) && fieldAccess.isWriter()) { // Réécris l'accés en ecriture à la property fieldAccess.replace( "play.classloading.enhancers.PropertiesEnhancer.FieldAccessor.invokeWriteProperty($0, \"" + fieldAccess.getFieldName() + "\", " + fieldAccess.getField().getType().getName() + ".class, $1, \"" + fieldAccess.getClassName() + "\", \"" + invocationPoint + "\");"); } } } } catch (Exception e) { throw new UnexpectedException("Error in PropertiesEnhancer", e); } } }); } // Done. applicationClass.enhancedByteCode = ctClass.toBytecode(); ctClass.defrost(); }
/** * Creates a map of concrete json request handler invokers keyed by <b><code> * <service-name>/<op-name></code></b>. * * @param handlerInstance The request handler instance to generate invokers for * @return the map of generated invokers */ public static Map<String, Map<String, AbstractJSONRequestHandlerInvoker>> createInvokers( Object handlerInstance) { if (handlerInstance == null) throw new IllegalArgumentException("The passed handlerInstance was null"); Map<String, AbstractJSONRequestHandlerInvoker> subInvokerMap = new HashMap<String, AbstractJSONRequestHandlerInvoker>(); Map<String, Map<String, AbstractJSONRequestHandlerInvoker>> invokerMap = invokerCache.get(handlerInstance.getClass()); if (invokerMap != null) { LOG.info("Found Cached Invokers for [{}]", handlerInstance.getClass().getName()); return invokerMap; } invokerMap = new HashMap<String, Map<String, AbstractJSONRequestHandlerInvoker>>(1); LOG.info("Generating Invokers for [{}]", handlerInstance.getClass().getName()); JSONRequestService svc = handlerInstance.getClass().getAnnotation(JSONRequestService.class); final String invokerServiceKey = svc.name(); final String invokerServiceDescription = svc.description(); invokerMap.put(invokerServiceKey, subInvokerMap); ClassPool cp = new ClassPool(); cp.appendClassPath(new ClassClassPath(handlerInstance.getClass())); cp.appendClassPath(new ClassClassPath(AbstractJSONRequestHandlerInvoker.class)); cp.importPackage(handlerInstance.getClass().getPackage().getName()); Set<ClassLoader> classPathsAdded = new HashSet<ClassLoader>(); Set<String> packagesImported = new HashSet<String>(); try { final CtClass jsonRequestCtClass = cp.get(JSONRequest.class.getName()); final CtClass parent = cp.get(AbstractJSONRequestHandlerInvoker.class.getName()); CtClass targetClass = cp.get(handlerInstance.getClass().getName()); Collection<Method> methods = getTargetMethods(handlerInstance.getClass()); for (Method m : methods) { final JSONRequestHandler jsonHandler = m.getAnnotation(JSONRequestHandler.class); final String opName = jsonHandler.name(); final String opDescription = jsonHandler.description(); final RequestType opType = jsonHandler.type(); int targetMethodHashCode = m.toGenericString().hashCode(); final String className = String.format( "%s-%s%s-%s-%s", handlerInstance.getClass().getName(), invokerServiceKey, opName, "ServiceInvoker", targetMethodHashCode); final CtClass invokerClass = cp.makeClass(className, parent); CtField ctf = new CtField(targetClass, "typedTarget", invokerClass); ctf.setModifiers(ctf.getModifiers() | Modifier.FINAL); invokerClass.addField(ctf); for (CtConstructor parentCtor : parent.getConstructors()) { CtConstructor invokerCtor = CtNewConstructor.copy(parentCtor, invokerClass, null); invokerCtor.setBody( "{ super($$); typedTarget = (" + handlerInstance.getClass().getName() + ")$1; }"); invokerClass.addConstructor(invokerCtor); } CtMethod invokerMethod = CtNewMethod.copy( parent.getDeclaredMethod("doInvoke", new CtClass[] {jsonRequestCtClass}), invokerClass, null); StringBuilder b = new StringBuilder("{this.typedTarget.").append(m.getName()).append("($1"); final Class<?>[] ptypes = m.getParameterTypes(); final int remainingParamCount = ptypes.length - 1; // Set<Class<?>> classPathsAdded = new HashSet<Class<?>>(); // Set<String> packagesImported = new HashSet<String>(); if (remainingParamCount > 0) { for (int i = 0; i < remainingParamCount; i++) { final Class<?> type = ptypes[i + 1]; if (type.getName().contains("UniqueIdType")) { System.err.println("Comin Up...."); } if (type.isPrimitive()) { b.append(", (").append(type.getName()).append(") null"); } else { if (classPathsAdded.add(type.getClassLoader())) { cp.appendClassPath(new LoaderClassPath(type.getClassLoader())); } try { Package p = type.getPackage(); if (p == null) { if (type.isArray()) { if (!type.getComponentType().isPrimitive()) { p = type.getComponentType().getPackage(); } } } if (type.isEnum()) { final String f = type.getEnclosingClass().getName() + "." + type.getSimpleName(); b.append(", (").append(f).append(") null"); String pack = type.getEnclosingClass().getPackage().getName(); if (packagesImported.add(pack)) { cp.importPackage(pack); } continue; } if (p != null) { if (packagesImported.add(p.getName())) { cp.importPackage(p.getName()); } } } catch (Exception ex) { ex.printStackTrace(System.err); } b.append(", (").append(type.getSimpleName()).append(") null"); } } } b.append(");}"); System.out.println("[" + m.getName() + "]: [" + b.toString() + "]"); // invokerMethod.setBody("{this.typedTarget." + m.getName() + "($1);}"); invokerMethod.setBody(b.toString()); invokerMethod.setModifiers(invokerMethod.getModifiers() & ~Modifier.ABSTRACT); invokerClass.addMethod(invokerMethod); // invokerClass.writeFile(System.getProperty("java.io.tmpdir") + File.separator + // "jsoninvokers"); Class<?> clazz = invokerClass.toClass( handlerInstance.getClass().getClassLoader(), handlerInstance.getClass().getProtectionDomain()); Constructor<?> ctor = clazz.getDeclaredConstructor( Object.class, String.class, String.class, String.class, String.class, RequestType.class); AbstractJSONRequestHandlerInvoker invokerInstance = (AbstractJSONRequestHandlerInvoker) ctor.newInstance( handlerInstance, invokerServiceKey, invokerServiceDescription, opName, opDescription, opType); subInvokerMap.put(opName, invokerInstance); } invokerCache.put(handlerInstance.getClass(), invokerMap); return invokerMap; } catch (Exception ex) { LOG.error( "Failed to create RequestHandlerInvoker for [{}]", handlerInstance.getClass().getName(), ex); throw new RuntimeException( "Failed to create RequestHandlerInvoker [" + handlerInstance.getClass().getName() + "]", ex); } }
@Override public void enhanceThisClass(ApplicationClass applicationClass) throws Exception { CtClass ctClass = makeClass(applicationClass); String entityName = ctClass.getName(); Logger.debug("Enhance class " + entityName); // Only enhance Neo4jModel classes. if (!ctClass.subtypeOf(classPool.get("play.modules.neo4j.model.Neo4jModel"))) { return; } // Add a default constructor if needed try { for (CtConstructor constructor : ctClass.getDeclaredConstructors()) { if (constructor.getParameterTypes().length == 0) { ctClass.removeConstructor(constructor); } if (constructor.getParameterTypes().length == 1 && constructor.getParameterTypes()[0].getClass().isInstance(Node.class)) { ctClass.removeConstructor(constructor); } } if (!ctClass.isInterface()) { Logger.debug("Adding default constructor"); CtConstructor defaultConstructor = CtNewConstructor.make("public " + ctClass.getSimpleName() + "() { super();}", ctClass); ctClass.addConstructor(defaultConstructor); } } catch (Exception e) { Logger.error(e, "Error in PropertiesEnhancer"); throw new UnexpectedException("Error in PropertiesEnhancer", e); } // for all field, we add getter / setter for (CtField ctField : ctClass.getDeclaredFields()) { try { // Property name String propertyName = ctField.getName().substring(0, 1).toUpperCase() + ctField.getName().substring(1); String getter = "get" + propertyName; String setter = "set" + propertyName; Logger.debug("Field " + ctField.getName() + " is a property ?"); if (isProperty(ctField)) { Logger.debug("true"); // ~~~~~~~~~ // GETTER // ~~~~~~~ try { CtMethod ctMethod = ctClass.getDeclaredMethod(getter); if (!ctMethod.getName().equalsIgnoreCase("getShouldBeSave")) { ctClass.removeMethod(ctMethod); throw new NotFoundException("it's not a true getter !"); } } catch (NotFoundException noGetter) { // create getter Logger.debug("Adding getter " + getter + " for class " + entityName); // @formatter:off String code = "public " + ctField.getType().getName() + " " + getter + "() {" + "if(this.shouldBeSave == Boolean.FALSE && this.node != null){" + "return ((" + ctField.getType().getName() + ") play.modules.neo4j.util.Binder.bindFromNeo4jFormat(this.node.getProperty(\"" + ctField.getName() + "\", null)," + ctField.getType().getName() + ".class ));" + "}else{" + "return " + ctField.getName() + ";" + "}" + "}"; // @formatter:on Logger.debug(code); CtMethod getMethod = CtMethod.make(code, ctClass); ctClass.addMethod(getMethod); } // ~~~~~~~~~ // SETTER // ~~~~~~~ try { CtMethod ctMethod = ctClass.getDeclaredMethod(setter); if (ctMethod.getParameterTypes().length != 1 || !ctMethod.getParameterTypes()[0].equals(ctField.getType()) || Modifier.isStatic(ctMethod.getModifiers()) || hasPlayPropertiesAccessorAnnotation(ctMethod)) { if (hasPlayPropertiesAccessorAnnotation(ctMethod)) { ctClass.removeMethod(ctMethod); } throw new NotFoundException("it's not a true setter !"); } } catch (NotFoundException noSetter) { // create setter Logger.debug("Adding setter " + setter + " for class " + entityName); // @formatter:off String code = "public void " + setter + "(" + ctField.getType().getName() + " value) { " + "this." + ctField.getName() + " = value;" + "this.shouldBeSave = Boolean.TRUE;" + "}"; // formatter:on CtMethod setMethod = CtMethod.make(code, ctClass); Logger.debug(code); ctClass.addMethod(setMethod); } } else { // ~~~~~~~~~ // GETTER for neo4j relation property // ~~~~~~~ if (hasNeo4jRelationAnnotation(ctField)) { // test for related annotation Neo4jRelatedTo relatedTo = getRelatedAnnotation(ctField); if (relatedTo != null) { CtMethod ctMethod = ctClass.getDeclaredMethod(getter); ctClass.removeMethod(ctMethod); String code; if (relatedTo.lazy()) { // @formatter:off code = "public " + ctField.getType().getName() + " " + getter + "() {" + "if(this." + ctField.getName() + " == null){" + "java.lang.reflect.Field field = this.getClass().getField(\"" + ctField.getName() + "\");" + "this." + ctField.getName() + "=play.modules.neo4j.relationship.Neo4jRelationFactory.getModelsFromRelation(\"" + relatedTo.value() + "\", \"" + relatedTo.direction() + "\", field, this.node);" + "}" + "return " + ctField.getName() + ";" + "}"; // @formatter:on } else { // @formatter:off code = "public " + ctField.getType().getName() + " " + getter + "() {" + "return " + ctField.getName() + ";" + "}"; // @formatter:on } Logger.debug(code); CtMethod method = CtMethod.make(code, ctClass); ctClass.addMethod(method); } // test for unique relation annotation Neo4jUniqueRelation uniqueRelation = getUniqueRelationAnnotation(ctField); if (uniqueRelation != null) { CtMethod ctMethod = ctClass.getDeclaredMethod(getter); ctClass.removeMethod(ctMethod); String code; // @formatter:off code = "public " + ctField.getType().getName() + " " + getter + "() {" + "return (" + ctField.getType().getName() + ")" + ctField.getName() + ";" + "}"; // @formatter:on Logger.debug(code); CtMethod method = CtMethod.make(code, ctClass); ctClass.addMethod(method); } } } } catch (Exception e) { Logger.error(e, "Error in PropertiesEnhancer"); throw new UnexpectedException("Error in PropertiesEnhancer", e); } } // Adding getByKey() method Logger.debug("Adding getByKey() method for class " + entityName); // @formatter:off String codeGetByKey = "public static play.modules.neo4j.model.Neo4jModel getByKey(Long key) throws play.modules.neo4j.exception.Neo4jException {" + "return (" + entityName + ")_getByKey(key, \"" + entityName + "\");" + "}"; // @formatter:on Logger.debug(codeGetByKey); CtMethod getByKeyMethod = CtMethod.make(codeGetByKey, ctClass); ctClass.addMethod(getByKeyMethod); // ~~~~~~~~~~~~~~~ // Adding findAll() method // @formatter:off String codeFindAll = "public static java.util.List findAll() {" + "return " + entityName + "._findAll(\"" + entityName + "\");" + "}"; // @formatter:on Logger.debug(codeFindAll); CtMethod findAllMethod = CtMethod.make(codeFindAll, ctClass); ctClass.addMethod(findAllMethod); // ~~~~~~~~~~~~~~~ // Adding queryIndex() method // @formatter:off String queryIndex = "public static java.util.List queryIndex(String indexname, String query) {" + "return " + entityName + "._queryIndex(indexname, query);" + "}"; // @formatter:on Logger.debug(queryIndex); CtMethod queryIndexMethod = CtMethod.make(queryIndex, ctClass); ctClass.addMethod(queryIndexMethod); // Done. applicationClass.enhancedByteCode = ctClass.toBytecode(); ctClass.defrost(); }
public ClazzInfo classProcessing(String clazzName) throws NotFoundException, CannotCompileException { ClassPool classPool = ClassPool.getDefault(); CtClass cz = classPool.get(clazzName); classPool.importPackage(clazzName); // 继承 classPool.importPackage("java.lang.reflect.Method"); // 添加反射引用 CtClass newClass = classPool.makeClass(clazzName + "$MC_IMPL"); // 新建代理类 newClass.setSuperclass(cz); // 继承 // 构造块 CtConstructor tempC; CtConstructor[] ctConstructors = cz.getDeclaredConstructors(); newClass.addConstructor(CtNewConstructor.defaultConstructor(newClass)); for (CtConstructor c : ctConstructors) { try { tempC = CtNewConstructor.copy(c, newClass, null); tempC.setBody("{super($$);}"); newClass.addConstructor(tempC); } catch (Exception e) { // e.printStackTrace(); } } // 字段块 // CtField[] ctFields = cz.getDeclaredFields(); // for (CtField f : ctFields) // System.out.println(f.getFieldInfo().getConstantValue()); // 方法块 CtMethod[] ctMethods = cz.getDeclaredMethods(); CtMethod tempM; // 复制方法名 Map<String, Method> tempMethod = new HashMap<String, Method>(); for (CtMethod m : ctMethods) { tempMethod.put( String.format( "%s %s %s(%s);", Modifier.toString(m.getModifiers()), m.getReturnType().getName(), m.getName(), Util.getParameterTypes(m.getParameterTypes())), null); // System.err.println(String.format("%s %s %s(%s);", Modifier.toString(m.getModifiers()), // m.getReturnType().getName(), m.getName(), Util.getParameterTypes(m.getParameterTypes()))); tempM = CtNewMethod.copy(m, newClass, null); if ("void".equals(tempM.getReturnType().getName())) tempM.setBody("{super." + tempM.getName() + "($$);}"); else tempM.setBody("{ return super." + tempM.getName() + "($$);}"); // CtNewMethod.make(src, declaring, delegateObj, delegateMethod) // 方法修改 // if (m.getName().equals("x")) { // //tempM.setBody("{$proceed($$);}", "this", "mba"); // //tempM.setBody("{n nn = new n();" + "Method a = n.class.getDeclaredMethod(\"a\", new // Class[] { Integer.TYPE });" + "a.invoke(nn, new Object[] { Integer.valueOf(1) });}"); // tempM.setBody("{Method a = n.class.getDeclaredMethod(\"axx\", new Class[] { Integer.TYPE // });}"); // } newClass.addMethod(tempM); } // 测试输出 try { newClass.writeFile("D:/Desktop"); } catch (IOException e) { e.printStackTrace(); } // Class clazz = newClass.toClass(); // System.out.println(clazz.getCanonicalName()); // DefaultCachePoolFactory.newInstance().addNFloop4Map(new ClazzInfo(clazz, tempMethod), // DefaultPool.NORNAL_BEAN, clazz.getCanonicalName()); // return clazz; return new ClazzInfo(newClass.toClass(), tempMethod); }
private static CtClass makeExpressionClass( Source.Staged staged, String superClassName, String memberClassName) { // Here we make the language class accessible! if (!Modifier.isPublic(staged.getLanguage().getModifiers())) { staged.getLanguage().setModifiers(Modifier.setPublic(staged.getLanguage().getModifiers())); } CtClass clazz; try { ClassPool cp = ClassPool.getDefault(); CtClass superClass = cp.getCtClass(superClassName); clazz = cp.makeClass( superClass.getName() + "$Generated" + id + "$" + staged.getMember().getDeclaringClass().getName().replace(".", "_") + "$" + staged.getMember().getName().replace(".", "_"), superClass); id++; // Make accepted language static fields HashMap<CtClass, String> acceptedLanguageMap = new HashMap<>(); for (Use.Argument a : staged.getArguments()) { for (CtClass l : a.getAcceptedLanguages()) { if (!acceptedLanguageMap.containsKey(l) && !l.equals(Util.LANGUAGE_CLASS)) { String lName = "acceptedLanguage" + acceptedLanguageMap.size(); int lPersistentId = Dispatcher.addPersistent(l); CtField lField = CtField.make( "private static final " + CtClass.class.getName() + " " + lName + " = (" + CtClass.class.getName() + ") " + Util.DISPATCHER_CLASS.getName() + ".removePersistent(" + lPersistentId + ");", clazz); clazz.addField(lField); acceptedLanguageMap.put(l, lName); } } } // Make language field String languageName = "language"; int languagePersistentId = Dispatcher.addPersistent(staged.getLanguage()); CtField languageField = CtField.make( "private static final " + CtClass.class.getName() + " " + languageName + " = (" + CtClass.class.getName() + ") " + Util.DISPATCHER_CLASS.getName() + ".removePersistent(" + languagePersistentId + ");", clazz); clazz.addField(languageField); // Make member field String memberName = "member"; int memberPersistentId = Dispatcher.addPersistent(staged.getMember()); CtField memberField = CtField.make( "private static final " + memberClassName + " " + memberName + " = (" + memberClassName + ")" + Util.DISPATCHER_CLASS.getName() + ".removePersistent(" + memberPersistentId + ");", clazz); clazz.addField(memberField); // Make constructor String constructorSource = "private constructor(" + Util.EXPRESSION_CLASS.getName() + "[] arguments, " + Util.STATIC_INFO_CLASS.getName() + " staticInfo, " + Util.CLOSURE_HOLDER_CLASS.getName() + " closureHolder) {\n" + " super(arguments, staticInfo, closureHolder);\n" + "}"; CtConstructor constructor = CtNewConstructor.make(constructorSource, clazz); clazz.addConstructor(constructor); // Make factory-like invoke methods ImmutableList<Use.Argument> args = staged.getArguments(); StringBuilder invokeSource = new StringBuilder(); if (staged.isStrict() || Util.isCarrier(staged.getType())) { invokeSource.append( "public static " + staged.getType().getCtClass().getName() + " invoke("); } else if (staged.getType().isReference()) { invokeSource.append("public static " + Util.LOCAL_CARRIER_CLASS.getName() + " invoke("); } else { invokeSource.append("public static " + clazz.getName() + " invoke("); } if (staged.getArguments().size() > 253) { invokeSource.append("Object[] objectArguments, "); if (!staged.getStaticInfoElements().isEmpty()) { invokeSource.append(Util.STATIC_INFO_CLASS.getName() + " staticInfo, "); } invokeSource.append(Util.CLOSURE_HOLDER_CLASS.getName() + " closureHolder) {\n"); for (int i = 0; i < args.size(); i++) { if (Util.isGlobalCarrier(args.get(i).getType())) { invokeSource .append(" ") .append(Util.GLOBAL_CARRIER_CLASS.getName()) .append(" argument") .append(i) .append(" = (") .append(Util.GLOBAL_CARRIER_CLASS.getName()) .append(") objectArguments[") .append(i) .append("];\n"); } else if (Util.isLocalCarrier(args.get(i).getType()) || (args.get(i).getType().isReference() && !Util.couldBeGlobalCarrier(args.get(i).getType()))) { invokeSource .append(" ") .append(Util.LOCAL_CARRIER_CLASS.getName()) .append(" argument") .append(i) .append(" = (") .append(Util.LOCAL_CARRIER_CLASS.getName()) .append(") objectArguments[") .append(i) .append("];\n"); } else if (args.get(i).getType().isReference()) { invokeSource .append(" ") .append(Type.OBJECT.getCtClass().getName()) .append(" argument") .append(i) .append(" = objectArguments[") .append(i) .append("];\n"); } else { invokeSource .append(" ") .append(Util.EXPRESSION_CLASS.getName()) .append(" argument") .append(i) .append(" = (") .append(Util.EXPRESSION_CLASS.getName()) .append(") objectArguments[") .append(i) .append("];\n"); } } } else { for (int i = 0; i < args.size(); i++) { if (Util.isGlobalCarrier(args.get(i).getType())) { invokeSource.append(Util.GLOBAL_CARRIER_CLASS.getName()).append(" argument").append(i); } else if (Util.isLocalCarrier(args.get(i).getType()) || (args.get(i).getType().isReference() && !Util.couldBeGlobalCarrier(args.get(i).getType()))) { invokeSource.append(Util.LOCAL_CARRIER_CLASS.getName()).append(" argument").append(i); } else if (args.get(i).getType().isReference()) { invokeSource.append(Type.OBJECT.getCtClass().getName()).append(" argument").append(i); } else { invokeSource.append(Util.EXPRESSION_CLASS.getName()).append(" argument").append(i); } invokeSource.append(", "); } if (!staged.getStaticInfoElements().isEmpty()) { invokeSource.append(Util.STATIC_INFO_CLASS.getName() + " staticInfo, "); } invokeSource.append(Util.CLOSURE_HOLDER_CLASS.getName() + " closureHolder) {\n"); } invokeSource.append( " " + Util.EXPRESSION_CLASS.getName() + " payload;\n" + " " + Util.EXPRESSION_CLASS.getName() + "[] arguments = new " + Util.EXPRESSION_CLASS.getName() + "[" + args.size() + "];\n"); for (int i = 0; i < args.size(); i++) { if (Util.isGlobalCarrier(args.get(i).getType())) { invokeSource.append( " payload = " + Util.DISPATCHER_CLASS.getName() + ".unloadGlobalCarrierChecked(argument" + i + ");\n" + " if (!(" + generateLanguageAcceptCheck( "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap) + ")) {\n" + " arguments[" + i + "] = " + Util.DISPATCHER_CLASS.getName() + ".selfLiftGlobalCarrier(argument" + i + ");\n" + " } else {\n" + " arguments[" + i + "] = payload;\n" + " }\n"); } else if (Util.isLocalCarrier(args.get(i).getType()) || (args.get(i).getType().isReference() && !Util.couldBeGlobalCarrier(args.get(i).getType()))) { invokeSource.append( " payload = " + Util.DISPATCHER_CLASS.getName() + ".unloadLocalCarrierChecked(argument" + i + ");\n" + " if (" + generateLanguageAcceptCheck( "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap) + ") {\n" + " arguments[" + i + "] = payload.getRaw();\n" + " } else {\n" + " payload.evaluate();\n" // This handles the weird case when the materialized argument could be globally // carried and might need unloading and checking // We know that it is an ObjectValue instance + " " + Util.EXPRESSION_CLASS.getName() + " value = payload.asValueIfEvaluated();\n" + " Object obj = value.materializeAsObject(); \n" + " if (obj instanceof " + Util.GLOBAL_CARRIER_CLASS.getName() + ") {\n" + " payload = " + Util.DISPATCHER_CLASS.getName() + ".unloadGlobalCarrier((" + Util.GLOBAL_CARRIER_CLASS.getName() + ") obj);\n" + " if (payload == null || !(" + generateLanguageAcceptCheck( "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap) + ")) {\n" + " arguments[" + i + "] = value;\n" + " } else {\n" + " arguments[" + i + "] = payload;\n" + " }\n" + " } else {\n" + " arguments[" + i + "] = value;\n" + " }\n" + " }\n"); } else if (args.get(i).getType().isReference()) { invokeSource.append( " if (argument" + i + " instanceof " + Util.LOCAL_CARRIER_CLASS.getName() + ") {\n" + " payload = " + Util.DISPATCHER_CLASS.getName() + ".unloadLocalCarrierChecked((" + Util.LOCAL_CARRIER_CLASS.getName() + ") argument" + i + ");\n" + " if (" + generateLanguageAcceptCheck( "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap) + ") {\n" + " arguments[" + i + "] = payload.getRaw();\n" + " } else {\n" + " payload.evaluate();\n" // This handles the weird case when the materialized argument could be globally // carried and might need unloading and checking // We know that it is an ObjectValue instance + " " + Util.EXPRESSION_CLASS.getName() + " value = payload.asValueIfEvaluated();\n" + " Object obj = value.materializeAsObject(); \n" + " if (obj instanceof " + Util.GLOBAL_CARRIER_CLASS.getName() + ") {\n" + " payload = " + Util.DISPATCHER_CLASS.getName() + ".unloadGlobalCarrier((" + Util.GLOBAL_CARRIER_CLASS.getName() + ") obj);\n" + " if (payload == null || !(" + generateLanguageAcceptCheck( "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap) + ")) {\n" + " arguments[" + i + "] = value;\n" + " } else {\n" + " arguments[" + i + "] = payload;\n" + " }\n" + " } else {\n" + " arguments[" + i + "] = value;\n" + " }\n" + " }\n" + " } else if (argument" + i + " instanceof " + Util.GLOBAL_CARRIER_CLASS.getName() + ") {\n" + " payload = " + Util.DISPATCHER_CLASS.getName() + ".unloadGlobalCarrierChecked((" + Util.GLOBAL_CARRIER_CLASS.getName() + ") argument" + i + ");\n" + " if (!(" + generateLanguageAcceptCheck( "payload", args.get(i).getAcceptedLanguages(), acceptedLanguageMap) + ")) {\n" + " arguments[" + i + "] = " + Util.DISPATCHER_CLASS.getName() + ".selfLiftGlobalCarrier((" + Util.GLOBAL_CARRIER_CLASS.getName() + ") argument" + i + ");\n" + " } else {\n" + " arguments[" + i + "] = payload;\n" + " }\n" + " } else {\n" + " arguments[" + i + "] = " + Util.DISPATCHER_CLASS.getName() + "." + Util.getLiftMethodName(Type.OBJECT) + "(argument" + i + ");\n" + " }\n"); } else { invokeSource.append( " if (" + generateLanguageAcceptCheck( "argument" + i, args.get(i).getAcceptedLanguages(), acceptedLanguageMap) + ") {\n" + " arguments[" + i + "] = argument" + i + generateConversionSuffix(args.get(i).getType()) + ".getRaw();\n" + " } else {\n" + " argument" + i + ".evaluate();\n" + " arguments[" + i + "] = argument" + i + ".asValueIfEvaluated();\n" + " }\n"); } } String construction; if (!staged.getStaticInfoElements().isEmpty()) { construction = "new " + clazz.getName() + "(arguments, staticInfo, closureHolder)"; } else { construction = "new " + clazz.getName() + "(arguments, null, closureHolder)"; } if (staged.isStrict()) { Type type = staged.getType(); if (type.isReference()) { invokeSource.append( " return (" + type.getCtClass().getName() + ") (" + construction + ").materializeAsObject();\n"); } else if (type.equals(Type.BOOLEAN)) { invokeSource.append(" return (" + construction + ").materializeAsBoolean();\n"); } else if (type.equals(Type.INT)) { invokeSource.append(" return (" + construction + ").materializeAsInteger();\n"); } else if (type.equals(Type.LONG)) { invokeSource.append(" return (" + construction + ").materializeAsLong();\n"); } else if (type.equals(Type.FLOAT)) { invokeSource.append(" return (" + construction + ").materializeAsFloat();\n"); } else if (type.equals(Type.DOUBLE)) { invokeSource.append(" return (" + construction + ").materializeAsDouble();\n"); } else if (type.equals(Type.BYTE)) { invokeSource.append(" return (" + construction + ").materializeAsByte();\n"); } else if (type.equals(Type.CHAR)) { invokeSource.append(" return (" + construction + ").materializeAsCharacter();\n"); } else if (type.equals(Type.SHORT)) { invokeSource.append(" return (" + construction + ").materializeAsShort();\n"); } else if (type.equals(Type.VOID)) { invokeSource.append(" return (" + construction + ").evaluate();\n"); } } else { if (Util.isGlobalCarrier(staged.getType())) { if (staged.getType().getCtClass().equals(Util.GLOBAL_CARRIER_CLASS)) { invokeSource.append( " return new " + Util.GLOBAL_CARRIER_CLASS.getName() + "(" + construction + ");\n"); } else { CarrierTransformer.transformCarrierChecked(staged.getType().getCtClass()); invokeSource.append( " return new " + staged.getType().getCtClass().getName() + "((" + Util.DISAMBIGUATION_PARAMETER_CLASS.getName() + ") null, " + construction + ");\n"); } } else if (Util.isLocalCarrier(staged.getType())) { if (staged.getType().getCtClass().equals(Util.LOCAL_CARRIER_CLASS)) { invokeSource.append( " return new " + Util.LOCAL_CARRIER_CLASS.getName() + "(" + construction + ");\n"); } else { CarrierTransformer.transformCarrierChecked(staged.getType().getCtClass()); invokeSource.append( " return new " + staged.getType().getCtClass().getName() + "((" + Util.DISAMBIGUATION_PARAMETER_CLASS.getName() + ") null, " + construction + ");\n"); } } else if (staged.getType().isReference()) { invokeSource.append( " return new " + Util.LOCAL_CARRIER_CLASS.getName() + "(" + construction + ");\n"); } else { invokeSource.append(" return " + construction + ";\n"); } } invokeSource.append("}"); CtMethod invoke = CtMethod.make(invokeSource.toString(), clazz); clazz.addMethod(invoke); // Make isomorphic hash code method String isomorphicHashCodeSource = "int isomorphicHashCode() {\n" + " if (!$0.isomorphicHashCodeHasBeenCalculated) {\n" + " super.isomorphicHashCode(" + staged.getMember().hashCode() + ");\n" + " }" + " return $0.isomorphicHashCode;" + "}"; CtMethod isomorphicHashCode = CtMethod.make(isomorphicHashCodeSource, clazz); clazz.addMethod(isomorphicHashCode); // Make isomorphism check method String isIsomorphicToSource = "boolean isIsomorphicTo(java.util.IdentityHashMap identityMap, " + Util.EXPRESSION_CLASS.getName() + " expression) {\n" + " if (!(expression instanceof " + clazz.getName() + ")) { return false; }\n" + " return super.isIsomorphicTo(identityMap, expression);\n" + "}"; CtMethod isIsomorphicTo = CtMethod.make(isIsomorphicToSource, clazz); clazz.addMethod(isIsomorphicTo); // Make cache clone (with empty leaves to save memory) creation method String cacheCloneSource = Util.EXPRESSION_CLASS.getName() + " cacheClone(java.util.IdentityHashMap identityMap) {\n" + " " + Util.EXPRESSION_CLASS.getName() + " e = (" + Util.EXPRESSION_CLASS.getName() + ") identityMap.get(this);\n" + " if (e != null) {\n" + " return e;\n" + " } else {\n" + " " + Util.EXPRESSION_CLASS.getName() + "[] clonedArguments = super.cacheCloneArguments(identityMap);\n" + " if (clonedArguments != null) {\n" + " " + clazz.getName() + " s = new " + clazz.getName() + "(clonedArguments, $0.staticInfo, null);\n" + " s.isomorphicHashCode = $0.isomorphicHashCode();\n" + " s.isomorphicHashCodeHasBeenCalculated = true;\n" + " identityMap.put(this, s);\n" + " return s;\n" + " } else {\n" + " identityMap.put(this, this);\n" + " return this;\n" + " }\n" + " }\n" + "}"; CtMethod cacheClone = CtMethod.make(cacheCloneSource, clazz); clazz.addMethod(cacheClone); // Make language acceptance check method String isAcceptedBySource = "boolean isAcceptedBy(" + CtClass.class.getName() + " language) { return $0.language.equals(language); }"; CtMethod isAcceptedBy = CtMethod.make(isAcceptedBySource, clazz); clazz.addMethod(isAcceptedBy); // Make polymorphic member retrieval method String getMemberSource = "public " + memberClassName + " getMember() { return $0." + memberName + "; }"; CtMethod getMember = CtMethod.make(getMemberSource, clazz); clazz.addMethod(getMember); // Make evaluation method Class<?> closureInterface = getClosureInterface(staged.getType()); String evaluateSource; if (Util.isGlobalCarrier(staged.getType()) && !staged.isStrict()) { evaluateSource = "public void evaluate() { throw new UnsupportedOperationException(); }"; } else { evaluateSource = "public void evaluate() {\n" + " if ($0.value != null) { return; }\n" + " " + closureInterface.getName() + " closure;\n" + " " + Util.ENVIRONMENT_CLASS.getName() + " environment;\n" + " if ($0.closureHolder == null) {\n" + " " + Util.CLOSURE_HOLDER_CLASS.getName() + " cachedClosureHolder = " + GlobalCache.class.getName() + ".getCachedClosureHolder($0);\n" + " if (cachedClosureHolder == null) {\n" + " " + Util.BINDER_CLASS.getName() + " binder = new " + Util.BINDER_CLASS.getName() + "($0);\n" + " closure = " + staged.getLanguage().getName() + ".make" + closureInterface.getSimpleName() + "($0, binder, false);\n" + " environment = new " + Util.ENVIRONMENT_CLASS.getName() + "($0, binder.getBoundCount());\n" + " if (!binder.inspectionOccurred()) {\n" + " " + GlobalCache.class.getName() + ".cache($0, closure, binder.getBoundCount());\n" + " }\n" + " } else {\n" + " closure = (" + closureInterface.getName() + ") cachedClosureHolder.getClosure();\n" + " environment = new " + Util.ENVIRONMENT_CLASS.getName() + "($0, cachedClosureHolder.getEnvironmentSize());\n" + " }\n" + " } else {\n" + " closure = (" + closureInterface.getName() + ") $0.closureHolder.getClosure();\n" + " if (closure == null) {\n" + " " + Util.CLOSURE_HOLDER_CLASS.getName() + " cachedClosureHolder = " + GlobalCache.class.getName() + ".getCachedClosureHolder($0);\n" + " if (cachedClosureHolder == null) {\n" + " " + Util.BINDER_CLASS.getName() + " binder = new " + Util.BINDER_CLASS.getName() + "($0);\n" + " closure = " + staged.getLanguage().getName() + ".make" + closureInterface.getSimpleName() + "($0, binder, $0.closureHolder.isPermanent());\n" + " environment = new " + Util.ENVIRONMENT_CLASS.getName() + "($0, binder.getBoundCount());\n" + " if (!binder.inspectionOccurred()) {\n" + " $0.closureHolder.set(closure, binder.getBoundCount());\n" + " " + GlobalCache.class.getName() + ".cache($0, closure, binder.getBoundCount());\n" + " }\n" + " } else {\n" + " closure = (" + closureInterface.getName() + ") cachedClosureHolder.getClosure();\n" + " environment = new " + Util.ENVIRONMENT_CLASS.getName() + "($0, cachedClosureHolder.getEnvironmentSize());\n" + " $0.closureHolder.set(closure, cachedClosureHolder.getEnvironmentSize());\n" + " }\n" + " } else {\n" + " environment = new " + Util.ENVIRONMENT_CLASS.getName() + "($0, $0.closureHolder.getEnvironmentSize());\n" + " }\n" + " }\n" + (staged.getType().equals(Type.VOID) ? " closure.evaluate(environment);\n" : " $0.value = " + Util.DISPATCHER_CLASS.getName() + "." + Util.getLiftMethodName(staged.getType()) + "(closure.evaluate(environment));\n") + "}"; } CtMethod evaluate = CtMethod.make(evaluateSource, clazz); clazz.addMethod(evaluate); clazz.toClass(); } catch (CannotCompileException | NotFoundException e) { throw new RuntimeException(e); } return clazz; }
/** * Given a bean-style interface, generate an instance of the interface by implementing getters and * setters for each property. It will also add implementations to support the {@link * SupportsRdfId} interface and generate simple, default equals, toString and hashCode methods. * * <p>If there are other non-bean style (getter and/or setter's for properties) methods on the * interface, this will likely fail to generate the instance. * * @param theInterface the interface to build an instance of * @param <T> the type of the interface * @return New dynamically generated bytecode of a class that implements the given interface. * @throws Exception if there is an error while generating the bytecode of the new class. */ public static synchronized <T> Class<T> generateInstanceClass(Class<T> theInterface) throws Exception { processedMethods.clear(); // TODO: can we use some sort of template language for this? ClassPool aPool = ClassPool.getDefault(); aPool.appendClassPath(new LoaderClassPath(theInterface.getClassLoader())); CtClass aInterface = aPool.get(theInterface.getName()); CtClass aSupportsRdfIdInterface = aPool.get(SupportsRdfId.class.getName()); CtClass aEmpireGeneratedInterface = aPool.get(EmpireGenerated.class.getName()); if (!Arrays.asList(aInterface.getInterfaces()).contains(aSupportsRdfIdInterface) && !SupportsRdfId.class.isAssignableFrom(theInterface)) { throw new IllegalArgumentException( "Class '" + theInterface.getName() + "' does not implement SupportsRdfId, cannot generate Empire suitable implementation."); } String aName = aInterface.getPackageName() + ".impl." + aInterface.getSimpleName() + "Impl"; CtClass aClass = null; try { // i had a good reason for doing this, but i dont remember what it is. when i do, i'll // explain it here =) aClass = aPool.get(aName); return (Class<T>) BeanReflectUtil.loadClass(aName); } catch (NotFoundException e) { aClass = aPool.makeClass( aInterface.getPackageName() + ".impl." + aInterface.getSimpleName() + "Impl"); } catch (ClassNotFoundException e) { throw new Exception("Previously created class cannot be loaded.", e); } if (aClass.isFrozen()) { aClass.defrost(); } if (aInterface.isInterface()) { aClass.addInterface(aInterface); } else { aClass.setSuperclass(aInterface); } aClass.addInterface(aSupportsRdfIdInterface); aClass.addInterface(aEmpireGeneratedInterface); CtField aInterfaceField = new CtField(aPool.get(Class.class.getName()), "mInterfaceClass", aClass); aClass.addField( aInterfaceField, CtField.Initializer.byExpr(theInterface.getName() + ".class;")); CtField aAllTriplesField = new CtField(aPool.get(Graph.class.getName()), "mAllTriples", aClass); aClass.addField( aAllTriplesField, CtField.Initializer.byExpr("new com.clarkparsia.openrdf.ExtGraph();")); CtField aInstanceTriplesField = new CtField(aPool.get(Graph.class.getName()), "mInstanceTriples", aClass); aClass.addField( aInstanceTriplesField, CtField.Initializer.byExpr("new com.clarkparsia.openrdf.ExtGraph();")); aClass.addConstructor(CtNewConstructor.defaultConstructor(aClass)); generateMethods(theInterface, aPool, aClass); generateMethodsForSuperInterfaces(theInterface, aPool, aClass); CtField aIdField = new CtField(aPool.get(SupportsRdfId.class.getName()), "supportsId", aClass); aClass.addField( aIdField, CtField.Initializer.byExpr("new com.clarkparsia.empire.annotation.SupportsRdfIdImpl();")); if (!hasMethod(aClass, "getRdfId")) { aClass.addMethod( CtNewMethod.make( "public com.clarkparsia.empire.SupportsRdfId.RdfKey getRdfId() { return supportsId.getRdfId(); } ", aClass)); } if (!hasMethod(aClass, "setRdfId")) { aClass.addMethod( CtNewMethod.make( "public void setRdfId(com.clarkparsia.empire.SupportsRdfId.RdfKey theURI) { supportsId.setRdfId(theURI); } ", aClass)); } if (!hasMethod(aClass, "getAllTriples")) { aClass.addMethod( CtNewMethod.make( "public org.openrdf.model.Graph getAllTriples() { return mAllTriples; } ", aClass)); } if (!hasMethod(aClass, "setAllTriples")) { aClass.addMethod( CtNewMethod.make( "public void setAllTriples(org.openrdf.model.Graph theGraph) { mAllTriples = theGraph; } ", aClass)); } if (!hasMethod(aClass, "getInstanceTriples")) { aClass.addMethod( CtNewMethod.make( "public org.openrdf.model.Graph getInstanceTriples() { return mInstanceTriples; } ", aClass)); } if (!hasMethod(aClass, "setInstanceTriples")) { aClass.addMethod( CtNewMethod.make( "public void setInstanceTriples(org.openrdf.model.Graph theGraph) { mInstanceTriples = theGraph; } ", aClass)); } String equalsMethodBody = "public boolean equals(Object theObj) {\n" + " if (theObj == this) return true;\n" + " if (!(theObj instanceof com.clarkparsia.empire.SupportsRdfId)) return false;\n" + " if (!(mInterfaceClass.isAssignableFrom(theObj.getClass()))) return false;\n" + " return getRdfId().equals( ((com.clarkparsia.empire.SupportsRdfId) theObj).getRdfId()) && super.equals(theObj);\n" + "}\n"; aClass.addMethod(CtNewMethod.make(equalsMethodBody, aClass)); if (theInterface.isInterface()) { aClass.addMethod( CtNewMethod.make( "public String toString() { return getRdfId() != null ? getRdfId().toString() : super.toString(); } ", aClass)); aClass.addMethod( CtNewMethod.make( "public int hashCode() { return getRdfId() != null ? getRdfId().hashCode() : 0; } ", aClass)); } aClass.freeze(); Class<T> aResult = (Class<T>) aClass.toClass(); try { // make sure this is a valid class, that is, we can create instances of it! aResult.newInstance(); } catch (Exception ex) { // TODO: log this? throw ex; } return aResult; }
// 用javassit得到动态代理 public T createJavassistBytecodeDynamicProxy( LoadBalancer loadBalance, ConcurrentMap<String, T> map, Class ifaces) { try { ClassPool mPool = new ClassPool(true); CtClass mCtc = mPool.makeClass(ifaces.getName() + "JavaassistProxy"); mCtc.addInterface(mPool.get(ifaces.getName())); mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc)); mCtc.addField(CtField.make("public " + loadBalance.getClass().getName() + " sub;", mCtc)); mCtc.addField(CtField.make("public " + map.getClass().getName() + " map;", mCtc)); // mCtc.addField(CtField.make("public " + ArrayList.class.getName() + " list;", // mCtc)); mCtc.addMethod( CtNewMethod.make( "public Object getRealClient() { return (Object)sub.select(new " + ArrayList.class.getName() + "(map.values())); }", mCtc)); // 获取接口的方法 for (Method method : ifaces.getMethods()) { Class returnType = method.getReturnType(); String modifiers = "public"; if (Modifier.PUBLIC == method.getModifiers()) { modifiers = "public"; } else if (Modifier.PROTECTED == method.getModifiers()) { modifiers = "protected"; } else if (Modifier.PRIVATE == method.getModifiers()) { modifiers = "private"; } Class<?>[] parameter = method.getParameterTypes(); String params = ""; String ps = ""; for (Class param : parameter) { params += param.getName() + " " + param.getName() + ","; ps += param.getName() + ","; } if (params.equals("")) { params = ""; ps = ""; } else { params = params.substring(0, params.length()); ps = ps.substring(0, ps.length()); } mCtc.addMethod( CtNewMethod.make( modifiers + " void " + method.getName() + "(String a,String b){ Object t=this.getRealClient(); return ((" + ifaces.getName() + ")t)." + method.getName() + "(a,b) ;}", mCtc)); // mCtc.addMethod(CtNewMethod.make("public int count() { return // delegate.count(); }", mCtc)); } Class<?> pc = mCtc.toClass(); mCtc.debugWriteFile("/home/liguojun"); mCtc.writeFile("/home/liguojun"); T bytecodeProxy = (T) pc.newInstance(); Field filed = bytecodeProxy.getClass().getField("sub"); filed.set(bytecodeProxy, loadBalance); Field filed1 = bytecodeProxy.getClass().getField("map"); filed1.set(bytecodeProxy, map); return bytecodeProxy; } catch (Exception e) { e.printStackTrace(); } return null; }