Java tutorial
/******************************************************************************* * Copyright (c) 2007, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * yyyymmdd bug Email and other contact information * -------- -------- ----------------------------------------------------------- * 20071106 196997 ericdp@ca.ibm.com - Eric Peters * 20071120 209858 ericdp@ca.ibm.com - Eric Peters, Enhancing service policy framework and UI * 20071212 209858 ericdp@ca.ibm.com - Eric Peters, Enhancing service policy framework and UI * 20080211 218520 pmoogk@ca.ibm.com - Peter Moogk * 20080324 222095 pmoogk@ca.ibm.com - Peter Moogk, UI now listens for state changes. * 20080324 223634 ericdp@ca.ibm.com - Eric D. Peters, Service Policies preference tree should be 3 level tree * 20080506 219005 ericdp@ca.ibm.com - Eric D. Peters, Service policy preference page not restoring properly * 20080530 234944 pmoogk@ca.ibm.com - Peter Moogk, Fixed focus problem for action controls * 20080716 239457 ericdp@ca.ibm.com - Eric D. Peters, Service Policy UI Restore defaults does not refresh validation error * 20090306 224632 ericdp@ca.ibm.com - Eric D. Peters, Fix Service Policies preference page UI * 20120111 357580 kchong@ca.ibm.com - Keith Chong, Service Policies preference page tree view pane doesn't expand to show fully the tree items *******************************************************************************/ package org.eclipse.wst.ws.internal.service.policy.ui; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Vector; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.help.IWorkbenchHelpSystem; import org.eclipse.wst.ws.service.policy.IDescriptor; import org.eclipse.wst.ws.service.policy.IPolicyEnumerationList; import org.eclipse.wst.ws.service.policy.IPolicyRelationship; import org.eclipse.wst.ws.service.policy.IPolicyState; import org.eclipse.wst.ws.service.policy.IPolicyStateEnum; import org.eclipse.wst.ws.service.policy.IServicePolicy; import org.eclipse.wst.ws.service.policy.IStateEnumerationItem; import org.eclipse.wst.ws.service.policy.ServicePolicyPlatform; import org.eclipse.wst.ws.service.policy.listeners.IPolicyChildChangeListener; import org.eclipse.wst.ws.service.policy.listeners.IPolicyStateChangeListener; import org.eclipse.wst.ws.service.policy.ui.IPolicyOperation; import org.eclipse.wst.ws.service.policy.ui.ServicePolicyActivatorUI; import org.eclipse.wst.ws.service.policy.ui.ServicePolicyPlatformUI; import org.eclipse.wst.ws.service.policy.ui.IPolicyOperation.OperationKind; import org.eclipse.wst.ws.service.policy.ui.utils.ServiceUtils; import org.osgi.framework.Bundle; public class ServicePoliciesComposite extends Composite implements SelectionListener, IPolicyChildChangeListener { private ScrolledComposite operationsScrolledComposite; //a scrollable composite containing operations available for the selected policies private Composite operationsComposite; private IWorkbenchHelpSystem helpSystem; private Composite masterComposite; private Composite detailsComposite; private Tree masterPolicyTree; //tertiary and higher level policy nodes in a separate tree private Tree detailsPolicyTree; private Text text_DetailsPanel_description; private Text text_DetailsPanel_dependencies; private Label label_DetailsPanel_description; private Label label_detailsPanel_dependancies; private Hashtable<String, IStatus> allErrors; private IStatus error; private boolean bComplexOpCompleted = true; private List<ChildChangeEvent> listChildChangeEvents; private IConManager iconManager = new IConManager(); private IProject project = null; private SelectionListener listener; private ExpandableComposite excomposite; private ServicePolicyPlatform platform = ServicePolicyPlatform.getInstance(); private ServicePolicyPlatformUI platformUI = ServicePolicyPlatformUI.getInstance(); private IPolicyStateChangeListener stateChangeListener = new StateChangeListener(); private boolean stateChangeEnabled = true; private HashSet<IServicePolicy> stateChangePolicySet = new HashSet<IServicePolicy>(); private List<IServicePolicy> lastSelectedSp = null; /*CONTEXT_ID PTPP0001 for the Service Policies Preference & Property Page*/ private String INFOPOP_SPPP_PAGE = ServicePolicyActivatorUI.PLUGIN_ID + ".SPPP0001"; /** * Creates an expandable composite * @param parent * @param nColumns * @return */ private ExpandableComposite createExpandableComposite(Composite parent, int nColumns) { ExpandableComposite excomposite = new ExpandableComposite(parent, SWT.NONE, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT); excomposite.setExpanded(false); excomposite.setVisible(false); excomposite.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT)); excomposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, nColumns, 1)); excomposite.addExpansionListener(new ExpansionAdapter() { public void expansionStateChanged(ExpansionEvent e) { expandedStateChanged((ExpandableComposite) e.getSource()); } }); makeScrollableCompositeAware(excomposite); return excomposite; } /** * @author ericdp * Helper class that encapsulates data required when an action control changes state * */ private class ActionControlData { private List<IServicePolicy> spList; private List<IPolicyOperation> poList; // private IPolicyOperation po; public ActionControlData(List<IServicePolicy> spList, List<IPolicyOperation> poList) { this.spList = spList; this.poList = poList; } public List<IServicePolicy> getSpList() { return spList; } public void setSpList(List<IServicePolicy> spList) { this.spList = spList; } // // public IPolicyOperation getPo() { // return po; // } // // public void setPo(IPolicyOperation po) { // this.po = po; // } public List<IPolicyOperation> getPoList() { return poList; } public void setPoList(List<IPolicyOperation> poList) { this.poList = poList; } } /** * Makes the scrollable composite aware of this control, so expand/collapse * of the scrollable composite will move this control down/up accordingly * @param control the control to make the scrollable composite aware of */ private void makeScrollableCompositeAware(Control control) { ScrolledPageContent parentScrolledComposite = getParentScrolledComposite(control); if (parentScrolledComposite != null) { parentScrolledComposite.adaptChild(control); } } private ScrolledPageContent getParentScrolledComposite(Control control) { Control parent = control.getParent(); while (!(parent instanceof ScrolledPageContent) && parent != null) { parent = parent.getParent(); } if (parent instanceof ScrolledPageContent) { return (ScrolledPageContent) parent; } return null; } private final void expandedStateChanged(ExpandableComposite expandable) { ScrolledPageContent parentScrolledComposite = getParentScrolledComposite(expandable); if (parentScrolledComposite != null) { parentScrolledComposite.reflow(true); } } /** * @param parent * @return a scrollable composite containing an expandable content * */ private Composite createDetailsScrollPageContent(Composite parent) { int nColumns = 1; final ScrolledPageContent pageContent = new ScrolledPageContent(parent); GridLayout pageContLayout = new GridLayout(); pageContLayout.numColumns = nColumns; pageContLayout.marginHeight = 0; pageContLayout.marginWidth = 0; Composite composite = pageContent.getBody(); composite.setLayout(pageContLayout); excomposite = createExpandableComposite(composite, nColumns); Composite inner = new Composite(excomposite, SWT.NONE); inner.setFont(composite.getFont()); inner.setLayout(new GridLayout(nColumns, false)); excomposite.setClient(inner); //details policy tree for tertiary and higher level service policies detailsPolicyTree = new Tree(inner, SWT.BORDER | SWT.MULTI); detailsPolicyTree.addSelectionListener(this); GridData detailsPrefTreeGD = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); detailsPrefTreeGD.heightHint = 50; detailsPolicyTree.setLayoutData(detailsPrefTreeGD); detailsPolicyTree.setToolTipText(WstSPUIPluginMessages.TOOLTIP_PSP_DETAILSTREE); //make the scrollable composite aware of the tree so expand/collapse works properly makeScrollableCompositeAware(detailsPolicyTree); createPolicyOperationsComposite(composite); Composite descriptionAndDetailsComposite = new Composite(composite, SWT.NONE); descriptionAndDetailsComposite.setFont(composite.getFont()); GridLayout layout = new GridLayout(nColumns, false); layout.marginHeight = 0; layout.marginWidth = 0; descriptionAndDetailsComposite.setLayout(layout); GridData detailsGD4 = new GridData(SWT.FILL, SWT.END, true, true); descriptionAndDetailsComposite.setLayoutData(detailsGD4); makeScrollableCompositeAware(descriptionAndDetailsComposite); label_DetailsPanel_description = new Label(descriptionAndDetailsComposite, SWT.NONE); GridData detailsGD2 = new GridData(SWT.FILL, SWT.END, true, true); label_DetailsPanel_description.setLayoutData(detailsGD2); label_DetailsPanel_description.setText(WstSPUIPluginMessages.LABEL_SERVICEPOLICIES_DESCRIPTION); makeScrollableCompositeAware(label_DetailsPanel_description); text_DetailsPanel_description = new Text(descriptionAndDetailsComposite, SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY); GridData detailsGD = new GridData(SWT.FILL, SWT.END, true, true); detailsGD.heightHint = 75; detailsGD.widthHint = 220; text_DetailsPanel_description.setLayoutData(detailsGD); text_DetailsPanel_description.setToolTipText(WstSPUIPluginMessages.TOOLTIP_PSP_DESCRIPTION); makeScrollableCompositeAware(text_DetailsPanel_description); label_detailsPanel_dependancies = new Label(descriptionAndDetailsComposite, SWT.NONE); GridData detailsGD3 = new GridData(SWT.FILL, SWT.END, true, true); label_detailsPanel_dependancies.setLayoutData(detailsGD3); makeScrollableCompositeAware(label_detailsPanel_dependancies); label_detailsPanel_dependancies.setText(WstSPUIPluginMessages.LABEL_SERVICEPOLICIES_DEPENDENCIES); text_DetailsPanel_dependencies = new Text(descriptionAndDetailsComposite, SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY); text_DetailsPanel_dependencies.setToolTipText(WstSPUIPluginMessages.TOOLTIP_PSP_DEPENDENCIES); makeScrollableCompositeAware(text_DetailsPanel_dependencies); composite.setLayout(pageContLayout); GridData dependenciesGD = new GridData(SWT.FILL, SWT.END, true, true); dependenciesGD.heightHint = 75; dependenciesGD.widthHint = 220; text_DetailsPanel_dependencies.setLayoutData(dependenciesGD); return pageContent; } /** * Creates the scrollable composite that will contain widgets associated with a policy operation * @param parent the parent composite */ private void createPolicyOperationsComposite(Composite parent) { operationsScrolledComposite = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); operationsScrolledComposite.setExpandHorizontal(true); operationsScrolledComposite.setExpandVertical(true); GridData operationsScrolledCompositeGD = new GridData( GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); operationsScrolledCompositeGD.heightHint = 75; operationsScrolledComposite.setLayoutData(operationsScrolledCompositeGD); operationsComposite = new Composite(operationsScrolledComposite, SWT.NONE); operationsScrolledComposite.setContent(operationsComposite); GridLayout layout = new GridLayout(); layout.numColumns = 2; operationsComposite.setLayout(layout); operationsScrolledComposite.setMinSize(operationsComposite.computeSize(400, 100)); makeScrollableCompositeAware(operationsScrolledComposite); makeScrollableCompositeAware(operationsComposite); } public ServicePoliciesComposite(Composite parent, IProject project, SelectionListener listener) { super(parent, SWT.NONE); this.project = project; this.listener = listener; allErrors = new Hashtable<String, IStatus>(); helpSystem = PlatformUI.getWorkbench().getHelpSystem(); GridLayout parentLayout = new GridLayout(); parentLayout.numColumns = 2; parentLayout.horizontalSpacing = 0; this.setLayout(parentLayout); this.setLayoutData(new GridData(GridData.FILL_BOTH)); Label description = new Label(this, SWT.NONE); description.setText(WstSPUIPluginMessages.LABEL_SERVICEPOLICIES_PAGE_DESCRIPTION); GridData descGD = new GridData(SWT.BEGINNING, SWT.TOP, false, false, 2, 1); description.setLayoutData(descGD); masterComposite = new Composite(this, SWT.NONE); GridLayout masterLayout = new GridLayout(); masterLayout.numColumns = 1; masterLayout.horizontalSpacing = 0; masterComposite.setLayout(masterLayout); masterComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); detailsComposite = new Composite(this, SWT.NONE); GridLayout detailsLayout = new GridLayout(); detailsLayout.numColumns = 1; detailsLayout.horizontalSpacing = 0; detailsComposite.setLayout(detailsLayout); detailsComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); masterPolicyTree = new Tree(masterComposite, SWT.BORDER | SWT.MULTI); masterPolicyTree.setLayoutData(new GridData(GridData.FILL_BOTH)); masterPolicyTree.setToolTipText(WstSPUIPluginMessages.TOOLTIP_PSP_TREE); Composite othersComposite = createDetailsScrollPageContent(detailsComposite); GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true); othersComposite.setLayoutData(gridData); masterPolicyTree.addSelectionListener(this); List<IServicePolicy> policyList = platform.getRootServicePolicies(null); policyList = ServiceUtils.sortList(policyList); for (IServicePolicy policy : policyList) { addPolicy(policy, masterPolicyTree, true); } TreeItem[] treeItems = masterPolicyTree.getItems(); if (treeItems.length > 0) { //select the first item in the tree & fire event so UI is updated masterPolicyTree.setSelection(treeItems[0]); masterPolicyTree.notifyListeners(SWT.Selection, new Event()); } } /** * Sets the image on ti, if associated service policy defines an icon * it will will be used, otherwise default Folder/Leaf icons will be used * @param ti the TreeItem to set the image for * @param sp the service policy associated with ti * @param iconOverlays description of which overlays should be applied */ private void setImage(TreeItem ti, IServicePolicy sp, String[] iconOverlays) { Image i = (sp.getChildren().size() == 0) ? iconManager.getIconOverlay(iconManager.getLeafBaseUrl(), iconOverlays) : iconManager.getIconOverlay(iconManager.getFolderBaseUrl(), iconOverlays); if (sp.getDescriptor() != null) { String iconPathBundleID = null; String iconPath = null; iconPathBundleID = sp.getDescriptor().getIconBundleId(); iconPath = sp.getDescriptor().getIconPath(); if (iconPathBundleID != null && iconPath != null && iconPathBundleID.length() > 0 && iconPath.length() > 0) { Bundle b = Platform.getBundle(iconPathBundleID); i = iconManager.getIconOverlay(FileLocator.find(b, new Path(iconPath), null).toString(), iconOverlays); } } ti.setImage(i); // image has changed, notify change listeners so tree gets updated ti.notifyListeners(SWT.Modify, new Event()); } private boolean is4thLevelOrHigherPolicy(IServicePolicy sp) { return sp.getParentPolicy() != null && sp.getParentPolicy().getParentPolicy() != null && sp.getParentPolicy().getParentPolicy().getParentPolicy() != null; } private boolean is3rdLevelPolInMasterTreeWithChildren(List<IServicePolicy> spListInMasterTree) { return spListInMasterTree.get(0).getParentPolicy() != null && spListInMasterTree.get(0).getParentPolicy().getParentPolicy() != null && spListInMasterTree.get(0).getChildren().size() > 0; } /** * Add service policy sp and children of sp to the parent * @param sp the service policy to add * @param parent either a Tree (masterPolicyTree or DetailsPolicyTree), or a TreeItem * to add service policy children to * @param addUpToLevel3Only false if should add 4th and higher level * child policies */ private void addPolicy(IServicePolicy sp, Widget parent, boolean addUpToLevel3Only) { sp.addPolicyChildChangeListener(this); addStateListener(sp); if (addUpToLevel3Only && is4thLevelOrHigherPolicy(sp)) // don't add 4th level and higher branches, these are added on demand // to a different tree return; TreeItem ti; if (parent instanceof TreeItem) ti = new TreeItem((TreeItem) parent, SWT.NONE); else ti = new TreeItem((Tree) parent, SWT.NONE); ti.setText(sp.getDescriptor().getLongName()); ti.setData(sp); setImage(ti, sp, getIconOverlayInfo(sp, false)); List<IServicePolicy> childrenPolicyList = sp.getChildren(); childrenPolicyList = ServiceUtils.sortList(childrenPolicyList); for (IServicePolicy policy : childrenPolicyList) { addPolicy(policy, ti, addUpToLevel3Only); } } /** * Returns icon overlay information * @param sp the service policy that should have some overlay images associated with it * @param invalid true if the service policy is valid * @return String[] containing information about what overlays to apply to the icon that * is associated with sp */ private String[] getIconOverlayInfo(IServicePolicy sp, boolean invalid) { String[] overLays = new String[4]; IPolicyState polState = (project == null) ? sp.getPolicyState() : sp.getPolicyState(project); IPolicyStateEnum polEnum = (project == null) ? sp.getPolicyStateEnum() : sp.getPolicyStateEnum(project); if (!polState.isMutable()) overLays[0] = iconManager.lock; if ((sp.getStatus() != null && sp.getStatus().getSeverity() == IStatus.ERROR) || invalid) overLays[1] = iconManager.invalid; if ((sp.getStatus() != null && sp.getStatus().getSeverity() == IStatus.WARNING)) overLays[2] = iconManager.warning; if (polEnum != null) { if (polEnum.getEnumId().equals("org.eclipse.wst.service.policy.booleanEnum")) { //$NON-NLS-1$ if (policyHasIconSelectionOperationSelected(sp)) overLays[3] = iconManager.favorite; } } return overLays; } /** * @param sp */ private boolean policyHasIconSelectionOperationSelected(IServicePolicy sp) { boolean iconSelectionOperationSelected = false; List<IPolicyOperation> operationList = platformUI.getOperations(sp, project == null); for (IPolicyOperation operationItem : operationList) { if (operationItem.getOperationKind().equals(OperationKind.iconSelection)) { String stateID = operationItem.getStateItem(project); if (stateID.equals("org.eclipse.wst.true")) //$NON-NLS-1$ return true; } } return iconSelectionOperationSelected; } /** * Does anything necessary because the default button has been pressed. */ public void performDefaults() { initializeDefaults(); List<IServicePolicy> policyList = platform.getRootServicePolicies(null); policyList = ServiceUtils.sortList(policyList); masterPolicyTree.removeAll(); for (IServicePolicy policy : policyList) { addPolicy(policy, masterPolicyTree, true); } TreeItem[] treeItems = masterPolicyTree.getItems(); if (treeItems.length > 0) { //select the first item in the tree & fire event so UI is updated masterPolicyTree.setSelection(treeItems[0]); masterPolicyTree.notifyListeners(SWT.Selection, new Event()); error = validateAllPolicies((IServicePolicy) treeItems[0].getData()); } } private class ChildChangeEvent { public ChildChangeEvent(List<IServicePolicy> changedChildren, List<Boolean> added) { this.changedChildren = changedChildren; this.added = added; } private List<IServicePolicy> changedChildren; private List<Boolean> added; public List<IServicePolicy> getChangedChildren() { return changedChildren; } public void setChangedChildren(List<IServicePolicy> changedChildren) { this.changedChildren = changedChildren; } public List<Boolean> getAdded() { return added; } public void setAdded(List<Boolean> added) { this.added = added; } } /* (non-Javadoc) * @see org.eclipse.wst.ws.service.policy.listeners.IPolicyChildChangeListener#childChange(List<org.eclipse.wst.ws.service.policy.IServicePolicy>, List<java.lang.Boolean>) */ public void childChange(List<IServicePolicy> child, List<Boolean> added) { //ignore events unless we are in a complex operation if (!bComplexOpCompleted) //cache the event until complex operation completed listChildChangeEvents.add(new ChildChangeEvent(child, added)); } /** * @param child * @param added */ private void processChildChangeEvent(ChildChangeEvent cce, Hashtable<String, IServicePolicy> htTopLevelAddtions) { List<IServicePolicy> changedServicePolicyList = cce.getChangedChildren(); List<Boolean> changedServicePolicyAddedList = cce.getAdded(); for (int i = 0; i < changedServicePolicyList.size(); i++) { IServicePolicy nextChangedServicePolicy = changedServicePolicyList.get(i); boolean added = changedServicePolicyAddedList.get(i); if (!added) { //delete node processChildChangeEventRemoveServicePolicy(nextChangedServicePolicy); } else { //an addition, only process top level additions as this is a recursive operation (adds children too) if (htTopLevelAddtions.containsKey(nextChangedServicePolicy.getId())) { processChildChangeEventAddServicePolicy(nextChangedServicePolicy); } } } } /** * @param nextChangedServicePolicy */ private void processChildChangeEventRemoveServicePolicy(IServicePolicy nextChangedServicePolicy) { boolean is4thLevelOrHigher = is4thLevelOrHigherPolicy(nextChangedServicePolicy); removeStateListener(nextChangedServicePolicy); if (is4thLevelOrHigher) { if (detailsPolicyTree.isVisible()) { TreeItem[] children = detailsPolicyTree.getItems(); TreeItem found = null; for (int i = 0; i < children.length; i++) { found = findPolicy(nextChangedServicePolicy, children[i]); if (found != null) break; } if (found != null && !found.isDisposed()) { processChildChangeEventDeleteTreeItem(found); } } } else { TreeItem[] children = masterPolicyTree.getItems(); TreeItem found = null; for (int i = 0; i < children.length; i++) { found = findPolicy(nextChangedServicePolicy, children[i]); if (found != null) break; } if (found != null && !found.isDisposed()) { processChildChangeEventDeleteTreeItem(found); } } } /** * Delete the item, and choose set a new selection as appropriate from one of the policy trees * @param deleteItem */ private void processChildChangeEventDeleteTreeItem(TreeItem deleteItem) { Tree parentTree = deleteItem.getParent(); Tree selectionTree = parentTree; TreeItem parentTreeItem = deleteItem.getParentItem(); //index of found in the tree int idx = (parentTreeItem == null) ? parentTree.indexOf(deleteItem) : parentTreeItem.indexOf(deleteItem); //is index the last index in the tree boolean isLastIndex = (parentTreeItem == null) ? parentTree.indexOf(deleteItem) == parentTree.getItemCount() - 1 : parentTreeItem.indexOf(deleteItem) == parentTreeItem.getItemCount() - 1; //number of siblings int siblingsCount = (parentTreeItem == null) ? parentTree.getItemCount() - 1 : parentTreeItem.getItemCount() - 1; boolean hasParent = (parentTreeItem == null) ? parentTree.getItemCount() == 0 : parentTreeItem.getItemCount() == 0; deleteItem.dispose(); parentTree.redraw(); TreeItem selectItem = null; if (siblingsCount == 0) { if (hasParent) { //no siblings, select parent if (parentTreeItem == null) selectItem = parentTree.getItem(0); else selectItem = parentTreeItem; } else { if (parentTree == detailsPolicyTree) //select something from master tree if (masterPolicyTree.getItems().length > 0) { selectItem = masterPolicyTree.getItem(0); selectionTree = masterPolicyTree; } } } else { if (parentTreeItem == null) { if (isLastIndex) selectItem = parentTree.getItem(idx - 1); else selectItem = parentTree.getItem(idx); } else { if (isLastIndex) selectItem = parentTreeItem.getItem(idx - 1); else selectItem = parentTreeItem.getItem(idx); } } if (selectItem != null) { selectionTree.setSelection(selectItem); selectionTree.notifyListeners(SWT.Selection, new Event()); } } /** * @param policyToAdd */ private void processChildChangeEventAddServicePolicy(IServicePolicy policyToAdd) { boolean is4thLevelOrHigher = is4thLevelOrHigherPolicy(policyToAdd); IServicePolicy parent = policyToAdd.getParentPolicy(); if (is4thLevelOrHigher) { if (detailsPolicyTree.isVisible()) { TreeItem[] children = detailsPolicyTree.getItems(); TreeItem found = null; for (int i = 0; i < children.length; i++) { found = findPolicy(parent, children[i]); if (found != null) break; } if (found != null && !found.isDisposed()) { addPolicy(policyToAdd, found, false); } } } else { //less than 4th level policy TreeItem[] children = masterPolicyTree.getItems(); TreeItem found = null; for (int i = 0; i < children.length; i++) { found = findPolicy(parent, children[i]); if (found != null) break; } if (found != null && !found.isDisposed()) { addPolicy(policyToAdd, found, false); } } } /** * Find the policy within the tree ti * @param policyToFind */ private TreeItem findPolicy(IServicePolicy policyToFind, TreeItem ti) { TreeItem toReturn = null; if (ti == null || !(ti.getData() instanceof IServicePolicy)) return toReturn; IServicePolicy sp = (IServicePolicy) ti.getData(); if (sp.getId().equals(policyToFind.getId())) return ti; else { TreeItem[] tiChildren = ti.getItems(); for (int i = 0; i < tiChildren.length; i++) { toReturn = findPolicy(policyToFind, tiChildren[i]); if (toReturn != null) break; } } return toReturn; } /** * Initializes states of the controls using default values in the preference * store. */ private void initializeDefaults() { if (project == null) platform.restoreDefaults(); else platform.restoreDefaults(project); } /* (non-Javadoc) * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { if (e.getSource() == masterPolicyTree || e.getSource() == detailsPolicyTree) { TreeItem[] selectedItems; if (e.getSource() == masterPolicyTree) selectedItems = masterPolicyTree.getSelection(); else selectedItems = detailsPolicyTree.getSelection(); //possible that an event is fired and no nodes selected if (!(selectedItems.length > 0)) return; List<IServicePolicy> sp = new Vector<IServicePolicy>(); for (int i = 0; i < selectedItems.length; i++) { sp.add((IServicePolicy) selectedItems[i].getData()); } //update the context sensitive help updateCSH(sp); updateInfoPanels(sp); if (e.getSource() == masterPolicyTree) { // if selected node in master tree is 3rd level & has // children, populate details tree if (is3rdLevelPolInMasterTreeWithChildren(sp)) { populateDetailsPolicyTree(sp); } else { //if expandable composite was visible, collapse and set invisible if (excomposite.getVisible()) { excomposite.setVisible(false); excomposite.setExpanded(false); expandedStateChanged(excomposite); } } } addActionButtons(sp); lastSelectedSp = sp; } else { // an action control fired a change event Control actionControl = (Control) e.getSource(); Object oldData = actionControl.getData(); updatePolicy(actionControl); if (lastSelectedSp != null) { addActionButtons(lastSelectedSp); } //policy updates might delete nodes in the tree, so make sure action control not disposed IServicePolicy changedSP = null; if (!actionControl.isDisposed()) changedSP = ((ActionControlData) actionControl.getData()).getSpList().get(0); error = validateAllPolicies(changedSP); //inform listeners that a control has changed, as composite may be in error now listener.widgetSelected(e); setFocusForLastControl(oldData); } } // The UI is continually recreating the action buttons, so the focus is // is lost when an action button is selected. This method attempts // to find the newly created control that is associated with operation // that was previously selected. The focus is then reestablished for this // control. private void setFocusForLastControl(Object oldData) { if (oldData != null && oldData instanceof ActionControlData) { ActionControlData controlData = (ActionControlData) oldData; IPolicyOperation operation = controlData.getPoList().get(0); Control[] compositeControls = operationsComposite.getChildren(); for (Control newControl : compositeControls) { Object newData = newControl.getData(); if (newData != null && newData instanceof ActionControlData) { IPolicyOperation newOperation = ((ActionControlData) newData).poList.get(0); if (newOperation == operation) { newControl.setFocus(); break; } } } } } /** * Populate the details policy tree with sp and their children * @param sp a list of top level details tree service policies */ private void populateDetailsPolicyTree(List<IServicePolicy> sp) { List<IServicePolicy> childpolicyList = sp.get(0).getChildren(); detailsPolicyTree.removeAll(); for (IServicePolicy policy : childpolicyList) { addPolicy(policy, detailsPolicyTree, false); } // update details preference tree TreeItem[] treeItems = detailsPolicyTree.getItems(); for (int i = 0; i < treeItems.length; i++) { updateValidStates(treeItems[i], true); } excomposite.setVisible(true); excomposite .setText(sp.get(0).getDescriptor().getLongName() + " (" + WstSPUIPluginMessages.TEXT_DETAILS + ")"); //$NON-NLS-1$ //$NON-NLS-2$ // text has changed, so need to force layout so updated excomposite.layout(); } /** * Updates the details and dependencies panels for the first service * policy in spList * @param spList a list of selected service policies */ private void updateInfoPanels(List<IServicePolicy> spList) { String desc = (spList.get(0) == null || spList.get(0).getDescriptor() == null || spList.get(0).getDescriptor().getDescription() == null) ? "" //$NON-NLS-1$ : spList.get(0).getDescriptor().getDescription(); text_DetailsPanel_description.setText(desc); text_DetailsPanel_dependencies.setText(getDependanciesText(spList.get(0))); } /** * Updates the context sensitive help for the composite with * that defined for the first policy in spList (or a parent of * first policy in spList policy does not define any CSH) * @param spList the list of selected service policies */ private void updateCSH(List<IServicePolicy> spList) { String CSH_ID = (spList.get(0) == null || spList.get(0).getDescriptor() == null) ? null : spList.get(0).getDescriptor().getContextHelpId(); IServicePolicy parentSP = spList.get(0); while ((CSH_ID == null || CSH_ID.length() == 0)) { parentSP = parentSP.getParentPolicy(); if (parentSP == null) break; CSH_ID = (parentSP.getDescriptor() == null) ? null : parentSP.getDescriptor().getContextHelpId(); } if (CSH_ID == null) CSH_ID = INFOPOP_SPPP_PAGE; helpSystem.setHelp(this, CSH_ID); } /** * Validates all Service Policies in the model * * @param IServicePolicy * the focus policy, i.e. one that changed state * @return IStatus null if no Service policies in error, otherwise a Service * Policy error (the focucPolicy error if it is in error). * Postcondition- the error property is updated. */ private IStatus validateAllPolicies(IServicePolicy focusPolicy) { // remove all errors as going to re-validate allErrors.clear(); // re-validate all policies in model List<IServicePolicy> servicePolicyList = platform.getRootServicePolicies(null); for (IServicePolicy servicePolicyItem : servicePolicyList) { validatePolicy(servicePolicyItem); } // get the error for the selected/focusPolicy IStatus error = (focusPolicy == null) ? null : allErrors.get(focusPolicy.getId()); //if there was no error for the selected/focusPolicy, get the first error in the list of errors if (error == null) if (!allErrors.isEmpty()) error = allErrors.get(allErrors.keys().nextElement()); // update master policy tree nodes denoting node error status TreeItem[] treeItems = masterPolicyTree.getItems(); for (int i = 0; i < treeItems.length; i++) { updateValidStates(treeItems[i], false); } if (detailsPolicyTree.isVisible()) { // update details preference tree nodes denoting node error status treeItems = detailsPolicyTree.getItems(); for (int i = 0; i < treeItems.length; i++) { updateValidStates(treeItems[i], false); } } return error; } /** * Updates the policy trees to reflect valid or invalid states, invalid states are * propagated up through the tree, and up to master tree if updateDetailsOnly is false * @param ti the TreeItem to update, updates ti and all it's children * @param updateDetailsOnly if false then propagate invalid states into * master tree */ private void updateValidStates(TreeItem ti, boolean updateDetailsOnly) { // assume tree item is valid for now IServicePolicy sp = (IServicePolicy) ti.getData(); setValidPolicyState(ti); if (allErrors.containsKey(sp.getId())) setInvalidPolicyState(ti, updateDetailsOnly); TreeItem[] treeItems = ti.getItems(); if (ti.getItems().length == 0) { if (sp.getChildren().size() != 0 && policyChildrenInvalid(sp)) setInvalidPolicyState(ti, updateDetailsOnly); } else { for (int i = 0; i < treeItems.length; i++) { updateValidStates(treeItems[i], updateDetailsOnly); } } } /** * Checks whether the sp has invalid children * @param sp the service policy whose children may be invalid * @return true if sp has an invalid child */ private boolean policyChildrenInvalid(IServicePolicy sp) { boolean toReturn = false; List<IServicePolicy> servicePolicyList = sp.getChildren(); for (IServicePolicy servicePolicyItem : servicePolicyList) { if (allErrors.containsKey(servicePolicyItem.getId())) return true; else toReturn = policyChildrenInvalid(servicePolicyItem); } return toReturn; } /** * Validates the Service Policies for the sp and all it's children, creating * error status objects for any unsatisfied relationships * * @param sp * the service policy to validate */ private void validatePolicy(IServicePolicy sp) { String operationLongName; String operationSelectionLongName; String dependantPolicyShortName; List<IPolicyRelationship> relationShipList = sp.getRelationships(); String currentValueID = null; if (relationShipList != null && relationShipList.size() > 0) { for (IPolicyRelationship relationShipItem : relationShipList) { //operations for the policy List<IPolicyOperation> policyOperationsList = platformUI .getOperations(relationShipItem.getPolicyEnumerationList().getPolicy(), project == null); //default operation name operationLongName = ""; //$NON-NLS-1$ for (IPolicyOperation policyOperationItem : policyOperationsList) { if (policyOperationItem.isUseDefaultData()) { operationLongName = policyOperationItem.getDescriptor().getLongName(); currentValueID = policyOperationItem.getStateItem(project); break; } } // a list of states List<IStateEnumerationItem> spStateEnumerationList = relationShipItem.getPolicyEnumerationList() .getEnumerationList(); // a list of related policies and their acceptable states to satisfy a stateEnumerationItem in spStateEnumerationList List<IPolicyEnumerationList> relatedPolicies = relationShipItem.getRelatedPolicies(); for (IStateEnumerationItem stateEnumerationItem : spStateEnumerationList) { if (stateEnumerationItem.getId() != currentValueID) continue; //long name of the related policy operation operationSelectionLongName = stateEnumerationItem.getLongName(); for (IPolicyEnumerationList relatedPolicyEnumerationItem : relatedPolicies) { dependantPolicyShortName = relatedPolicyEnumerationItem.getPolicy().getDescriptor() .getShortName(); //the list of related sp states that satisfy the stateEnumerationItem List<IStateEnumerationItem> relatedSPStateEnumerationList = relatedPolicyEnumerationItem .getEnumerationList(); //the list of valid ids for the related service policy operation List<String> validIds = new Vector<String>(); for (int i = 0; i < relatedSPStateEnumerationList.size(); i++) { validIds.add(relatedSPStateEnumerationList.get(i).getId()); } //get the current value of the related service policy default operation String currentItemID = ""; //$NON-NLS-1$ List<IPolicyOperation> relatedServicePolicyPolicyOperationsList = platformUI .getOperations(relatedPolicyEnumerationItem.getPolicy(), project == null); IPolicyOperation relatedPolicyOperationItem = null; for (IPolicyOperation relatedServicePolicyPolicyOperationItem : relatedServicePolicyPolicyOperationsList) { if (relatedServicePolicyPolicyOperationItem.isUseDefaultData()) { currentItemID = relatedServicePolicyPolicyOperationItem.getStateItem(project); relatedPolicyOperationItem = relatedServicePolicyPolicyOperationItem; break; } } if (!validIds.contains(currentItemID)) { // policy state is invalid IStatus error = createUnsatisfiedRelationshipError(sp, operationLongName, operationSelectionLongName, dependantPolicyShortName, relatedPolicyOperationItem, relatedSPStateEnumerationList); allErrors.put(sp.getId(), error); } } } } } List<IServicePolicy> servicePolicyChildrenList = sp.getChildren(); for (IServicePolicy servicePolicyChildrenItem : servicePolicyChildrenList) { validatePolicy(servicePolicyChildrenItem); } } /** * Sets the icon for the ti denoting it as valid * @param ti a valid tree item */ private void setValidPolicyState(TreeItem ti) { IServicePolicy sp = (IServicePolicy) ti.getData(); setImage(ti, sp, getIconOverlayInfo(sp, false)); } /** * Sets the icon for ti denoting it as invalid, as well as ti's parent tree items * @param ti an invalid tree item * @param updateDetailsOnly true indicates do not update parent tree items only in master tree */ private void setInvalidPolicyState(TreeItem ti, boolean updateDetailsOnly) { IServicePolicy SP = (IServicePolicy) ti.getData(); setImage(ti, SP, getIconOverlayInfo(SP, true)); TreeItem parent; if (ti.getParent() == masterPolicyTree || updateDetailsOnly) parent = ti.getParentItem(); else parent = (ti.getParentItem() == null && SP.getParentPolicy() != null) ? getParentInMasterTree(SP.getId()) : ti.getParentItem(); while (parent != null) { setImage(parent, (IServicePolicy) parent.getData(), getIconOverlayInfo((IServicePolicy) parent.getData(), true)); if (updateDetailsOnly) parent = parent.getParentItem(); else { parent = (parent.getParentItem() == null && ((IServicePolicy) parent.getData()).getParentPolicy() != null) ? getParentInMasterTree( ((IServicePolicy) parent.getData()).getParentPolicy().getId()) : parent.getParentItem(); } } } /** * Creates an error status object for the sp. The error message contains information about * an unsatisfied relationship * @param sp * @param operationLongName * @param operationSelectionLongName * @param dependantPolicyShortName * @param relatedOperation * @param relatedOperationAcceptableValues * @return an Error status */ private IStatus createUnsatisfiedRelationshipError(IServicePolicy sp, String operationLongName, String operationSelectionLongName, String dependantPolicyShortName, IPolicyOperation relatedOperation, List<IStateEnumerationItem> relatedOperationAcceptableValues) { String dependantOperationShortName; String dependantOperationSelectionShortNameList; dependantOperationShortName = relatedOperation.getDescriptor().getShortName(); dependantOperationSelectionShortNameList = new String(); for (int i = 0; i < relatedOperationAcceptableValues.size(); i++) { IStateEnumerationItem item = relatedOperationAcceptableValues.get(i); if (i != 0) dependantOperationSelectionShortNameList += " | "; //$NON-NLS-1$ dependantOperationSelectionShortNameList += item.getShortName(); } String[] args = { sp.getDescriptor().getLongName(), operationLongName, operationSelectionLongName, dependantPolicyShortName, dependantOperationShortName, dependantOperationSelectionShortNameList }; IStatus error = new Status(Status.ERROR, ServicePolicyActivatorUI.PLUGIN_ID, NLS.bind(WstSPUIPluginMessages.SERVICEPOLICIES_DEPENDENCY_ERROR, args)); return error; } /** * @param parentID the id to find in the master tree * @return a TreeItem with the id in the master tree */ private TreeItem getParentInMasterTree(String parentID) { TreeItem parent = null; TreeItem[] rootNodes = masterPolicyTree.getItems(); for (int i = 0; i < rootNodes.length; i++) { parent = findChildNode(rootNodes[i], parentID); if (parent != null) break; } return parent; } /** * Returns a TreeItem associated with a child policy of ti * @param ti * @param id the policy id of a child node of ti * @return null if there is no child policy matching id */ private TreeItem findChildNode(TreeItem ti, String id) { TreeItem toReturn = null; if (((IServicePolicy) ti.getData()).getId().equals(id)) { toReturn = ti; } else { TreeItem[] childItems = ti.getItems(); for (int i = 0; i < childItems.length; i++) { toReturn = findChildNode(childItems[i], id); } } return toReturn; } /** * Returns dependancy information about sp, that is information about * it's relationships (if any) with other service policies * @param sp the service policy to get dependency info about * @return */ private String getDependanciesText(IServicePolicy sp) { // the relationships defined for the policy List<IPolicyRelationship> relationShipList = sp.getRelationships(); if (relationShipList == null || relationShipList.size() == 0) return WstSPUIPluginMessages.SERVICEPOLICIES_DEPENDENCIES_NONE; String toReturn = new String(); String operationLongName; String operationSelectionLongName; String dependantPolicyShortName; String dependantOperationShortName; String dependantOperationSelectionShortNameList; for (IPolicyRelationship relationShipItem : relationShipList) { List<IPolicyOperation> policyOperationsList = platformUI .getOperations(relationShipItem.getPolicyEnumerationList().getPolicy(), project == null); operationLongName = ""; //$NON-NLS-1$ for (IPolicyOperation policyOperationItem : policyOperationsList) { if (policyOperationItem.isUseDefaultData()) { operationLongName = policyOperationItem.getDescriptor().getLongName(); break; } } // policies associated with the relationship item List<IPolicyEnumerationList> relatedPolicies = relationShipItem.getRelatedPolicies(); List<IStateEnumerationItem> spStateEnumerationList = relationShipItem.getPolicyEnumerationList() .getEnumerationList(); for (IStateEnumerationItem stateEnumerationItem : spStateEnumerationList) { operationSelectionLongName = stateEnumerationItem.getLongName(); for (IPolicyEnumerationList relatedPolicyEnumerationItem : relatedPolicies) { dependantPolicyShortName = relatedPolicyEnumerationItem.getPolicy().getDescriptor() .getShortName(); List<IStateEnumerationItem> relatedSPStateEnumerationList = relatedPolicyEnumerationItem .getEnumerationList(); List<IPolicyOperation> relatedPolicyOperationsList = platformUI .getOperations(relatedPolicyEnumerationItem.getPolicy(), (project == null)); dependantOperationShortName = ""; //$NON-NLS-1$ for (IPolicyOperation relatedPolicyOperationItem : relatedPolicyOperationsList) { if (relatedPolicyOperationItem.isUseDefaultData()) dependantOperationShortName = relatedPolicyOperationItem.getDescriptor().getShortName(); break; } dependantOperationSelectionShortNameList = new String(); for (int i = 0; i < relatedSPStateEnumerationList.size(); i++) { IStateEnumerationItem item = relatedSPStateEnumerationList.get(i); if (i != 0) dependantOperationSelectionShortNameList += " | "; //$NON-NLS-1$ dependantOperationSelectionShortNameList += item.getShortName(); } String[] args = { operationLongName, operationSelectionLongName, dependantPolicyShortName, dependantOperationShortName, dependantOperationSelectionShortNameList }; toReturn += NLS.bind(WstSPUIPluginMessages.SERVICEPOLICIES_DEPENDENCIES, args) + "\r\n"; //$NON-NLS-1$ } } } return toReturn; } /** * Saves to the preference store the widget data (widget data contains all * service policy operations the control applies to) * @param actionControl a widget who's data needs to be saved to the preference store * */ private void updatePolicy(Control actionControl) { List<IPolicyOperation> policyOperationList = ((ActionControlData) actionControl.getData()).getPoList(); IPolicyOperation po0 = policyOperationList.get(0); List<IServicePolicy> servicePolicyList = ((ActionControlData) actionControl.getData()).getSpList(); if (actionControl instanceof Button && po0.getOperationKind().equals(OperationKind.complex)) updateComplexOperationPreference(po0, servicePolicyList); else for (IPolicyOperation policyOperationItem : policyOperationList) { updateSelectionOperationPreference(actionControl, policyOperationItem); } } public boolean okToLeave() { return allErrors.size() == 0; } /** * Saves value of enumeration, selection, and iconselection type operations * to the preference store * @param actionControl the action control containing the value to set for the preference * @param po * @param sp */ private void updateSelectionOperationPreference(Control actionControl, IPolicyOperation po) { String selectedValue; // We are updating the state of a service policy. We don't want this // update to trigger our state change listener. enableStateListener(false); if (actionControl instanceof Combo) { selectedValue = ((Combo) actionControl).getText(); List<IStateEnumerationItem> enumItemList = ServicePolicyPlatform.getInstance() .getStateEnumeration(po.getEnumerationId()); for (IStateEnumerationItem enumItem : enumItemList) { if (enumItem.getLongName().equals(selectedValue)) { po.setStateItem(project, enumItem.getId()); break; } } } else { if (((Button) actionControl).getSelection()) { po.setStateItem(project, "org.eclipse.wst.true"); //$NON-NLS-1$ } else po.setStateItem(project, "org.eclipse.wst.false"); //$NON-NLS-1$ } // Reenable our state change listener. enableStateListener(true); } private void addStateListener(IServicePolicy policy) { if (stateChangePolicySet.contains(policy)) return; if (project == null) { policy.getPolicyState().addPolicyStateChangeListener(stateChangeListener, false); } else { policy.getPolicyState(project).addPolicyStateChangeListener(stateChangeListener, false); } stateChangePolicySet.add(policy); } private void removeStateListener(IServicePolicy policy) { if (stateChangePolicySet.contains(policy)) return; if (project == null) { policy.getPolicyState().removePolicyStateChangeListener(stateChangeListener); } else { policy.getPolicyState(project).removePolicyStateChangeListener(stateChangeListener); } stateChangePolicySet.remove(policy); } private void enableStateListener(boolean enabled) { stateChangeEnabled = enabled; } /** * Launches the complex operation for the list of service policies * @param po a "complex" policy operation * @param sps a list of service policies to apply the operation to */ private void updateComplexOperationPreference(IPolicyOperation po, List<IServicePolicy> sps) { //complex operations can result in added and deleted nodes, cache them until operation completed bComplexOpCompleted = false; listChildChangeEvents = new Vector<ChildChangeEvent>(); try { po.launchOperation(sps); } catch (RuntimeException e) { //just want to make sure finally clause is executed so can update UI of additions/deletions } finally { bComplexOpCompleted = true; Hashtable<String, IServicePolicy> topLevelAdds = getHighestLevelChildren(listChildChangeEvents, true); for (ChildChangeEvent childChangeEventItem : listChildChangeEvents) { processChildChangeEvent(childChangeEventItem, topLevelAdds); } } } private Hashtable<String, IServicePolicy> getHighestLevelChildren(List<ChildChangeEvent> htChildChangeEvents, boolean forAddOnly) { Hashtable<String, IServicePolicy> toReturn = new Hashtable<String, IServicePolicy>(); Iterator<ChildChangeEvent> elements = htChildChangeEvents.iterator(); ChildChangeEvent next; Hashtable<String, IServicePolicy> allSps = new Hashtable<String, IServicePolicy>(); while (elements.hasNext()) { next = elements.next(); List<IServicePolicy> changedChildrenList = next.getChangedChildren(); List<Boolean> addedList = next.getAdded(); for (int i = 0; i < changedChildrenList.size(); i++) { if (forAddOnly && addedList.get(i).booleanValue() == true) allSps.put(changedChildrenList.get(i).getId(), changedChildrenList.get(i)); } } Enumeration<IServicePolicy> servicePolicyElements = allSps.elements(); IServicePolicy nextServicePolicyElement; while (servicePolicyElements.hasMoreElements()) { nextServicePolicyElement = servicePolicyElements.nextElement(); if (nextServicePolicyElement.getParentPolicy() == null || !allSps.containsKey(nextServicePolicyElement.getParentPolicy().getId())) { toReturn.put(nextServicePolicyElement.getId(), nextServicePolicyElement); } } return toReturn; } public void dispose() { super.dispose(); iconManager.dispose(); for (IServicePolicy policy : stateChangePolicySet) { IPolicyState state = project == null ? policy.getPolicyState() : policy.getPolicyState(project); state.removePolicyStateChangeListener(stateChangeListener); } } /** * Create UI widgets for operations applicable to the list of service policies sp * @param spList the list of service policies to create UI widgets, the UI widgets * will be used to define operations/preferences to apply to the service policies in the list */ private void addActionButtons(List<IServicePolicy> spList) { // remove existing action controls Control[] toRemove = operationsComposite.getChildren(); for (int i = 0; i < toRemove.length; i++) { toRemove[i].dispose(); } List<List<IPolicyOperation>> policyOperationListList = platformUI.getOperationsList(spList, (project == null)); for (List<IPolicyOperation> policyOperationList : policyOperationListList) { if (policyOperationList.size() > 0) { if (policyOperationList.get(0).getOperationKind() == IPolicyOperation.OperationKind.complex) { addComplexOperationUI(policyOperationList, spList); } else addSelectionOperationUI(policyOperationList, spList); } } // just removed and added some controls so force composite // to re-layout it's controls operationsScrolledComposite.setMinSize(operationsComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); operationsComposite.layout(); } /** * Creates UI widgets for policy operations of enumeration, selection, and * iconselection types * @param po the policy operation to create a UI widget for * @param sp the service policies this operation will apply to */ private void addSelectionOperationUI(List<IPolicyOperation> pos, List<IServicePolicy> sps) { //use the first operation instance in the list for data IPolicyOperation po0 = pos.get(0); //IServicePolicy sp0 = pos.get(0).getServicePolicy(); IDescriptor d = po0.getDescriptor(); Control selectionControl; if (po0.getOperationKind() == IPolicyOperation.OperationKind.enumeration) { Label l = new Label(operationsComposite, SWT.NONE); l.setText(d.getLongName() + ":"); //$NON-NLS-1$ GridData comboGD = new GridData(SWT.FILL, SWT.FILL, true, false); Combo cb = new Combo(operationsComposite, SWT.DROP_DOWN | SWT.READ_ONLY); cb.setLayoutData(comboGD); selectionControl = cb; cb.addSelectionListener(this); List<IStateEnumerationItem> enumItemList = ServicePolicyPlatform.getInstance() .getStateEnumeration(po0.getEnumerationId()); for (IStateEnumerationItem enumItem : enumItemList) { cb.add(enumItem.getLongName()); } l.setEnabled(po0.isEnabled(sps)); cb.setEnabled(po0.isEnabled(sps)); if (cb.isEnabled()) cb.setText(getEnumerationOperationCurrentSelection(po0)); } else { // a selection or icon Button checkBox = new Button(operationsComposite, SWT.CHECK); selectionControl = checkBox; checkBox.addSelectionListener(this); GridData checkBoxGD = new GridData(); checkBoxGD.horizontalSpan = 2; checkBox.setLayoutData(checkBoxGD); checkBox.setText(d.getLongName()); checkBox.setEnabled(po0.isEnabled(sps)); if (checkBox.isEnabled()) checkBox.setSelection(getSelectionOperationCurrentSelection(po0)); } selectionControl.setData(new ActionControlData(sps, pos)); } /** * @param sp a service policy with a selection or iconselection operation defined * @return true if the operation is currently selected */ private boolean getSelectionOperationCurrentSelection(IPolicyOperation po) { return po.getStateItem(project).equals("org.eclipse.wst.true") ? true : false; //$NON-NLS-1$ } /** * @param sp a service policy with an enumeration operation defined * @return the currently selected enumeration item */ private String getEnumerationOperationCurrentSelection(IPolicyOperation po) { String currentSelection = ""; //$NON-NLS-1$ List<IStateEnumerationItem> enumItemList = ServicePolicyPlatform.getInstance() .getStateEnumeration(po.getEnumerationId()); for (IStateEnumerationItem enumItem : enumItemList) { if (enumItem.getId().equals(po.getStateItem(project))) { currentSelection = enumItem.getLongName(); break; } } return currentSelection; } /** * Creates UI widgets for policy operations of complex type * @param po the policy operation to create a UI widget for * @param sps the service policies this operation will apply to */ private void addComplexOperationUI(List<IPolicyOperation> pos, List<IServicePolicy> sps) { IPolicyOperation po0 = pos.get(0); IDescriptor d = po0.getDescriptor(); Button pushButton = new Button(operationsComposite, SWT.PUSH); GridData pushButtonGD = new GridData(); pushButtonGD.horizontalSpan = 2; pushButton.setLayoutData(pushButtonGD); pushButton.setText(d.getLongName()); pushButton.addSelectionListener(this); pushButton.setData(new ActionControlData(sps, pos)); pushButton.setEnabled(po0.isEnabled(sps)); } /* (non-Javadoc) * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetDefaultSelected(SelectionEvent e) { } /** * @return the error that should be shown, if there are multiple validation errors, * return the validation error for a service policy that just changes state (often the * selected service policy) */ public IStatus getError() { return error; } private class StateChangeListener implements IPolicyStateChangeListener { public void policyStateChange(IServicePolicy policy, String key, String oldValue, String newValue) { // We are not enabled for state change events so we will ignore this event. if (!stateChangeEnabled) return; error = validateAllPolicies(policy); //inform listeners that a control has changed, as composite may be in error now listener.widgetSelected(null); } } }