/*
* Copyright 2014 NAVER Corp.
* 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 com.navercorp.pinpoint.profiler.instrument.interceptor;
import java.lang.reflect.Method;
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentMethod;
import com.navercorp.pinpoint.profiler.metadata.ApiMetaDataService;
/**
* @author Jongho Moon
*
*/
public class InvokeBeforeCodeGenerator extends InvokeCodeGenerator {
private final int interceptorId;
private final InstrumentClass targetClass;
public InvokeBeforeCodeGenerator(int interceptorId, InterceptorDefinition interceptorDefinition, InstrumentClass targetClass, InstrumentMethod targetMethod, ApiMetaDataService apiMetaDataService) {
super(interceptorId, interceptorDefinition, targetMethod, apiMetaDataService);
this.interceptorId = interceptorId;
this.targetClass = targetClass;
}
public String generate() {
final CodeBuilder builder = new CodeBuilder();
builder.begin();
// try {
// _$PINPOINT$_holder13 = InterceptorRegistry.findInterceptor(13);
// (($INTERCEPTOR_TYPE)_$PINPOINT$_holder13.getInterceptor.before($ARGUMENTS);
// } catch (Throwable t) {
// InterceptorInvokerHelper.handleException(t);
// }
builder.append("try { ");
builder.format("%1$s = %2$s.getInterceptor(%3$d); ", getInterceptorVar(), getInterceptorRegistryClassName(), interceptorId);
final Method beforeMethod = interceptorDefinition.getBeforeMethod();
if (beforeMethod != null) {
builder.format("((%1$s)%2$s).before(", getInterceptorType(), getInterceptorVar());
appendArguments(builder);
builder.format(");");
}
builder.format("} catch (java.lang.Throwable _$PINPOINT_EXCEPTION$_) { %1$s.handleException(_$PINPOINT_EXCEPTION$_); }", getInterceptorInvokerHelperClassName());
builder.end();
return builder.toString();
}
private void appendArguments(CodeBuilder builder) {
final InterceptorType type = interceptorDefinition.getInterceptorType();
switch (type) {
case ARRAY_ARGS:
appendSimpleBeforeArguments(builder);
break;
case STATIC:
appendStaticBeforeArguments(builder);
break;
case API_ID_AWARE:
appendApiIdAwareBeforeArguments(builder);
break;
case BASIC:
appendCustomBeforeArguments(builder);
break;
}
}
private void appendSimpleBeforeArguments(CodeBuilder builder) {
builder.format("%1$s, %2$s", getTarget(), getArguments());
}
private void appendStaticBeforeArguments(CodeBuilder builder) {
builder.format("%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s", getTarget(), targetClass.getName(), targetMethod.getName(), getParameterTypes(), getArguments());
}
private void appendApiIdAwareBeforeArguments(CodeBuilder builder) {
builder.format("%1$s, %2$d, %3$s", getTarget(), getApiId(), getArguments());
}
private void appendCustomBeforeArguments(CodeBuilder builder) {
final Method interceptorMethod = interceptorDefinition.getBeforeMethod();
final Class<?>[] paramTypes = interceptorMethod.getParameterTypes();
if (paramTypes.length == 0) {
return;
}
builder.append(getTarget());
int i = 0;
int argNum = targetMethod.getParameterTypes().length;
int interceptorArgNum = paramTypes.length - 1;
int matchNum = Math.min(argNum, interceptorArgNum);
for (; i < matchNum; i++) {
builder.append(", ($w)$" + (i + 1));
}
for (; i < interceptorArgNum; i++) {
builder.append(", null");
}
}
}