/*
* 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;
import java.lang.reflect.Method;
import com.navercorp.pinpoint.common.util.Asserts;
/**
* @author Jongho Moon
*
*/
public class AccessorAnalyzer {
public AccessorDetails analyze(Class<?> accessorType) {
Asserts.notNull(accessorType, "accessorType");
if (!accessorType.isInterface()) {
throw new IllegalArgumentException("accessorType " + accessorType + "is not an interface");
}
Method[] methods = accessorType.getDeclaredMethods();
if (methods.length != 2) {
throw new IllegalArgumentException("accessorType has to declare 2 methods. " + accessorType + " has " + methods.length + ".");
}
Method getter;
Method setter;
if (methods[0].getParameterTypes().length == 0) {
getter = methods[0];
setter = methods[1];
} else {
getter = methods[1];
setter = methods[0];
}
Class<?> fieldType = getter.getReturnType();
if (fieldType == void.class || fieldType == Void.class) {
throw new IllegalArgumentException("accessorType must declare an getter and setter: " + accessorType);
}
Class<?>[] setterParamTypes = setter.getParameterTypes();
if (setterParamTypes.length != 1) {
throw new IllegalArgumentException("accessorType must declare an getter and setter: " + accessorType);
}
if (setterParamTypes[0] != fieldType) {
throw new IllegalArgumentException("The return type of getter is different to the parameter type of setter: " + accessorType);
}
if (setter.getReturnType() != void.class) {
throw new IllegalArgumentException("Setter must have return type void: " + accessorType);
}
return new AccessorDetails(fieldType, getter, setter);
}
public static class AccessorDetails {
private final Class<?> fieldType;
private final Method getter;
private final Method setter;
public AccessorDetails(Class<?> fieldType, Method getter, Method setter) {
this.fieldType = fieldType;
this.getter = getter;
this.setter = setter;
}
public Class<?> getFieldType() {
return fieldType;
}
public Method getGetter() {
return getter;
}
public Method getSetter() {
return setter;
}
}
}