001 /* 002 Copyright (C) 2002-2003 Laurent Martelli <laurent@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 package org.objectweb.jac.core.rtti; 019 020 import java.lang.reflect.*; 021 /** 022 * This class defines a meta item that corresponds to a field or a 023 * method. 024 * 025 * @author Renaud Pawlak 026 * @author Laurent Martelli 027 */ 028 029 public abstract class MemberItem extends MetaItemDelegate { 030 031 /** 032 * A util method to get a member item reference from a full name. 033 * 034 * @param str member's full name, E.g.: myPackage.Person.name. 035 */ 036 public static MemberItem getMemberFromFullName(String str) throws Exception { 037 MemberItem ret=null; 038 int index = -1; 039 int paren = str.indexOf("("); 040 if (paren==-1) 041 index = str.lastIndexOf("."); 042 else 043 index = str.lastIndexOf(".",paren); 044 if (index!=-1) { 045 ClassItem classItem = 046 ClassRepository.get().getClass 047 (str.substring(0,index)); 048 ret = classItem.getMember(str.substring(index+1)); 049 } else { 050 new Exception("Failed to convert "+str+ 051 " into a class member"); 052 } 053 return ret; 054 } 055 056 static Class wrappeeClass = ClassRepository.wrappeeClass; 057 058 public MemberItem(ClassItem parent) { 059 this.parent = parent; 060 } 061 062 public MemberItem(Object delegate, ClassItem parent) throws InvalidDelegateException { 063 super(delegate); 064 this.parent = parent; 065 } 066 067 public abstract Class getType(); 068 069 public final ClassItem getTypeItem() { 070 return ClassRepository.get().getClass(getType()); 071 } 072 073 /** Returns the class item that owns the field (like getParent). */ 074 public final ClassItem getClassItem() { 075 return (ClassItem)getParent(); 076 } 077 078 MethodItem[] dependentMethods = MethodItem.emptyArray; 079 /** 080 * @see #getDependentMethods() 081 */ 082 public final void addDependentMethod(MethodItem method) { 083 MethodItem[] tmp = new MethodItem[dependentMethods.length+1]; 084 System.arraycopy(dependentMethods, 0, tmp, 0, dependentMethods.length); 085 tmp[dependentMethods.length] = method; 086 dependentMethods = tmp; 087 ClassItem superClass = getClassItem().getSuperclass(); 088 if (superClass!=null) { 089 FieldItem superField = superClass.getFieldNoError(getName()); 090 if (superField!=null) 091 superField.addDependentMethod(method); 092 } 093 } 094 /** 095 * Returns an array of methods whose result depend on the member. 096 * @see #addDependentMethod(MethodItem) 097 */ 098 public final MethodItem[] getDependentMethods() { 099 return dependentMethods; 100 } 101 102 103 protected boolean role; 104 105 /** 106 * Tells if this field is actually implemented by a role wrapper 107 * field. 108 * 109 * @return value of role 110 * @see #setRole(ClassItem,String,String) */ 111 112 public boolean isRole() { 113 return role; 114 } 115 116 protected ClassItem roleClassType = null; 117 protected String roleType = null; 118 protected String roleName = null; 119 120 /** 121 * Sets this field to be actually implemented by a field of a role 122 * wrapper. 123 * 124 * <p>When this method is called once, the <code>isRole()</code> 125 * method will return true. Moreover, the actually accessed and 126 * modified field when using set, get, etc, is the field of the 127 * role wrapper. 128 */ 129 public void setRole(ClassItem roleClassType, String roleType, String roleName) { 130 this.role = true; 131 this.roleClassType = roleClassType; 132 this.roleType = roleType; 133 this.roleName = roleName; 134 } 135 136 /** 137 * Returns the name prfixed with the owning class name. 138 */ 139 public String getLongName() { 140 return parent!=null ? parent.getName()+"."+getName() : "???"; 141 } 142 143 public int getModifiers() { 144 return ((Member)delegate).getModifiers(); 145 } 146 147 public String toString() { 148 return getLongName()+":"+getType().getName(); 149 } 150 151 /** 152 * Two members are equal if the class of one is a subclass of the 153 * other's class and they have the same name 154 */ 155 public boolean equals(Object o) { 156 if (!(o instanceof MemberItem)) 157 return false; 158 MemberItem m = (MemberItem)o; 159 return (m.getClassItem().isSubClassOf(getClassItem()) || 160 getClassItem().isSubClassOf(m.getClassItem())) 161 && getName().equals(m.getName()); 162 } 163 }