static TypeParameterMatcher generate(Class<?> type, ClassLoader classLoader) { final String className = "io.netty.util.internal.__matchers__." + type.getName() + "Matcher"; try { try { return (TypeParameterMatcher) Class.forName(className, true, classLoader).newInstance(); } catch (Exception e) { // Not defined in the specified class loader. } CtClass c = classPool.getAndRename(NoOpTypeParameterMatcher.class.getName(), className); c.setModifiers(c.getModifiers() | Modifier.FINAL); c.getDeclaredMethod("match").setBody("{ return $1 instanceof " + type.getName() + "; }"); byte[] byteCode = c.toBytecode(); c.detach(); Method method = ClassLoader.class.getDeclaredMethod( "defineClass", String.class, byte[].class, int.class, int.class); method.setAccessible(true); Class<?> generated = (Class<?>) method.invoke(classLoader, className, byteCode, 0, byteCode.length); logger.debug("Generated: {}", generated.getName()); return (TypeParameterMatcher) generated.newInstance(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(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(); } }
private static void treatClassToPatch(CtClass c) throws CannotCompileException { if (c == null) { throw new IllegalArgumentException("the class to patch cannot be null"); } int modifiers = c.getModifiers(); if (Modifier.isAnnotation(modifiers)) { throw new IllegalArgumentException("the class to patch cannot be an annotation"); } if (Modifier.isInterface(modifiers)) { throw new IllegalArgumentException("the class to patch cannot be an interface"); } if (Modifier.isEnum(modifiers)) { throw new IllegalArgumentException("the class to patch cannot be an enum"); } c.setModifiers(Modifier.PUBLIC); addDefaultConstructor(c); }