001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.model.tree;
014:
015: import java.awt.Component;
016: import java.awt.Rectangle;
017: import java.beans.PropertyChangeEvent;
018: import java.beans.PropertyChangeListener;
019: import java.util.Collections;
020: import java.util.Comparator;
021: import java.util.List;
022:
023: import javax.swing.JPopupMenu;
024: import javax.swing.JTree;
025: import javax.swing.event.TreeModelEvent;
026: import javax.swing.tree.TreePath;
027:
028: import com.eviware.soapui.SoapUI;
029: import com.eviware.soapui.model.ModelItem;
030: import com.eviware.soapui.model.settings.SettingsListener;
031: import com.eviware.soapui.model.testsuite.TestStep;
032: import com.eviware.soapui.model.util.PanelBuilderRegistry;
033: import com.eviware.soapui.support.action.swing.ActionList;
034: import com.eviware.soapui.support.action.swing.ActionListBuilder;
035: import com.eviware.soapui.support.action.swing.ActionSupport;
036:
037: /**
038: * Abstract base class for SoapUITreeNode implementations
039: *
040: * @author Ole.Matzura
041: */
042:
043: public abstract class AbstractModelItemTreeNode<T extends ModelItem>
044: implements SoapUITreeNode, PropertyChangeListener {
045: private final T modelItem;
046: private final ModelItem parentItem;
047: private final SoapUITreeModel treeModel;
048: private List<? extends SoapUITreeNode> orderItems;
049: private String orderSetting;
050: private InternalSettingsListener internalSettingsListener;
051:
052: protected AbstractModelItemTreeNode(T modelItem,
053: ModelItem parentItem, SoapUITreeModel treeModel) {
054: this .modelItem = modelItem;
055: this .parentItem = parentItem;
056: this .treeModel = treeModel;
057:
058: modelItem.addPropertyChangeListener(this );
059: }
060:
061: public SoapUITreeModel getTreeModel() {
062: return treeModel;
063: }
064:
065: public Component getOverviewPanel() {
066: return PanelBuilderRegistry.getPanelBuilder(modelItem)
067: .buildOverviewPanel(modelItem);
068: }
069:
070: public T getModelItem() {
071: return modelItem;
072: }
073:
074: public boolean valueChanged(Object newValue) {
075: return false;
076: }
077:
078: public boolean isLeaf() {
079: return getChildCount() == 0;
080: }
081:
082: public int getChildCount() {
083: return orderItems == null ? 0 : orderItems.size();
084: }
085:
086: public SoapUITreeNode getChildNode(int index) {
087: return orderItems == null ? null : orderItems.get(index);
088: }
089:
090: public int getIndexOfChild(Object child) {
091: return orderItems == null ? -1 : orderItems.indexOf(child);
092: }
093:
094: public String toString() {
095: return modelItem.getName();
096: }
097:
098: public JPopupMenu getPopup() {
099: return ActionSupport.buildPopup(getActions());
100: }
101:
102: public ActionList getActions() {
103: return ActionListBuilder.buildActions(modelItem);
104: }
105:
106: public SoapUITreeNode getParentTreeNode() {
107: return treeModel.getTreeNode(parentItem);
108: }
109:
110: public void propertyChange(PropertyChangeEvent evt) {
111: String propertyName = evt.getPropertyName();
112: if (propertyName.equals(ModelItem.NAME_PROPERTY)
113: || propertyName.equals(TestStep.DISABLED_PROPERTY)) {
114: // use this since length has probably changed
115: getTreeModel().notifyNodeChanged(this );
116: } else if (propertyName.equals(ModelItem.ICON_PROPERTY)) {
117: // hack to improve rendering performance
118: JTree mainTree = SoapUI.getNavigator().getMainTree();
119: TreePath nodePath = getTreeModel().getPath(this );
120: Rectangle rowBounds = mainTree.getPathBounds(nodePath);
121: if (rowBounds != null) {
122: mainTree.repaint(rowBounds);
123: }
124: }
125: }
126:
127: public void release() {
128: modelItem.removePropertyChangeListener(this );
129:
130: if (internalSettingsListener != null)
131: SoapUI.getSettings().removeSettingsListener(
132: internalSettingsListener);
133:
134: getTreeModel().unmapModelItem(modelItem);
135: }
136:
137: public <T2 extends SoapUITreeNode> void initOrdering(
138: List<T2> items, String setting) {
139: this .orderItems = items;
140: this .orderSetting = setting;
141:
142: internalSettingsListener = new InternalSettingsListener(this ,
143: setting);
144: SoapUI.getSettings().addSettingsListener(
145: internalSettingsListener);
146: sortModelItems(items, setting);
147: }
148:
149: private final class InternalSettingsListener implements
150: SettingsListener {
151: private final AbstractModelItemTreeNode node;
152: private final String setting;
153:
154: public InternalSettingsListener(AbstractModelItemTreeNode node,
155: String setting) {
156: this .node = node;
157: this .setting = setting;
158: }
159:
160: public void settingChanged(String name, String newValue,
161: String oldValue) {
162: if (name.equals(setting)) {
163: if (oldValue == null)
164: oldValue = "false";
165:
166: if (newValue == null)
167: newValue = "false";
168:
169: if (!oldValue.equals(newValue)) {
170: TreePath path = getTreeModel().getPath(
171: AbstractModelItemTreeNode.this );
172: node.reorder(SoapUI.getNavigator().isVisible(path)
173: && SoapUI.getNavigator().isExpanded(path));
174: }
175: }
176: }
177: }
178:
179: public void reorder(boolean notify) {
180: if (orderItems != null) {
181: sortModelItems(orderItems, orderSetting);
182:
183: if (notify) {
184: getTreeModel().notifyStructureChanged(
185: new TreeModelEvent(this , getTreeModel()
186: .getPath(this )));
187: }
188: }
189: }
190:
191: public <T2 extends SoapUITreeNode> void sortModelItems(
192: List<T2> modelItems, final String setting) {
193: Collections.sort(modelItems, new Comparator<T2>() {
194: public int compare(T2 o1, T2 o2) {
195: String name1 = o1.getModelItem().getName();
196: String name2 = o2.getModelItem().getName();
197:
198: if (name1 == null && name2 == null) {
199: return 0;
200: } else if (name1 == null) {
201: return -1;
202: } else if (name2 == null) {
203: return 1;
204: } else if (setting != null
205: && SoapUI.getSettings().getBoolean(setting)) {
206: return name1.compareToIgnoreCase(name2);
207: } else {
208: return name1.compareTo(name2);
209: }
210: }
211: });
212: }
213:
214: public class ReorderPropertyChangeListener implements
215: PropertyChangeListener {
216: public void propertyChange(PropertyChangeEvent arg0) {
217: reorder(true);
218: SoapUI.getNavigator().selectModelItem(
219: (ModelItem) arg0.getSource());
220: }
221: }
222: }
|