/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.dragome.callbackevictor.serverside.bytecode.transformation.asm;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import com.dragome.callbackevictor.enhancers.Continuable;
public final class ContinuationClassAdapter extends ClassVisitor
{
private String className;
public ContinuationClassAdapter(final ClassVisitor cv)
{
super(Opcodes.ASM5, cv);
}
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
{
className= name;
// Check that it doesn't implement Continuable (already been instrumented)
String[] newInterfaces= new String[interfaces.length + 1];
for (int i= 0; i < interfaces.length; i++)
{
if (interfaces[i].equals(Type.getInternalName(Continuable.class)))
{
throw new RuntimeException(className + " has already been instrumented");
}
newInterfaces[i]= interfaces[i];
}
// Add the Continuable interface so that the class is marked and wont be instrumented again by mistake
newInterfaces[newInterfaces.length - 1]= Type.getInternalName(Continuable.class);
cv.visit(version, access, name, signature, superName, newInterfaces);
}
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
{
MethodVisitor mv= super.visitMethod(access, name, desc, signature, exceptions);
// TODO skip native and abstract methods?
if (!"<init>".equals(name) && mv != null)
{
return new ContinuationMethodAnalyzer(className, this.cv, mv, access, name, desc, signature, exceptions);
}
return mv;
}
}