@Test public void testSetter() throws Exception { CtClass mock = new WicketMockClassFactory(Date.class).getMock(); assertNotNull( mock.getMethod( "setSeconds", Descriptor.ofMethod( voidType, new CtClass[] {ClassPool.getDefault().get(Object.class.getName())}))); }
private void initExtraHarvest() { try { CtClass terraForming = HookManager.getInstance() .getClassPool() .get("com.wurmonline.server.behaviours.Terraforming"); CtClass[] paramTypes = { HookManager.getInstance().getClassPool().get("com.wurmonline.server.creatures.Creature"), CtPrimitiveType.intType, CtPrimitiveType.intType, CtPrimitiveType.booleanType, CtPrimitiveType.intType, CtPrimitiveType.floatType, HookManager.getInstance().getClassPool().get("com.wurmonline.server.items.Item") }; CtMethod method = terraForming.getMethod( "harvest", Descriptor.ofMethod(CtPrimitiveType.booleanType, paramTypes)); MethodInfo methodInfo = method.getMethodInfo(); CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); CodeIterator codeIterator = codeAttribute.iterator(); LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag); int quantityIndex = -1; for (int i = 0; i < attr.tableLength(); i++) { if ("quantity".equals(attr.variableName(i))) { quantityIndex = attr.index(i); } } if (quantityIndex == -1) { throw new HookException("Quantity variable can not be resolved"); } while (codeIterator.hasNext()) { int pos = codeIterator.next(); int op = codeIterator.byteAt(pos); if (op == CodeIterator.ISTORE) { int fieldRefIdx = codeIterator.byteAt(pos + 1); if (quantityIndex == fieldRefIdx) { Bytecode bytecode = new Bytecode(codeIterator.get().getConstPool()); bytecode.addIconst(extraHarvest); bytecode.add(Bytecode.IADD); codeIterator.insertAt(pos, bytecode.get()); break; } } } } catch (NotFoundException | BadBytecode e) { throw new HookException(e); } }
/** * Creates a CtClass object representing the specified class. It first examines whether or not the * corresponding class file exists. If yes, it creates a CtClass object. * * @return null if the class file could not be found. */ protected CtClass createCtClass(String classname, boolean useCache) { // accept "[L<class name>;" as a class name. if (classname.charAt(0) == '[') classname = Descriptor.toClassName(classname); if (classname.endsWith("[]")) { String base = classname.substring(0, classname.indexOf('[')); if ((!useCache || getCached(base) == null) && find(base) == null) return null; else return new CtArray(classname, this); } else if (find(classname) == null) return null; else return new CtClassType(classname, this); }
public static String describe(Type t) { if (t instanceof Class<?>) { return Descriptor.of(((Class) t).getName()); } else if (t instanceof ParameterizedType) { ParameterizedType pType = ((ParameterizedType) t); Type[] args = pType.getActualTypeArguments(); StringBuilder formatted = new StringBuilder(); for (Type type : args) { formatted.append(describe(type)); } return parameterized((Class) pType.getRawType()).ofFormatted(formatted.toString()).build(); } return ""; }
public BaseClassData(Class<?> cls) { className = cls.getName(); internalName = Descriptor.toJvmName(cls.getName()); this.loader = cls.getClassLoader(); replaceable = false; if (cls.getSuperclass() != null) { superClassName = cls.getSuperclass().getName(); } else { superClassName = null; } Set<MethodData> meths = new HashSet<MethodData>(); for (Method m : cls.getDeclaredMethods()) { MemberType type = MemberType.NORMAL; final String descriptor = DescriptorUtils.getDescriptor(m); if ((descriptor.equals(Constants.ADDED_METHOD_DESCRIPTOR) && m.getName().equals(Constants.ADDED_METHOD_NAME)) || (descriptor.equals(Constants.ADDED_STATIC_METHOD_DESCRIPTOR) && m.getName().equals(Constants.ADDED_STATIC_METHOD_NAME))) { type = MemberType.ADDED_SYSTEM; } MethodData md = new MethodData(m.getName(), descriptor, cls.getName(), type, m.getModifiers(), false); meths.add(md); } for (Constructor<?> c : cls.getDeclaredConstructors()) { MemberType type = MemberType.NORMAL; final String descriptor = DescriptorUtils.getDescriptor(c); if (descriptor.equals(Constants.ADDED_CONSTRUCTOR_DESCRIPTOR)) { type = MemberType.ADDED_SYSTEM; } MethodData md = new MethodData("<init>", descriptor, cls.getName(), type, c.getModifiers(), false); meths.add(md); } this.methods = Collections.unmodifiableSet(meths); Set<FieldData> fieldData = new HashSet<FieldData>(); for (Field m : cls.getDeclaredFields()) { fieldData.add(new FieldData(m)); } this.fields = Collections.unmodifiableSet(fieldData); }
public BaseClassData(ClassFile file, ClassLoader loader, boolean replaceable) { className = file.getName(); this.replaceable = replaceable; internalName = Descriptor.toJvmName(file.getName()); this.loader = loader; superClassName = file.getSuperclass(); boolean finalMethod = false; Set<MethodData> meths = new HashSet<MethodData>(); for (Object o : file.getMethods()) { String methodClassName = className; MethodInfo m = (MethodInfo) o; MemberType type = MemberType.NORMAL; if ((m.getDescriptor().equals(Constants.ADDED_METHOD_DESCRIPTOR) && m.getName().equals(Constants.ADDED_METHOD_NAME)) || (m.getDescriptor().equals(Constants.ADDED_STATIC_METHOD_DESCRIPTOR) && m.getName().equals(Constants.ADDED_STATIC_METHOD_NAME)) || (m.getDescriptor().equals(Constants.ADDED_CONSTRUCTOR_DESCRIPTOR))) { type = MemberType.ADDED_SYSTEM; } else if (m.getAttribute(Constants.FINAL_METHOD_ATTRIBUTE) != null) { finalMethod = true; } MethodData md = new MethodData( m.getName(), m.getDescriptor(), methodClassName, type, m.getAccessFlags(), finalMethod); meths.add(md); } this.methods = Collections.unmodifiableSet(meths); Set<FieldData> fieldData = new HashSet<FieldData>(); for (Object o : file.getFields()) { FieldInfo m = (FieldInfo) o; MemberType mt = MemberType.NORMAL; fieldData.add(new FieldData(m, mt, className, m.getAccessFlags())); } this.fields = Collections.unmodifiableSet(fieldData); }
private Set<CtMethod> getPatchMethods(Set<CtClass> patchClasses) { Set<CtMethod> result = new HashSet<CtMethod>(); // add all @PatchMethod found in a temporary map Map<String, List<CtMethod>> temp = new HashMap<String, List<CtMethod>>(); for (CtClass patchClass : patchClasses) { for (CtMethod ctMethod : patchClass.getDeclaredMethods()) { if (ctMethod.hasAnnotation(PatchMethod.class)) { if (!Modifier.isStatic(ctMethod.getModifiers())) { throw new GwtTestPatchException( "@" + PatchMethod.class.getName() + " has to be static : '" + ctMethod.getLongName() + "'"); } String nameAndSignature = ctMethod.getName() + Descriptor.toString(ctMethod.getSignature()); List<CtMethod> correspondingMethods = temp.get(nameAndSignature); if (correspondingMethods == null) { correspondingMethods = new ArrayList<CtMethod>(); temp.put(nameAndSignature, correspondingMethods); } correspondingMethods.add(ctMethod); } } } // for each @PatchMethod with the same signature, filter to get one with // override=true for (Map.Entry<String, List<CtMethod>> entry : temp.entrySet()) { CtMethod methodToUse = getMethodToUse(entry.getValue(), PatchMethod.class); methodToUse.setModifiers(Modifier.PUBLIC + Modifier.STATIC); result.add(methodToUse); } return result; }
@Override public void init() { // // We initialize a method hook that gets called right before CropTilePoller.checkForFarmGrowth // is called // if (disableWeeds) { try { // // To make sure we hook the correct method the list of method parameter types is compiled // CtClass[] paramTypes = { CtPrimitiveType.intType, CtPrimitiveType.intType, CtPrimitiveType.intType, CtPrimitiveType.byteType, CtPrimitiveType.byteType, HookManager.getInstance().getClassPool().get("com.wurmonline.mesh.MeshIO"), CtPrimitiveType.booleanType }; // // next we register the hook for // com.wurmonline.server.zones.CropTilePoller.checkForFarmGrowth(int, int, int, byte, byte, // MeshIO, boolean) // HookManager.getInstance() .registerHook( "com.wurmonline.server.zones.CropTilePoller", "checkForFarmGrowth", Descriptor.ofMethod(CtPrimitiveType.voidType, paramTypes), new InvocationHandlerFactory() { @Override public InvocationHandler createInvocationHandler() { return new InvocationHandler() { // // The actual hook is an InvocationHandler. It's invoke method is called // instead of the hooked method. // The object, method and arguments are passed as parameters to invoke() // @Override public Object invoke(Object object, Method method, Object[] args) throws Throwable { // // When the hook is called we can do stuff depending on the input parameters // Here we check if the tileAge is 6 (the second ripe stage) // byte aData = ((Number) args[4]).byteValue(); final int tileState = aData >> 4; int tileAge = tileState & 0x7; if (tileAge == 6) { // tileAge is 6. Advancing it further would create weeds. // Therefore we just exit here. // return null is required if the hooked method has a void return type return null; } // // tileAge is not 6. We just continue by calling the hooked method // return method.invoke(object, args); } }; } }); } catch (NotFoundException e) { throw new HookException(e); } } }
@Test(expected = NotFoundException.class) public void testFinalField() throws Exception { CtClass mock = new WicketMockClassFactory(FieldContainer.class).getMock(); mock.getMethod("setField", Descriptor.ofMethod(voidType, new CtClass[] {intType})); }
@Test(expected = Test.None.class) public void testField() throws Exception { CtClass mock = new WicketMockClassFactory(FieldContainer.class).getMock(); mock.getMethod("getNonFinalField", Descriptor.ofMethod(OBJECT_CLASS, new CtClass[] {})); mock.getMethod("setNonFinalField", Descriptor.ofMethod(voidType, new CtClass[] {intType})); }
/** * Returns a <code>CtClass</code> object with the given name. This is almost equivalent to <code> * get(String)</code> except that classname can be an array-type "descriptor" (an encoded type * name) such as <code>[Ljava/lang/Object;</code>. * * <p>Using this method is not recommended; this method should be used only to obtain the <code> * CtClass</code> object with a name returned from <code>getClassInfo</code> in <code> * javassist.bytecode.ClassPool</code>. <code>getClassInfo</code> returns a fully-qualified class * name but, if the class is an array type, it returns a descriptor. * * @param classname a fully-qualified class name or a descriptor representing an array type. * @see #get(String) * @see javassist.bytecode.ConstPool#getClassInfo(int) * @see javassist.bytecode.Descriptor#toCtClass(String, ClassPool) * @since 3.8.1 */ public CtClass getCtClass(String classname) throws NotFoundException { if (classname.charAt(0) == '[') return Descriptor.toCtClass(classname, this); else return get(classname); }
public static ClassNameBuilder parameterized(Class<?> clazz) { return new ClassNameBuilder(Descriptor.of(clazz.getName())); }
ClassNameBuilder of(Class<?> clazz) { return new ClassNameBuilder(prune(this.name) + "<" + Descriptor.of(clazz.getName()) + ">;"); }
@Test public void nullDescriptor() { String nullDescriptor = Descriptor.ofParameters(null); logger.info("Descript null:{}", nullDescriptor); }
public MethodAdapter(MethodVisitor mv, boolean add, CtClass target) { super(mv); addSynchronized = add; this.target = target; targetOwner = Descriptor.toJvmName(target.getName()); }