001: package abbot.editor.editors;
002:
003: import java.awt.Component;
004: import java.awt.event.ActionEvent;
005: import java.lang.reflect.*;
006: import java.util.*;
007:
008: import javax.swing.*;
009:
010: import abbot.i18n.Strings;
011: import abbot.script.*;
012: import abbot.tester.ComponentTester;
013:
014: /** Provide convenient editing of a PropertyCall step. */
015: public abstract class PropertyCallEditor extends CallEditor {
016:
017: private JComboBox component;
018: private PropertyCall call;
019:
020: public PropertyCallEditor(PropertyCall call) {
021: super (call);
022: this .call = call;
023: component = addComponentSelector(Strings.get("ComponentID"),
024: call.getComponentID(), call.getResolver(), true);
025: component.setName(TAG_COMPONENT);
026: }
027:
028: /** Get the class of the current component target, if any. */
029: protected Class getComponentTargetClass(Class cls) {
030: String[] args = getCall().getArguments();
031: if (args.length == 1) {
032: String id = args[0];
033: ComponentReference ref = getCall().getResolver()
034: .getComponentReference(id);
035: if (ref != null) {
036: try {
037: return getCall()
038: .resolveClass(ref.getRefClassName());
039: } catch (ClassNotFoundException e) {
040: }
041: }
042: }
043: return null;
044: }
045:
046: /** If the target is Component or ComponentTester, provide a merge of
047: property-like methods from both.
048: */
049: protected Map getMethods(Class cls, int mask) {
050: boolean isTester = ComponentTester.class.isAssignableFrom(cls);
051: boolean isComponent = Component.class.isAssignableFrom(cls);
052: Class componentClass = isTester ? getComponentTargetClass(cls)
053: : (isComponent ? cls : null);
054: Class testerClass = isTester ? cls
055: : (isComponent ? ComponentTester.getTester(
056: componentClass).getClass() : null);
057: if (!isTester && !isComponent)
058: return super .getMethods(cls, mask);
059:
060: Map map = new HashMap();
061: if (componentClass != null) {
062: Iterator iter = super .getMethods(componentClass, mask)
063: .values().iterator();
064: while (iter.hasNext()) {
065: Method m = (Method) iter.next();
066: if (PropertyCall.isPropertyMethod(m)) {
067: map.put(m.getName(), m);
068: }
069: }
070: }
071: // Scan the corresponding component tester for additional property
072: // methods
073: try {
074: ComponentTester tester = componentClass != null ? ComponentTester
075: .getTester(componentClass)
076: : (ComponentTester) testerClass.newInstance();
077: Iterator iter = getComponentTesterMethods(tester)
078: .iterator();
079: while (iter.hasNext()) {
080: Method m = (Method) iter.next();
081: map.put(m.getName(), m);
082: }
083: } catch (Exception e) {
084: }
085: return map;
086: }
087:
088: protected boolean includeMethod(Class cls, Method m) {
089: return true;
090: }
091:
092: protected Collection getComponentTesterMethods(
093: ComponentTester tester) {
094: return Arrays.asList(tester.getPropertyMethods());
095: }
096:
097: /** Synchronize the component selector with the PropertyCall data. */
098: protected void componentChanged() {
099: component.setSelectedItem(call.getComponentID());
100: }
101:
102: public void actionPerformed(ActionEvent ev) {
103: Object src = ev.getSource();
104: if (src == component) {
105: String id = (String) component.getSelectedItem();
106: if (id != null)
107: id = id.trim();
108: if ("".equals(id)) {
109: id = null;
110: }
111: ComponentReference ref = call.getResolver()
112: .getComponentReference(id);
113: String tcn = ref != null ? ref.getRefClassName()
114: : Component.class.getClass().getName();
115: call.setComponentID(id);
116:
117: call.setTargetClassName(tcn);
118: call.setArguments(new String[0]);
119: targetClassChanged();
120: argumentsChanged();
121:
122: fireStepChanged();
123: } else if (src == method) {
124: super .actionPerformed(ev);
125: // When the method changes to or from a ComponentTester
126: // pseudo-property method, we need to change the target class.
127: try {
128: Class cls = call.getTargetClass();
129: String methodName = (String) method.getSelectedItem();
130: Map methods = getMethods(cls, Modifier.PUBLIC);
131: Method m = (Method) methods.get(methodName);
132: if (m != null) {
133: Class newClass = m.getDeclaringClass();
134: if (ComponentTester.class
135: .isAssignableFrom(newClass)
136: && Component.class.isAssignableFrom(cls)) {
137: String id = call.getComponentID();
138: if (id != null) {
139: call.setArguments(new String[] { id });
140: argumentsChanged();
141: }
142: call.setComponentID(null);
143: call.setTargetClassName(newClass.getName());
144: componentChanged();
145: targetClassChanged();
146:
147: fireStepChanged();
148: } else if (Component.class
149: .isAssignableFrom(newClass)
150: && ComponentTester.class
151: .isAssignableFrom(cls)
152: && call.getArguments().length == 1) {
153: newClass = getComponentTargetClass(cls);
154: String id = call.getArguments()[0];
155:
156: call.setArguments(new String[0]);
157: call.setComponentID(id);
158: call.setTargetClassName(newClass.getName());
159: argumentsChanged();
160: componentChanged();
161: targetClassChanged();
162:
163: fireStepChanged();
164: }
165: }
166: } catch (ClassNotFoundException e) {
167: // don't care
168: }
169: } else {
170: super.actionPerformed(ev);
171: }
172: }
173: }
|