/**
* 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 org.apache.cxf.aegis.type.basic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
class InterfaceInvocationHandler implements InvocationHandler {
private Map<Object, Object> attributes = new HashMap<>();
InterfaceInvocationHandler() {
}
public void writeProperty(Object key, Object value) {
attributes.put(key, value);
}
public Object readProperty(Object key) {
return attributes.get(key);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.getMethod("hashCode", (Class[]) null).equals(method)) {
return proxyHashCode(proxy);
} else if (Object.class.getMethod("equals", new Class[] {Object.class}).equals(method)) {
return proxyEquals(proxy, args[0]);
} else if (Object.class.getMethod("toString", (Class[]) null).equals(method)) {
return proxyToString(proxy);
} else {
if (isGetterMethod(method, args)) {
return doGetter(method, args);
} else if (isSetterMethod(method, args)) {
return doSetter(method, args);
} else {
throw new IllegalAccessError(method.getName() + " is not delegated.");
}
}
}
protected boolean isGetterMethod(Method method, Object[] args) {
if (args != null && args.length > 0) {
return false;
}
String methodName = method.getName();
if (methodName.startsWith("get") && methodName.length() > 3) {
return true;
}
return methodName.length() > 2 && methodName.startsWith("is");
/*
* // should "hasXXX()" be considered a getter method? else if
* (methodName.startsWith("has") && methodName.length() > 3) { return
* true; }
*/
}
protected boolean isSetterMethod(Method method, Object[] args) {
if (args == null || args.length != 1) {
return false;
}
if (!"void".equals(method.getReturnType().getName())) {
return false;
}
String methodName = method.getName();
return methodName.startsWith("set") && methodName.length() > 3;
}
protected Object doGetter(Method method, Object[] args) throws Throwable {
String methodName = method.getName();
String attrName = null;
if (methodName.startsWith("get")) {
attrName = convertMethodName(methodName, 3);
} else if (methodName.startsWith("is")) {
attrName = convertMethodName(methodName, 2);
} else {
throw new IllegalAccessError(methodName + " is not a valid getter method.");
}
Object prop = readProperty(attrName);
if (prop == null && method.getReturnType().isPrimitive()) {
if (method.getReturnType() == int.class) {
prop = Integer.valueOf(0);
} else if (method.getReturnType() == boolean.class) {
prop = Boolean.FALSE;
} else if (method.getReturnType() == long.class) {
prop = Long.valueOf(0);
} else if (method.getReturnType() == double.class) {
prop = Double.valueOf(0);
} else if (method.getReturnType() == short.class) {
prop = Short.valueOf((short)0);
} else if (method.getReturnType() == byte.class) {
prop = Byte.valueOf((byte)0);
} else if (method.getReturnType() == char.class) {
prop = Character.valueOf((char)0);
}
}
return prop;
}
protected Object doSetter(Method method, Object[] args) throws Throwable {
String methodName = method.getName();
String attrName = null;
if (methodName.startsWith("set")) {
attrName = convertMethodName(methodName, 3);
} else {
throw new IllegalAccessError(methodName + " is not a valid setter method.");
}
writeProperty(attrName, args[0]);
return null;
}
private String convertMethodName(String methodName, int firstCharacter) {
if (methodName.length() >= firstCharacter + 2) {
if (!Character.isUpperCase(methodName.charAt(firstCharacter + 1))) {
return Character.toLowerCase(methodName.charAt(firstCharacter))
+ methodName.substring(firstCharacter + 1);
} else {
return methodName.substring(3);
}
} else {
return Character.toLowerCase(methodName.charAt(firstCharacter))
+ methodName.substring(firstCharacter + 1);
}
}
protected Integer proxyHashCode(Object proxy) {
return Integer.valueOf(System.identityHashCode(proxy));
}
protected Boolean proxyEquals(Object proxy, Object other) {
return proxy == other ? Boolean.TRUE : Boolean.FALSE;
}
protected String proxyToString(Object proxy) {
return proxy.getClass().getName() + '@' + proxy.hashCode();
}
}