0001: /*
0002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
0003: * notice. All rights reserved.
0004: */
0005: package com.tc;
0006:
0007: import org.dijon.Button;
0008: import org.dijon.CheckBox;
0009: import org.dijon.Container;
0010: import org.dijon.ContainerResource;
0011: import org.dijon.Dialog;
0012: import org.dijon.EmptyBorder;
0013: import org.dijon.Label;
0014: import org.dijon.PagedView;
0015: import org.dijon.RadioButton;
0016: import org.dijon.TextArea;
0017: import org.dijon.TextField;
0018:
0019: import com.tc.admin.common.AbstractResolutionAction;
0020: import com.tc.admin.common.AbstractWorkState;
0021: import com.tc.admin.common.NonPortableMessages;
0022: import com.tc.admin.common.NonPortableResolutionAction;
0023: import com.tc.admin.common.NonPortableWalkNode;
0024: import com.tc.admin.common.NonPortableWorkState;
0025: import com.tc.admin.common.XCellEditor;
0026: import com.tc.admin.common.XCheckBox;
0027: import com.tc.admin.common.XContainer;
0028: import com.tc.admin.common.XLabel;
0029: import com.tc.admin.common.XList;
0030: import com.tc.admin.common.XTextField;
0031: import com.tc.admin.common.XTextPane;
0032: import com.tc.admin.common.XTree;
0033: import com.tc.admin.common.XTreeCellRenderer;
0034: import com.tc.object.appevent.NonPortableObjectEvent;
0035: import com.tc.object.appevent.NonPortableObjectState;
0036: import com.terracottatech.config.Include;
0037: import com.terracottatech.config.OnLoad;
0038: import com.terracottatech.config.TcConfigDocument.TcConfig;
0039:
0040: import java.awt.Color;
0041: import java.awt.Component;
0042: import java.awt.FlowLayout;
0043: import java.awt.Point;
0044: import java.awt.event.ActionEvent;
0045: import java.awt.event.ActionListener;
0046: import java.awt.event.MouseEvent;
0047: import java.util.ArrayList;
0048: import java.util.Enumeration;
0049: import java.util.EventObject;
0050: import java.util.Iterator;
0051:
0052: import javax.swing.ButtonGroup;
0053: import javax.swing.DefaultListCellRenderer;
0054: import javax.swing.DefaultListModel;
0055: import javax.swing.Icon;
0056: import javax.swing.ImageIcon;
0057: import javax.swing.JList;
0058: import javax.swing.JTree;
0059: import javax.swing.SwingConstants;
0060: import javax.swing.SwingUtilities;
0061: import javax.swing.UIManager;
0062: import javax.swing.event.ListSelectionEvent;
0063: import javax.swing.event.ListSelectionListener;
0064: import javax.swing.event.TreeSelectionEvent;
0065: import javax.swing.event.TreeSelectionListener;
0066: import javax.swing.tree.DefaultMutableTreeNode;
0067: import javax.swing.tree.DefaultTreeCellEditor;
0068: import javax.swing.tree.DefaultTreeCellRenderer;
0069: import javax.swing.tree.DefaultTreeModel;
0070: import javax.swing.tree.DefaultTreeSelectionModel;
0071: import javax.swing.tree.TreePath;
0072: import javax.swing.tree.TreeSelectionModel;
0073:
0074: public class NonPortableObjectPanel extends XContainer implements
0075: TreeSelectionListener {
0076: private NonPortableObjectEvent fEvent;
0077: private SessionIntegratorFrame fMainFrame;
0078: private Label fMessageLabel;
0079: private XList fIssueList;
0080: private DefaultListModel fIssueListModel;
0081: private IssueListSelectionHandler fIssueListSelectionHandler;
0082: private XTree fObjectTree;
0083: private Container fIssueDetailsPanel;
0084: private Label fSummaryLabel;
0085: private XTextPane fDescriptionText;
0086: private Container fResolutionsPanel;
0087: private XTree fActionTree;
0088: private PagedView fActionPanel;
0089: private TextField fIncludePatternField;
0090: private CheckBox fHonorTransientToggle;
0091: private ButtonGroup fOnLoadGroup;
0092: private ActionListener fOnLoadButtonGroupHandler;
0093: private RadioButton fOnLoadDoNothingToggle;
0094: private RadioButton fOnLoadMethodToggle;
0095: private TextField fOnLoadMethodField;
0096: private RadioButton fOnLoadCodeToggle;
0097: private TextArea fOnLoadCodeText;
0098: private XList fIncludeTypesList;
0099: private XList fBootTypesList;
0100: private Button fPreviousIssueButton;
0101: private Button fNextIssueButton;
0102: private Button fApplyButton;
0103: private Button fCancelButton;
0104: private ConfigHelper fConfigHelper;
0105: private TcConfig fNewConfig;
0106:
0107: private static final ImageIcon NOT_PORTABLE_ICON = new ImageIcon(
0108: NonPortableWalkNode.class
0109: .getResource("/com/tc/admin/icons/field_private_obj.gif"));
0110: private static final ImageIcon NEVER_PORTABLE_ICON = new ImageIcon(
0111: NonPortableWalkNode.class
0112: .getResource("/com/tc/admin/icons/field_private_obj.gif"));
0113: private static final ImageIcon TRANSIENT_ICON = new ImageIcon(
0114: NonPortableWalkNode.class
0115: .getResource("/com/tc/admin/icons/field_public_obj.gif"));
0116: private static final ImageIcon PORTABLE_ICON = new ImageIcon(
0117: NonPortableWalkNode.class
0118: .getResource("/com/tc/admin/icons/field_default_obj.gif"));
0119: private static final ImageIcon PRE_INSTRUMENTED_ICON = new ImageIcon(
0120: NonPortableWalkNode.class
0121: .getResource("/com/tc/admin/icons/field_protected_obj.gif"));
0122: private static final ImageIcon OBJ_CYCLE_ICON = new ImageIcon(
0123: NonPortableWalkNode.class
0124: .getResource("/com/tc/admin/icons/obj_cycle.gif"));
0125: private static final ImageIcon RESOLVED_ICON = new ImageIcon(
0126: NonPortableWalkNode.class
0127: .getResource("/com/tc/admin/icons/installed_ovr.gif"));
0128: private static final ImageIcon BLANK_ICON = new ImageIcon(
0129: NonPortableWalkNode.class
0130: .getResource("/com/tc/admin/icons/blank12x12.gif"));
0131:
0132: public NonPortableObjectPanel(ContainerResource res,
0133: SessionIntegratorFrame frame) {
0134: super ();
0135: load(res);
0136: fMainFrame = frame;
0137: fNewConfig = (TcConfig) frame.getConfigHelper().getConfig()
0138: .copy();
0139: fConfigHelper = new ConfigCopyHelper();
0140: }
0141:
0142: class ConfigCopyHelper extends ConfigHelper {
0143: public TcConfig getConfig() {
0144: return fNewConfig;
0145: }
0146: }
0147:
0148: public void load(ContainerResource res) {
0149: super .load(res);
0150:
0151: fMessageLabel = (Label) findComponent("MessageLabel");
0152:
0153: fIssueList = (XList) findComponent("IssueList");
0154: fIssueList.setModel(fIssueListModel = new DefaultListModel());
0155: fIssueList.setCellRenderer(new IssueListCellRenderer());
0156: fIssueList
0157: .addListSelectionListener(fIssueListSelectionHandler = new IssueListSelectionHandler());
0158: fIssueList.setVisibleRowCount(15);
0159:
0160: fObjectTree = (XTree) findComponent("Tree");
0161: fObjectTree.setCellRenderer(new ObjectTreeCellRenderer());
0162: ((DefaultTreeSelectionModel) fObjectTree.getSelectionModel())
0163: .setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
0164: fObjectTree.addTreeSelectionListener(this );
0165:
0166: fIssueDetailsPanel = (Container) findComponent("IssueDetailsPanel");
0167:
0168: fSummaryLabel = (Label) findComponent("SummaryLabel");
0169: fDescriptionText = (XTextPane) findComponent("DescriptionText");
0170: fResolutionsPanel = (Container) findComponent("ResolutionsPanel");
0171:
0172: fActionTree = (XTree) findComponent("ActionTree");
0173: fActionTree
0174: .addTreeSelectionListener(new ActionTreeSelectionHandler());
0175: fActionTree.setCellRenderer(new ActionTreeNodeRenderer());
0176: fActionTree.setCellEditor(new ActionTreeNodeEditor());
0177: fActionTree.setRootVisible(true);
0178: fActionTree.setEditable(true);
0179: ((DefaultTreeModel) fActionTree.getModel())
0180: .setRoot(new ActionTreeRootNode());
0181: fActionTree.setInvokesStopCellEditing(true);
0182:
0183: fActionPanel = (PagedView) findComponent("ActionPanel");
0184:
0185: fIncludePatternField = (TextField) findComponent("PatternField");
0186: fHonorTransientToggle = (CheckBox) findComponent("HonorTransientToggle");
0187: fOnLoadGroup = new ButtonGroup();
0188: fOnLoadButtonGroupHandler = new OnLoadButtonGroupHandler();
0189: fOnLoadGroup
0190: .add(fOnLoadDoNothingToggle = (RadioButton) findComponent("DoNothingButton"));
0191: fOnLoadDoNothingToggle
0192: .addActionListener(fOnLoadButtonGroupHandler);
0193: fOnLoadGroup
0194: .add(fOnLoadMethodToggle = (RadioButton) findComponent("CallMethodButton"));
0195: fOnLoadMethodToggle
0196: .addActionListener(fOnLoadButtonGroupHandler);
0197: fOnLoadGroup
0198: .add(fOnLoadCodeToggle = (RadioButton) findComponent("ExecuteCodeButton"));
0199: fOnLoadCodeToggle.addActionListener(fOnLoadButtonGroupHandler);
0200: fOnLoadMethodField = (TextField) findComponent("CallMethodField");
0201: fOnLoadCodeText = (TextArea) findComponent("ExecuteCodeText");
0202: fOnLoadCodeText.setRows(3);
0203:
0204: fBootTypesList = (XList) findComponent("BootTypesList");
0205: fIncludeTypesList = (XList) findComponent("IncludeTypesList");
0206:
0207: fNextIssueButton = (Button) findComponent("NextIssueButton");
0208: fNextIssueButton.addActionListener(new ActionListener() {
0209: public void actionPerformed(ActionEvent ae) {
0210: gotoNextIssue();
0211: }
0212: });
0213: fPreviousIssueButton = (Button) findComponent("PreviousIssueButton");
0214: fPreviousIssueButton.addActionListener(new ActionListener() {
0215: public void actionPerformed(ActionEvent ae) {
0216: gotoPreviousIssue();
0217: }
0218: });
0219: fApplyButton = (Button) findComponent("ApplyButton");
0220: fApplyButton.addActionListener(new ActionListener() {
0221: public void actionPerformed(ActionEvent ae) {
0222: apply();
0223: }
0224: });
0225: fCancelButton = (Button) findComponent("CancelButton");
0226: fCancelButton.addActionListener(new ActionListener() {
0227: public void actionPerformed(ActionEvent ae) {
0228: cancel();
0229: }
0230: });
0231: }
0232:
0233: private void apply() {
0234: ConfigHelper configHelper = fMainFrame.getConfigHelper();
0235: configHelper.setConfig(fNewConfig);
0236: fMainFrame.modelChanged();
0237: close();
0238: fMainFrame.saveAndStart();
0239: }
0240:
0241: private void cancel() {
0242: close();
0243: }
0244:
0245: private void close() {
0246: Dialog dialog = (Dialog) getAncestorOfClass(Dialog.class);
0247: dialog.setVisible(false);
0248: }
0249:
0250: void gotoNextIssue() {
0251: DefaultMutableTreeNode nextIssue = getNextIssue();
0252: if (nextIssue != null) {
0253: TreePath treePath = new TreePath(nextIssue.getPath());
0254: fObjectTree.setSelectionPath(treePath);
0255: fObjectTree.scrollPathToVisible(treePath);
0256: }
0257: }
0258:
0259: private DefaultMutableTreeNode getNextIssue(
0260: DefaultMutableTreeNode item) {
0261: while ((item = item.getNextNode()) != null) {
0262: Object userObject = item.getUserObject();
0263:
0264: if (userObject instanceof NonPortableWorkState) {
0265: NonPortableWorkState workState = (NonPortableWorkState) userObject;
0266: if (testIsIssue(workState)) {
0267: return item;
0268: }
0269: }
0270: }
0271:
0272: return null;
0273: }
0274:
0275: DefaultMutableTreeNode getNextIssue() {
0276: DefaultMutableTreeNode node = (DefaultMutableTreeNode) fObjectTree
0277: .getLastSelectedPathComponent();
0278: if (node != null) {
0279: return getNextIssue(node);
0280: }
0281: return null;
0282: }
0283:
0284: void gotoPreviousIssue() {
0285: DefaultMutableTreeNode previousIssue = getPreviousIssue();
0286: if (previousIssue != null) {
0287: TreePath treePath = new TreePath(previousIssue.getPath());
0288: fObjectTree.setSelectionPath(treePath);
0289: fObjectTree.scrollPathToVisible(treePath);
0290: }
0291: }
0292:
0293: DefaultMutableTreeNode getPreviousIssue(DefaultMutableTreeNode item) {
0294: while ((item = item.getPreviousNode()) != null) {
0295: Object userObject = item.getUserObject();
0296:
0297: if (userObject instanceof NonPortableWorkState) {
0298: NonPortableWorkState workState = (NonPortableWorkState) userObject;
0299: if (testIsIssue(workState)) {
0300: return item;
0301: }
0302: }
0303: }
0304:
0305: return null;
0306: }
0307:
0308: DefaultMutableTreeNode getPreviousIssue() {
0309: DefaultMutableTreeNode node = (DefaultMutableTreeNode) fObjectTree
0310: .getLastSelectedPathComponent();
0311: if (node != null) {
0312: return getPreviousIssue(node);
0313: }
0314: return null;
0315: }
0316:
0317: // NOTE: this is copied in ui-eclipse/src/org/terracotta/dso/dialogs/NonPortableObjectDialog.
0318: // ConfigHelper needs to be unified before we can move this to NonPortableWorkState.testIsIssue(ConfigHelper).
0319:
0320: boolean testIsIssue(NonPortableWorkState workState) {
0321: String fieldName = workState.getFieldName();
0322: boolean isTransientField = fieldName != null
0323: && (fConfigHelper.isTransient(fieldName) || workState
0324: .isTransient());
0325:
0326: if (workState.isNull() || workState.isRepeated()
0327: || isTransientField)
0328: return false;
0329:
0330: if (workState.isNeverPortable()
0331: || workState.extendsLogicallyManagedType()) {
0332: return true;
0333: }
0334:
0335: if (workState.hasRequiredBootTypes()) {
0336: java.util.List types = workState.getRequiredBootTypes();
0337: for (Iterator iter = types.iterator(); iter.hasNext();) {
0338: if (!fConfigHelper.isBootJarClass((String) iter.next()))
0339: return true;
0340: }
0341: }
0342:
0343: if (workState.hasRequiredIncludeTypes()) {
0344: java.util.List types = workState.getRequiredIncludeTypes();
0345: for (Iterator iter = types.iterator(); iter.hasNext();) {
0346: if (!fConfigHelper.isAdaptable((String) iter.next()))
0347: return true;
0348: }
0349: }
0350:
0351: if (!workState.isPortable()
0352: && workState.isSystemType()
0353: && !fConfigHelper.isBootJarClass(workState
0354: .getTypeName()))
0355: return true;
0356:
0357: if (workState.getExplaination() != null)
0358: return true;
0359:
0360: return !workState.isPortable()
0361: && !fConfigHelper.isAdaptable(workState.getTypeName());
0362: }
0363:
0364: boolean checkAddToIssueList(NonPortableWorkState workState) {
0365: if (workState.hasSelectedActions()) {
0366: return true;
0367: }
0368: return testIsIssue(workState);
0369: }
0370:
0371: void initIssueList() {
0372: fIssueList
0373: .removeListSelectionListener(fIssueListSelectionHandler);
0374: fIssueListModel.clear();
0375: Enumeration e = ((DefaultMutableTreeNode) fObjectTree
0376: .getModel().getRoot()).preorderEnumeration();
0377: while (e.hasMoreElements()) {
0378: Object obj = e.nextElement();
0379:
0380: if (obj instanceof DefaultMutableTreeNode) {
0381: DefaultMutableTreeNode node = (DefaultMutableTreeNode) obj;
0382: Object userObject = node.getUserObject();
0383:
0384: if (userObject instanceof NonPortableWorkState) {
0385: NonPortableWorkState workState = (NonPortableWorkState) userObject;
0386:
0387: if (checkAddToIssueList(workState)) {
0388: String label = workState.shortSummary();
0389: Icon icon = workState.hasSelectedActions() ? RESOLVED_ICON
0390: : BLANK_ICON;
0391: fIssueListModel.addElement(new IssueListItem(
0392: node, label, icon));
0393: }
0394: }
0395: }
0396: }
0397: fIssueList.addListSelectionListener(fIssueListSelectionHandler);
0398: }
0399:
0400: class IssueListSelectionHandler implements ListSelectionListener {
0401: public void valueChanged(ListSelectionEvent e) {
0402: if (!e.getValueIsAdjusting()
0403: && fIssueList.getModel().getSize() > 0) {
0404: int index = fIssueList.getSelectedIndex();
0405: IssueListItem item = (IssueListItem) fIssueList
0406: .getModel().getElementAt(index);
0407: DefaultMutableTreeNode node = item.fTreeNode;
0408: TreePath path = new TreePath(node.getPath());
0409:
0410: fObjectTree.setSelectionPath(path);
0411: fObjectTree.scrollPathToVisible(path);
0412: }
0413: }
0414: }
0415:
0416: class IssueListCellRenderer extends DefaultListCellRenderer {
0417: public IssueListCellRenderer() {
0418: setOpaque(true);
0419: }
0420:
0421: public Component getListCellRendererComponent(JList list,
0422: Object value, int index, boolean isSelected,
0423: boolean cellHasFocus) {
0424: super .getListCellRendererComponent(list, value, index,
0425: isSelected, cellHasFocus);
0426: if (value instanceof IssueListItem) {
0427: IssueListItem item = (IssueListItem) value;
0428:
0429: setText(item.fLabel);
0430: setIcon(item.fIcon);
0431: }
0432:
0433: return this ;
0434: }
0435: }
0436:
0437: class IssueListItem {
0438: DefaultMutableTreeNode fTreeNode;
0439: String fLabel;
0440: Icon fIcon;
0441:
0442: IssueListItem(DefaultMutableTreeNode treeNode, String label,
0443: Icon icon) {
0444: fTreeNode = treeNode;
0445: fLabel = label;
0446: fIcon = icon;
0447: }
0448:
0449: void setIcon(Icon icon) {
0450: fIcon = icon;
0451: }
0452: }
0453:
0454: public void setEvent(NonPortableObjectEvent event) {
0455: if (event == null) {
0456: return;
0457: }
0458:
0459: fEvent = event;
0460: fMessageLabel.setText(event.getNonPortableEventReason()
0461: .getMessage());
0462:
0463: fObjectTree.setModel(event.getNonPortableEventContext()
0464: .getTreeModel());
0465:
0466: DefaultMutableTreeNode root = (DefaultMutableTreeNode) fObjectTree
0467: .getModel().getRoot();
0468: Enumeration enumeration = root.preorderEnumeration();
0469: while (enumeration.hasMoreElements()) {
0470: DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration
0471: .nextElement();
0472: Object userObject = node.getUserObject();
0473: if (userObject instanceof NonPortableObjectState) {
0474: userObject = new NonPortableWorkState(
0475: (NonPortableObjectState) userObject);
0476: node.setUserObject(userObject);
0477: }
0478: }
0479:
0480: initIssueList();
0481: resetSearchButtons();
0482:
0483: if (fIssueList.getModel().getSize() > 0) {
0484: fIssueList.setSelectedIndex(0);
0485: }
0486: }
0487:
0488: private void resetSearchButtons() {
0489: fPreviousIssueButton.setEnabled(getPreviousIssue() != null);
0490: fNextIssueButton.setEnabled(getNextIssue() != null);
0491: }
0492:
0493: public void valueChanged(TreeSelectionEvent e) {
0494: DefaultMutableTreeNode node = (DefaultMutableTreeNode) fObjectTree
0495: .getLastSelectedPathComponent();
0496:
0497: if (node != null) {
0498: Object userObject = node.getUserObject();
0499:
0500: selectIssueListItem(node);
0501: if (userObject instanceof NonPortableWorkState) {
0502: NonPortableWorkState workState = (NonPortableWorkState) userObject;
0503: setWorkState(workState);
0504: } else {
0505: hideIssueDetailsPanel();
0506: }
0507: fPreviousIssueButton.setEnabled(getPreviousIssue() != null);
0508: fNextIssueButton.setEnabled(getNextIssue() != null);
0509: } else {
0510: fIssueList
0511: .removeListSelectionListener(fIssueListSelectionHandler);
0512: fIssueList.clearSelection();
0513: fIssueList
0514: .addListSelectionListener(fIssueListSelectionHandler);
0515: }
0516: }
0517:
0518: private void selectIssueListItem(DefaultMutableTreeNode node) {
0519: fIssueList
0520: .removeListSelectionListener(fIssueListSelectionHandler);
0521: for (int i = 0; i < fIssueListModel.getSize(); i++) {
0522: IssueListItem item = (IssueListItem) fIssueListModel.get(i);
0523: if (item.fTreeNode == node) {
0524: fIssueList.setSelectedIndex(i);
0525: fIssueList
0526: .addListSelectionListener(fIssueListSelectionHandler);
0527: return;
0528: }
0529: }
0530: fIssueList.clearSelection();
0531: fIssueList.addListSelectionListener(fIssueListSelectionHandler);
0532: }
0533:
0534: Icon iconFor(NonPortableWorkState workState) {
0535: if (workState.isRepeated()) {
0536: return OBJ_CYCLE_ICON;
0537: } else if (workState.isPreInstrumented()) {
0538: return PRE_INSTRUMENTED_ICON;
0539: } else if (workState.isNeverPortable()) {
0540: return NEVER_PORTABLE_ICON;
0541: } else if (!workState.isPortable()) {
0542: return NOT_PORTABLE_ICON;
0543: } else if (workState.isTransient()) {
0544: return TRANSIENT_ICON;
0545: } else {
0546: return PORTABLE_ICON;
0547: }
0548: }
0549:
0550: class ObjectTreeCellRenderer extends XTreeCellRenderer {
0551: public Component getTreeCellRendererComponent(JTree tree,
0552: Object value, boolean sel, boolean expanded,
0553: boolean leaf, int row, boolean focused) {
0554: Label label = (Label) super .getTreeCellRendererComponent(
0555: tree, value, sel, expanded, leaf, row, focused);
0556:
0557: label.setIcon(PORTABLE_ICON);
0558: if (value instanceof DefaultMutableTreeNode) {
0559: DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
0560: Object userObject = node.getUserObject();
0561:
0562: if (userObject instanceof NonPortableWorkState) {
0563: NonPortableWorkState workState = (NonPortableWorkState) userObject;
0564: label.setText(workState.getLabel());
0565: label.setIcon(iconFor(workState));
0566: }
0567: }
0568:
0569: return label;
0570: }
0571: }
0572:
0573: void setWorkState(NonPortableWorkState workState) {
0574: showIssueDetailsPanel();
0575: fSummaryLabel.setText("<html><p>" + workState.summary()
0576: + "</p></html>");
0577: fSummaryLabel.setIcon(iconFor(workState));
0578: fDescriptionText.setText(workState.descriptionFor(fEvent
0579: .getNonPortableEventContext()));
0580: fDescriptionText.select(0, 0);
0581: fResolutionsPanel.setVisible(true);
0582: DefaultMutableTreeNode actionTreeRoot = (DefaultMutableTreeNode) fActionTree
0583: .getModel().getRoot();
0584: actionTreeRoot.removeAllChildren();
0585: createActionNodes(workState);
0586: ((DefaultTreeModel) fActionTree.getModel())
0587: .nodeStructureChanged(actionTreeRoot);
0588: if (actionTreeRoot.getChildCount() == 0) {
0589: hideResolutionsPanel();
0590: return;
0591: }
0592: ((DefaultTreeModel) fActionTree.getModel()).reload();
0593: fActionTree.expandRow(0);
0594: fResolutionsPanel.revalidate();
0595: fResolutionsPanel.repaint();
0596: SwingUtilities.invokeLater(new Runnable() {
0597: public void run() {
0598: fActionTree.startEditingAtPath(fActionTree
0599: .getPathForRow(0));
0600: }
0601: });
0602: }
0603:
0604: private void hideIssueDetailsPanel() {
0605: fIssueDetailsPanel.setVisible(false);
0606: }
0607:
0608: private void showIssueDetailsPanel() {
0609: fIssueDetailsPanel.setVisible(true);
0610: }
0611:
0612: private void hideResolutionsPanel() {
0613: fResolutionsPanel.setVisible(false);
0614: }
0615:
0616: class ActionTreeNode extends DefaultMutableTreeNode {
0617: ActionTreeNode(AbstractResolutionAction action) {
0618: super (action);
0619: }
0620:
0621: public void setUserObject(Object o) {/**/
0622: }
0623:
0624: AbstractResolutionAction getAction() {
0625: Object obj = getUserObject();
0626: if (obj instanceof AbstractResolutionAction) {
0627: return (AbstractResolutionAction) obj;
0628: }
0629: return null;
0630: }
0631:
0632: boolean isSelected() {
0633: AbstractResolutionAction action = getAction();
0634: return action != null ? action.isSelected() : false;
0635: }
0636:
0637: void setSelected(boolean selected) {
0638: AbstractResolutionAction action = getAction();
0639: if (action != null) {
0640: action.setSelected(selected);
0641: if (selected) {
0642: ((ActionTreeRootNode) getParent())
0643: .setSelected(false);
0644: } else {
0645: ((ActionTreeRootNode) getParent()).testSelect();
0646: }
0647: fireNodeChanged();
0648: }
0649: }
0650:
0651: void showControl(NonPortableObjectPanel panel) {
0652: AbstractResolutionAction action = getAction();
0653: if (action != null && action.isSelected()) {
0654: action.showControl(panel);
0655: } else {
0656: hideActionPanel();
0657: }
0658: }
0659:
0660: void fireNodeChanged() {
0661: ((DefaultTreeModel) fActionTree.getModel())
0662: .nodeChanged(this );
0663: }
0664: }
0665:
0666: class ActionTreeRootNode extends ActionTreeNode {
0667: boolean fSelected;
0668:
0669: ActionTreeRootNode() {
0670: super (null);
0671: userObject = NonPortableMessages
0672: .getString("TAKE_NO_ACTION");
0673: }
0674:
0675: boolean isSelected() {
0676: return fSelected;
0677: }
0678:
0679: void setSelected(boolean selected) {
0680: if ((fSelected = selected) == true) {
0681: for (int i = 0; i < getChildCount(); i++) {
0682: ((ActionTreeNode) getChildAt(i)).setSelected(false);
0683: }
0684: }
0685: fireNodeChanged();
0686: }
0687:
0688: void testSelect() {
0689: for (int i = 0; i < getChildCount(); i++) {
0690: if (((ActionTreeNode) getChildAt(i)).isSelected()) {
0691: return;
0692: }
0693: }
0694: fSelected = true;
0695: fireNodeChanged();
0696: SwingUtilities.invokeLater(new Runnable() {
0697: public void run() {
0698: fActionTree.selectTop();
0699: fActionTree.startEditingAtPath(fActionTree
0700: .getPathForRow(0));
0701: }
0702: });
0703: }
0704: }
0705:
0706: static class ActionTreeCellRendererComponent extends Container {
0707: public XCheckBox checkBox;
0708: public XLabel label;
0709: public Container container;
0710:
0711: public ActionTreeCellRendererComponent() {
0712: super ();
0713: setLayout(new FlowLayout(SwingConstants.CENTER, 3, 1));
0714: add(checkBox = new XCheckBox());
0715: add(label = new XLabel());
0716: checkBox.setBorder(new EmptyBorder());
0717: setBorder(new EmptyBorder());
0718: setFocusCycleRoot(true);
0719: }
0720:
0721: void setColors(Color fg, Color bg) {
0722: checkBox.setBackground(null);
0723: checkBox.setForeground(null);
0724: label.setBackground(null);
0725: label.setForeground(null);
0726: setBackground(bg);
0727: setForeground(fg);
0728: setOpaque(true);
0729: }
0730: }
0731:
0732: class ActionTreeNodeRenderer extends DefaultTreeCellRenderer {
0733: ActionTreeCellRendererComponent atcrc = new ActionTreeCellRendererComponent();
0734:
0735: public Component getTreeCellRendererComponent(JTree tree,
0736: Object value, boolean sel, boolean expanded,
0737: boolean leaf, int row, boolean focused) {
0738: Component comp = super .getTreeCellRendererComponent(tree,
0739: value, sel, expanded, leaf, row, focused);
0740:
0741: if (value instanceof ActionTreeNode) {
0742: ActionTreeNode actionNode = (ActionTreeNode) value;
0743: atcrc.checkBox.setSelected(actionNode.isSelected());
0744: atcrc.label.setText(actionNode.toString());
0745: Color bg = sel ? getBackgroundSelectionColor()
0746: : getBackgroundNonSelectionColor();
0747: Color fg = sel ? getTextSelectionColor()
0748: : getTextNonSelectionColor();
0749: atcrc.setColors(fg, bg);
0750: comp = atcrc;
0751: }
0752:
0753: return comp;
0754: }
0755: }
0756:
0757: class ActionSelectionHandler implements ActionListener {
0758: public void actionPerformed(ActionEvent e) {
0759: TreePath treePath = fActionTree.getEditingPath();
0760: ActionTreeNode actionNode = (ActionTreeNode) treePath
0761: .getLastPathComponent();
0762: if (actionNode != null) {
0763: XCheckBox checkBox = (XCheckBox) e.getSource();
0764: actionNode.setSelected(checkBox.isSelected());
0765:
0766: AbstractResolutionAction action = actionNode
0767: .getAction();
0768: if (action != null && action.isSelected()) {
0769: action.showControl(NonPortableObjectPanel.this );
0770: } else {
0771: hideActionPanel();
0772: }
0773: fApplyButton.setEnabled(anySelectedActions());
0774: }
0775: }
0776: }
0777:
0778: class CellEditor extends XCellEditor {
0779: ActionTreeCellRendererComponent atcrc;
0780:
0781: CellEditor() {
0782: super (new XTextField());
0783: atcrc = new ActionTreeCellRendererComponent();
0784: m_editorComponent = atcrc;
0785: atcrc.checkBox
0786: .addActionListener(new ActionSelectionHandler());
0787: }
0788:
0789: public boolean isCellEditable(EventObject event) {
0790: return true;
0791: }
0792:
0793: protected void fireEditingStopped() {/**/
0794: }
0795:
0796: public boolean shouldSelectCell(EventObject event) {
0797: if (event instanceof MouseEvent) {
0798: MouseEvent me = (MouseEvent) event;
0799: Point p = SwingUtilities.convertPoint(fActionTree,
0800: new Point(me.getX(), me.getY()), atcrc);
0801: Component activeComponent = SwingUtilities
0802: .getDeepestComponentAt(atcrc, p.x, p.y);
0803:
0804: if (activeComponent instanceof XCheckBox) {
0805: TreePath path = fActionTree.getPathForLocation(me
0806: .getX(), me.getY());
0807: if (path != null) {
0808: ActionTreeNode node = (ActionTreeNode) path
0809: .getLastPathComponent();
0810: node.setSelected(!node.isSelected());
0811: atcrc.checkBox.setSelected(node.isSelected());
0812: fApplyButton.setEnabled(anySelectedActions());
0813: }
0814: }
0815: }
0816: return true;
0817: }
0818:
0819: public Component getTreeCellEditorComponent(JTree tree,
0820: Object value, boolean isSelected, boolean expanded,
0821: boolean leaf, int row) {
0822: Component comp = super .getTreeCellEditorComponent(tree,
0823: value, isSelected, expanded, leaf, row);
0824:
0825: isSelected = true;
0826: if (value instanceof ActionTreeNode) {
0827: ActionTreeNode actionNode = (ActionTreeNode) value;
0828: atcrc.checkBox.setSelected(actionNode.isSelected());
0829: atcrc.label.setText(actionNode.toString());
0830: Color fg = isSelected ? UIManager
0831: .getColor("Tree.selectionForeground")
0832: : UIManager.getColor("Tree.textForeground");
0833: Color bg = isSelected ? UIManager
0834: .getColor("Tree.selectionBackground")
0835: : UIManager.getColor("Tree.textBackground");
0836: atcrc.setColors(fg, bg);
0837: comp = atcrc;
0838: }
0839:
0840: return comp;
0841: }
0842: }
0843:
0844: class ActionTreeNodeEditor extends DefaultTreeCellEditor {
0845: ActionTreeNodeEditor() {
0846: super (fActionTree, new ActionTreeNodeRenderer(),
0847: new CellEditor());
0848: }
0849:
0850: protected boolean canEditImmediately(EventObject event) {
0851: return true;
0852: }
0853:
0854: protected void determineOffset(JTree theTree, Object value,
0855: boolean isSelected, boolean expanded, boolean leaf,
0856: int row) {
0857: editingIcon = null;
0858: offset = 0;
0859: }
0860: }
0861:
0862: private boolean requiresPortabilityAction(
0863: NonPortableWorkState workState) {
0864: if (workState.isTransient()
0865: || workState.extendsLogicallyManagedType())
0866: return false;
0867: if (workState.hasRequiredBootTypes()) {
0868: java.util.List types = workState.getRequiredBootTypes();
0869: for (Iterator iter = types.iterator(); iter.hasNext();) {
0870: if (!fConfigHelper.isBootJarClass((String) iter.next()))
0871: return true;
0872: }
0873: }
0874: if (workState.hasNonPortableBaseTypes()) {
0875: java.util.List types = workState.getNonPortableBaseTypes();
0876: for (Iterator iter = types.iterator(); iter.hasNext();) {
0877: if (!fConfigHelper.isAdaptable((String) iter.next()))
0878: return true;
0879: }
0880: }
0881: return !fConfigHelper.isAdaptable(workState.getTypeName());
0882: }
0883:
0884: AbstractResolutionAction[] createActions(AbstractWorkState workState) {
0885: ArrayList<AbstractResolutionAction> list = new ArrayList<AbstractResolutionAction>();
0886:
0887: if (workState instanceof NonPortableWorkState) {
0888: NonPortableWorkState nonPortableWorkState = (NonPortableWorkState) workState;
0889: String fieldName = nonPortableWorkState.getFieldName();
0890:
0891: if (nonPortableWorkState.isNeverPortable()
0892: || nonPortableWorkState.isPortable()) {
0893: if (fieldName != null
0894: && !nonPortableWorkState.isTransient()
0895: && !fConfigHelper.isTransient(fieldName)) {
0896: list.add(new MakeTransientAction(
0897: nonPortableWorkState));
0898: }
0899: } else if (!nonPortableWorkState.isPortable()) {
0900: if (requiresPortabilityAction(nonPortableWorkState)) {
0901: list.add(new MakePortableAction(
0902: nonPortableWorkState));
0903: }
0904: if (fieldName != null
0905: && !nonPortableWorkState.isTransient()
0906: && !fConfigHelper.isTransient(fieldName)) {
0907: list.add(new MakeTransientAction(
0908: nonPortableWorkState));
0909: }
0910: }
0911: }
0912:
0913: return list.toArray(new AbstractResolutionAction[0]);
0914: }
0915:
0916: AbstractResolutionAction[] getActions(AbstractWorkState state) {
0917: AbstractResolutionAction[] actions = state.getActions();
0918:
0919: if (actions == null) {
0920: state.setActions(actions = createActions(state));
0921: }
0922:
0923: return actions;
0924: }
0925:
0926: void createActionNodes(AbstractWorkState state) {
0927: ActionTreeRootNode actionTreeRoot = (ActionTreeRootNode) fActionTree
0928: .getModel().getRoot();
0929: AbstractResolutionAction[] actions = getActions(state);
0930: AbstractResolutionAction action;
0931:
0932: actionTreeRoot.fSelected = true;
0933: if (actions != null && actions.length > 0) {
0934: for (int i = 0; i < actions.length; i++) {
0935: action = actions[i];
0936:
0937: if (action.isEnabled()) {
0938: actionTreeRoot.add(new ActionTreeNode(action));
0939: if (action.isSelected()) {
0940: ((IssueListItem) fIssueList.getSelectedValue())
0941: .setIcon(RESOLVED_ICON);
0942: fApplyButton.setEnabled(true);
0943: }
0944: }
0945: }
0946: }
0947: }
0948:
0949: private void hideActionPanel() {
0950: fActionPanel.setPage("EmptyPage");
0951: }
0952:
0953: private boolean anySelectedActions() {
0954: return selectedActions().hasNext();
0955: }
0956:
0957: private Iterator selectedActions() {
0958: ArrayList<AbstractResolutionAction> list = new ArrayList<AbstractResolutionAction>();
0959:
0960: for (int i = 0; i < fIssueList.getModel().getSize(); i++) {
0961: IssueListItem item = (IssueListItem) fIssueList.getModel()
0962: .getElementAt(i);
0963: DefaultMutableTreeNode node = item.fTreeNode;
0964: AbstractWorkState workState = (AbstractWorkState) node
0965: .getUserObject();
0966: AbstractResolutionAction[] actions = workState.getActions();
0967:
0968: if (actions != null && actions.length > 0) {
0969: for (int j = 0; j < actions.length; j++) {
0970: if (actions[j].isSelected()) {
0971: list.add(actions[j]);
0972: }
0973: }
0974: }
0975: }
0976:
0977: return list.iterator();
0978: }
0979:
0980: class ActionTreeSelectionHandler implements TreeSelectionListener {
0981: public void valueChanged(TreeSelectionEvent e) {
0982: ActionTreeNode actionNode = (ActionTreeNode) fActionTree
0983: .getLastSelectedPathComponent();
0984: if (actionNode != null) {
0985: AbstractResolutionAction action = actionNode
0986: .getAction();
0987:
0988: if (action != null && action.isSelected()) {
0989: action.showControl(NonPortableObjectPanel.this );
0990: } else {
0991: hideActionPanel();
0992: }
0993: }
0994: }
0995: }
0996:
0997: void setIncludeTypes(java.util.List<String> types) {
0998: fIncludeTypesList.setListData(types.toArray(new String[0]));
0999: }
1000:
1001: void setBootTypes(java.util.List<String> types) {
1002: fBootTypesList.setListData(types.toArray(new String[0]));
1003: }
1004:
1005: void setInclude(Include include) {
1006: fIncludePatternField.setText(include.getClassExpression());
1007: fHonorTransientToggle.setSelected(include.getHonorTransient());
1008: fOnLoadMethodField.setText("");
1009: fOnLoadCodeText.setText("");
1010: if (include.isSetOnLoad()) {
1011: OnLoad onLoad = include.getOnLoad();
1012: if (onLoad.isSetMethod()) {
1013: fOnLoadMethodToggle.setSelected(true);
1014: fOnLoadMethodField.setText(onLoad.getMethod());
1015: } else if (onLoad.isSetExecute()) {
1016: fOnLoadCodeToggle.setSelected(true);
1017: fOnLoadCodeText.setText(onLoad.getExecute());
1018: } else {
1019: fOnLoadDoNothingToggle.setSelected(false);
1020: }
1021: } else {
1022: fOnLoadDoNothingToggle.setSelected(true);
1023: }
1024: }
1025:
1026: class OnLoadButtonGroupHandler implements ActionListener {
1027: public void actionPerformed(ActionEvent ae) {
1028: RadioButton radioButton = (RadioButton) ae.getSource();
1029:
1030: if (radioButton == fOnLoadDoNothingToggle) {
1031: fOnLoadMethodField.setText("");
1032: fOnLoadMethodField.setEnabled(false);
1033:
1034: fOnLoadCodeText.setText("");
1035: fOnLoadCodeText.setEnabled(false);
1036: } else if (radioButton == fOnLoadMethodToggle) {
1037: fOnLoadCodeText.setText("");
1038: fOnLoadCodeText.setEnabled(false);
1039: } else {
1040: fOnLoadMethodField.setText("");
1041: fOnLoadMethodField.setEnabled(false);
1042: }
1043: }
1044: }
1045:
1046: class MakeTransientAction extends NonPortableResolutionAction {
1047: ArrayList<DefaultMutableTreeNode> fRemovedChildNodes;
1048:
1049: MakeTransientAction(NonPortableWorkState workState) {
1050: super (workState);
1051: }
1052:
1053: public void showControl(Object parentControl) {
1054: NonPortableObjectPanel parent = (NonPortableObjectPanel) parentControl;
1055: String fieldName = fWorkState.getFieldName();
1056: String declaringType = fieldName.substring(0, fieldName
1057: .lastIndexOf('.'));
1058: Include include = fConfigHelper
1059: .ensureIncludeRuleFor(declaringType);
1060:
1061: if (include != null) {
1062: parent.fActionPanel.setPage("IncludeRulePage");
1063: parent.setInclude(include);
1064: }
1065: }
1066:
1067: public String getText() {
1068: return NonPortableMessages.getString("DO_NOT_SHARE"); //$NON-NLS-1$
1069: }
1070:
1071: public void setSelected(boolean selected) {
1072: super .setSelected(selected);
1073:
1074: int index = fIssueList.getSelectedIndex();
1075: DefaultMutableTreeNode treeItem = (DefaultMutableTreeNode) fObjectTree
1076: .getLastSelectedPathComponent();
1077:
1078: if (selected) {
1079: fConfigHelper
1080: .ensureTransient(fWorkState.getFieldName());
1081: if (fRemovedChildNodes == null)
1082: fRemovedChildNodes = new ArrayList<DefaultMutableTreeNode>();
1083: for (int i = 0; i < treeItem.getChildCount(); i++) {
1084: fRemovedChildNodes
1085: .add((DefaultMutableTreeNode) treeItem
1086: .getChildAt(i));
1087: }
1088: treeItem.removeAllChildren();
1089: } else {
1090: fConfigHelper.ensureNotTransient(fWorkState
1091: .getFieldName());
1092:
1093: for (int i = 0; i < fRemovedChildNodes.size(); i++) {
1094: treeItem.add(fRemovedChildNodes.get(i));
1095: }
1096: fRemovedChildNodes.clear();
1097: }
1098: ((DefaultTreeModel) fObjectTree.getModel())
1099: .reload(treeItem);
1100:
1101: initIssueList();
1102: fObjectTree.setSelectionPath(new TreePath(treeItem
1103: .getPath()));
1104: fIssueList.setSelectedIndex(index);
1105: resetSearchButtons();
1106: }
1107: }
1108:
1109: class MakePortableAction extends NonPortableResolutionAction {
1110: MakePortableAction(NonPortableWorkState workState) {
1111: super (workState);
1112: }
1113:
1114: public void showControl(Object parentControl) {
1115: NonPortableObjectPanel parent = (NonPortableObjectPanel) parentControl;
1116: parent
1117: .setIncludeTypes(fWorkState
1118: .getRequiredIncludeTypes());
1119: parent.setBootTypes(fWorkState.getRequiredBootTypes());
1120: parent.fActionPanel.setPage("IncludeTypesPage");
1121: }
1122:
1123: public String getText() {
1124: return NonPortableMessages.getString("MAKE_PORTABLE"); //$NON-NLS-1$
1125: }
1126:
1127: public void setSelected(boolean selected) {
1128: super .setSelected(selected);
1129:
1130: if (fWorkState.hasRequiredBootTypes()) {
1131: java.util.List types = fWorkState
1132: .getRequiredBootTypes();
1133: if (selected) {
1134: for (Iterator iter = types.iterator(); iter
1135: .hasNext();) {
1136: fConfigHelper.ensureBootJarClass((String) iter
1137: .next());
1138: }
1139: } else {
1140: for (Iterator iter = types.iterator(); iter
1141: .hasNext();) {
1142: fConfigHelper
1143: .ensureNotBootJarClass((String) iter
1144: .next());
1145: }
1146: }
1147: }
1148:
1149: if (fWorkState.hasRequiredIncludeTypes()) {
1150: java.util.List types = fWorkState
1151: .getRequiredIncludeTypes();
1152: if (selected) {
1153: for (Iterator iter = types.iterator(); iter
1154: .hasNext();) {
1155: fConfigHelper.ensureAdaptable((String) iter
1156: .next());
1157: }
1158: } else {
1159: for (Iterator iter = types.iterator(); iter
1160: .hasNext();) {
1161: fConfigHelper.ensureNotAdaptable((String) iter
1162: .next());
1163: }
1164: }
1165: }
1166:
1167: int index = fIssueList.getSelectedIndex();
1168: initIssueList();
1169: fIssueList.setSelectedIndex(index);
1170: resetSearchButtons();
1171: }
1172: }
1173: }
|