package org.objectstyle.wolips.eomodeler.core.kvc;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
public class MemberContainer {
public static final int GET = 1;
public static final int SET = 2;
private static final String[] GET_METHOD_PREFIXES = { "get", "", "_", "_get", "is", "_is" }; //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
private static final String[] SET_METHOD_PREFIXES = { "set", "", "_", "_set" }; //$NON-NLS-4$
private static final String[] FIELD_PREFIXES = { "", "_" };
private int myMemberType;
private Class myClass;
private Map<String, IKey> myMembers;
public MemberContainer(Class _class, int _memberType) {
myMembers = new HashMap<String, IKey>();
myClass = _class;
myMemberType = _memberType;
Class currentClass = _class;
while (currentClass != null) {
hashMembers(currentClass.getDeclaredFields());
currentClass = currentClass.getSuperclass();
}
currentClass = _class;
while (currentClass != null) {
hashMembers(currentClass.getDeclaredMethods());
currentClass = currentClass.getSuperclass();
}
}
public IKey getMember(Object _instance, String _name) {
String[] prefixes = (myMemberType == MemberContainer.GET) ? MemberContainer.GET_METHOD_PREFIXES : MemberContainer.SET_METHOD_PREFIXES;
IKey setMember = getMemberWithPrefixes(_name, prefixes);
if (setMember == null) {
setMember = getMemberWithPrefixes(_name, MemberContainer.FIELD_PREFIXES);
if (setMember == null) {
if (_instance instanceof Map) {
setMember = new MapKey(_name);
} else if (myMemberType == MemberContainer.GET) {
throw new IllegalArgumentException("There is no get-method named '" + _name + "' on the class " + myClass.getName() + ".");
} else {
throw new IllegalArgumentException("There is no set-method named '" + _name + "' on the class " + myClass.getName() + ".");
}
}
}
return setMember;
}
protected void hashMembers(Member[] _members) {
for (int memberNum = 0; memberNum < _members.length; memberNum++) {
Member member = _members[memberNum];
int modifiers = member.getModifiers();
if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
IKey matchingMember = null;
if (myMemberType == MemberContainer.GET) {
if (member instanceof Field) {
matchingMember = new FieldKey((Field) member);
} else {
Method method = (Method) member;
if (method.getReturnType() != null && method.getParameterTypes().length == 0) {
matchingMember = new MethodKey(method);
}
}
} else if (myMemberType == MemberContainer.SET) {
if (member instanceof Field) {
matchingMember = new FieldKey((Field) member);
} else {
Method method = (Method) member;
if (method.getReturnType() == void.class && method.getParameterTypes().length == 1) {
matchingMember = new MethodKey(method);
}
}
}
if (matchingMember != null) {
myMembers.put(member.getName(), matchingMember);
}
}
}
}
protected IKey getMemberWithPrefixes(String _key, String[] _prefixes) {
IKey matchingMember = null;
for (int prefixNum = 0; matchingMember == null && prefixNum < _prefixes.length; prefixNum++) {
String prefix = _prefixes[prefixNum];
boolean capitalize = prefix.length() > 1; // Don't capitalize
// blank and _ prefixes
String keyWithPrefix = prependToKey(prefix, _key, capitalize);
matchingMember = myMembers.get(keyWithPrefix);
}
return matchingMember;
}
protected String prependToKey(String _prepend, String _key, boolean _capitalize) {
StringBuffer sb = new StringBuffer();
sb.append(_prepend);
if (_capitalize) {
sb.append(Character.toUpperCase(_key.charAt(0)));
sb.append(_key.substring(1));
} else {
sb.append(_key);
}
return sb.toString();
}
}