All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scouter.agent.asm.jdbc.PsExecuteMV Maven / Gradle / Ivy

There is a newer version: 2.20.0
Show newest version
/*
 *  Copyright 2015 Scouter Project.
 *
 *  Licensed 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 scouter.agent.asm.jdbc;

import scouter.agent.asm.util.AsmUtil;
import scouter.agent.trace.TraceSQL;
import scouter.org.objectweb.asm.Label;
import scouter.org.objectweb.asm.MethodVisitor;
import scouter.org.objectweb.asm.Opcodes;
import scouter.org.objectweb.asm.Type;
import scouter.org.objectweb.asm.commons.LocalVariablesSorter;

import java.util.HashSet;
import java.util.Set;


public class PsExecuteMV extends LocalVariablesSorter implements Opcodes {
	private static Set target = new HashSet();
	static {
		target.add("execute");
		target.add("executeQuery");
		target.add("executeUpdate");
		target.add("executeBatch");
	}

	private final byte methodType;

	public static boolean isTarget(String name) {
		return target.contains(name);
	}

	private final static String TRACESQL = TraceSQL.class.getName().replace('.', '/');
	private final static String START_METHOD = "start";
	private static final String START_SIGNATURE = "(Ljava/lang/Object;Lscouter/agent/trace/SqlParameter;B)Ljava/lang/Object;";
	private final static String END_METHOD = "end";
	private static final String END_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Throwable;I)V";

	public PsExecuteMV(int access, String desc, MethodVisitor mv, String owner,String name) {
		super(ASM4,access, desc, mv);
		this.owner = owner;
		this.returnType = Type.getReturnType(desc);
        this.desc = desc;
		this.methodType = StExecuteMV.methodType(name);
	}
	private Label startFinally = new Label();

	private String owner;
	private int statIdx;
	private final Type returnType;
    private final String desc;

	@Override
	public void visitCode() {
		mv.visitVarInsn(ALOAD, 0);
		mv.visitVarInsn(ALOAD, 0);
	    mv.visitFieldInsn(GETFIELD, owner, TraceSQL.PSTMT_PARAM_FIELD, "Lscouter/agent/trace/SqlParameter;");
		AsmUtil.PUSH(mv, this.methodType);

		mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, START_METHOD, START_SIGNATURE,false);

		statIdx = newLocal(scouter.org.objectweb.asm.Type.getType(Object.class));
		mv.visitVarInsn(Opcodes.ASTORE, statIdx);
		mv.visitLabel(startFinally);
		mv.visitCode();
	}

	@Override
	public void visitInsn(int opcode) {
		if ((opcode >= IRETURN && opcode <= RETURN)) {
            int lvPosReturn;
			switch (returnType.getSort()) {
                case Type.ARRAY:
                    if(returnType.getElementType().getSort() == Type.INT) {
                        lvPosReturn = newLocal(returnType);
                        mv.visitVarInsn(Opcodes.ASTORE, lvPosReturn);
                        mv.visitVarInsn(Opcodes.ALOAD, lvPosReturn);

                        mv.visitVarInsn(Opcodes.ALOAD, statIdx);
                        mv.visitInsn(Opcodes.ACONST_NULL);
                        mv.visitVarInsn(Opcodes.ALOAD, lvPosReturn);
                        mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, "getIntArraySum", "([I)I", false);

                    } else {
                        mv.visitVarInsn(Opcodes.ALOAD, statIdx);
                        mv.visitInsn(Opcodes.ACONST_NULL);
                        AsmUtil.PUSH(mv, -1);
                    }
                    break;
                case Type.BOOLEAN:
                case Type.INT:
                    lvPosReturn = newLocal(returnType);
					mv.visitVarInsn(Opcodes.ISTORE, lvPosReturn);
					mv.visitVarInsn(Opcodes.ILOAD, lvPosReturn);

					mv.visitVarInsn(Opcodes.ALOAD, statIdx);
					mv.visitInsn(Opcodes.ACONST_NULL);
					mv.visitVarInsn(Opcodes.ILOAD, lvPosReturn);

                    if(returnType.getSort()== Type.BOOLEAN){
						mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, "toInt", "(Z)I",false);
					}
					break;
				default:
					mv.visitVarInsn(Opcodes.ALOAD, statIdx);
					mv.visitInsn(Opcodes.ACONST_NULL);
					AsmUtil.PUSH(mv, -1);
			}
			mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, END_METHOD, END_SIGNATURE,false);
		}
		mv.visitInsn(opcode);
	}

	@Override
	public void visitMaxs(int maxStack, int maxLocals) {
		Label endFinally = new Label();
		mv.visitTryCatchBlock(startFinally, endFinally, endFinally, null);
		mv.visitLabel(endFinally);
		mv.visitInsn(DUP);
		int errIdx = newLocal(Type.getType(Throwable.class));
		mv.visitVarInsn(Opcodes.ASTORE, errIdx);

		mv.visitVarInsn(Opcodes.ALOAD, statIdx);
		mv.visitVarInsn(Opcodes.ALOAD, errIdx);
		AsmUtil.PUSH(mv, -3);

		mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, END_METHOD, END_SIGNATURE,false);
		mv.visitInsn(ATHROW);
		mv.visitMaxs(maxStack + 8, maxLocals + 2);
	}

    public static void main(String[] args) {
        Type type = Type.getReturnType("(Z)[I");
        System.out.println("type = " + type.getSort());
        System.out.println("dim = " + type.getDimensions());
        System.out.println("element = " + type.getElementType());

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy