summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorTobias Schwarz2012-06-26 05:05:37 (EDT)
committer Uwe Stieber2012-06-26 05:05:37 (EDT)
commit359418e7c9e14ea3dffe1ebf298d39d1b6cf95f7 (patch)
tree829bc12cd0cd7d43f7ad64d970be6175b1f980d7
parente490d8b26826c42bdec56289b11fc87108018b99 (diff)
downloadorg.eclipse.tcf-359418e7c9e14ea3dffe1ebf298d39d1b6cf95f7.zip
org.eclipse.tcf-359418e7c9e14ea3dffe1ebf298d39d1b6cf95f7.tar.gz
org.eclipse.tcf-359418e7c9e14ea3dffe1ebf298d39d1b6cf95f7.tar.bz2
Target Explorer: ADD generic category content handling
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/interfaces/nodes/IPeerModelProperties.java2
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/handler/DeleteHandler.java1001
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/navigator/ContentProviderDelegate.java137
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/categories/Category.java279
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/ICategory.java74
5 files changed, 787 insertions, 706 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/interfaces/nodes/IPeerModelProperties.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/interfaces/nodes/IPeerModelProperties.java
index 68638e3..51705ea 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/interfaces/nodes/IPeerModelProperties.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/interfaces/nodes/IPeerModelProperties.java
@@ -70,7 +70,7 @@ public interface IPeerModelProperties {
/**
* Property: The peer type.
*/
- public static final String PROP_TYPE = "Type"; //$NON-NLS-1$
+ public static final String PROP_TYPE = "type"; //$NON-NLS-1$
/**
* Property: The peer visible state.
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/handler/DeleteHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/handler/DeleteHandler.java
index a920432..a2b0b05 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/handler/DeleteHandler.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/handler/DeleteHandler.java
@@ -1,488 +1,513 @@
-/*******************************************************************************
- * Copyright (c) 2012 Wind River Systems, Inc. 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:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tcf.te.tcf.ui.handler;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeSelection;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.tcf.protocol.Protocol;
-import org.eclipse.tcf.te.runtime.callback.Callback;
-import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback;
-import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
-import org.eclipse.tcf.te.runtime.persistence.interfaces.IURIPersistenceService;
-import org.eclipse.tcf.te.runtime.properties.PropertiesContainer;
-import org.eclipse.tcf.te.runtime.services.ServiceManager;
-import org.eclipse.tcf.te.runtime.statushandler.StatusHandlerManager;
-import org.eclipse.tcf.te.runtime.statushandler.interfaces.IStatusHandler;
-import org.eclipse.tcf.te.runtime.statushandler.interfaces.IStatusHandlerConstants;
-import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel;
-import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
-import org.eclipse.tcf.te.tcf.locator.interfaces.services.ILocatorModelRefreshService;
-import org.eclipse.tcf.te.tcf.locator.model.Model;
-import org.eclipse.tcf.te.tcf.ui.activator.UIPlugin;
-import org.eclipse.tcf.te.tcf.ui.help.IContextHelpIds;
-import org.eclipse.tcf.te.tcf.ui.nls.Messages;
-import org.eclipse.tcf.te.ui.views.Managers;
-import org.eclipse.tcf.te.ui.views.ViewsUtil;
-import org.eclipse.tcf.te.ui.views.interfaces.ICategory;
-import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
-import org.eclipse.tcf.te.ui.views.interfaces.categories.ICategorizable;
-import org.eclipse.tcf.te.ui.views.interfaces.categories.ICategoryManager;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/**
- * Delete handler implementation.
- */
-public class DeleteHandler extends AbstractHandler {
- // Remember the shell from the execution event
- private Shell shell = null;
-
- /* (non-Javadoc)
- * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
- */
- @Override
- public Object execute(ExecutionEvent event) throws ExecutionException {
- // Get the shell
- shell = HandlerUtil.getActiveShell(event);
- // Get the current selection
- ISelection selection = HandlerUtil.getCurrentSelection(event);
- // Delete the selection
- if (selection != null) delete(selection, new Callback() {
- @Override
- protected void internalDone(Object caller, IStatus status) {
- // Refresh the view
- ViewsUtil.refresh(IUIConstants.ID_EXPLORER);
- }
- });
- // Reset the shell
- shell = null;
-
- return null;
- }
-
- /**
- * Tests if this delete handler can delete the elements of the given
- * selection.
- *
- * @param selection The selection. Must not be <code>null</code>.
- * @return <code>True</code> if the selection can be deleted by this handler, <code>false</code> otherwise.
- */
- public boolean canDelete(ISelection selection) {
- Assert.isNotNull(selection);
-
- boolean canDelete = false;
-
- // The selection must be a structured selection and must not be empty
- if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
- // Assume the selection to be deletable
- canDelete = true;
- // Iterate the selection. All elements must be of type IPeerModel
- Iterator<?> iterator = ((IStructuredSelection)selection).iterator();
- while (iterator.hasNext()) {
- Object element = iterator.next();
- if (!(element instanceof IPeerModel)) {
- canDelete = false;
- break;
- }
-
- // Determine if the selected peer model is static
- boolean isStatic = isStatic((IPeerModel)element);
- // Determine if the selected peer model represents an agent
- // started by the current user
- boolean isStartedByCurrentUser = isStartedByCurrentUser((IPeerModel)element);
- // Static nodes can be handled the one way or the other.
- // For dynamic nodes, "delete" means "remove from <category>",
- // and this works only if the parent category is not "Neighborhood".
- if (!isStatic) {
- // Determine the parent categories for the selected node
- ICategory[] categories = getParentCategories(selection, (IPeerModel)element);
- for (ICategory category : categories) {
- if (IUIConstants.ID_CAT_NEIGHBORHOOD.equals(category.getId())) {
- canDelete = false;
- break;
- }
- else if (IUIConstants.ID_CAT_MY_TARGETS.equals(category.getId()) && isStartedByCurrentUser) {
- canDelete = false;
- break;
- }
- }
- }
-
- if (!canDelete) break;
- }
- }
-
- return canDelete;
- }
-
- /**
- * Determines if the given peer model node is a static node.
- *
- * @param node The peer model node. Must not be <code>null</code>.
- * @return <code>True</code> if the node is static, <code>false</code> otherwise.
- */
- private boolean isStatic(final IPeerModel node) {
- Assert.isNotNull(node);
-
- final AtomicBoolean isStatic = new AtomicBoolean();
-
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- String value = node.getPeer().getAttributes().get("static.transient"); //$NON-NLS-1$
- isStatic.set(value != null && Boolean.parseBoolean(value.trim()));
- }
- };
-
- if (Protocol.isDispatchThread()) runnable.run();
- else Protocol.invokeAndWait(runnable);
-
- return isStatic.get();
- }
-
- /**
- * Determines if the given peer model node represents an agent started
- * by the current user.
- *
- * @param node The peer model node. Must not be <code>null</code>.
- * @return <code>True</code> if the node represents and agent started by the current user,
- * <code>false</code> otherwise.
- */
- private boolean isStartedByCurrentUser(final IPeerModel node) {
- Assert.isNotNull(node);
-
- final AtomicReference<String> username = new AtomicReference<String>();
-
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- username.set(node.getPeer().getUserName());
- }
- };
-
- if (Protocol.isDispatchThread()) runnable.run();
- else Protocol.invokeAndWait(runnable);
-
- return System.getProperty("user.name").equals(username.get()); //$NON-NLS-1$
- }
-
- /**
- * Returns the parent categories of the selected node based on the
- * given selection.
- *
- * @param selection The selection. Must not be <code>null</code>.
- * @param node The peer model node. Must not be <code>null</code>.
- *
- * @return The list of parent categories of the selected node.
- */
- private ICategory[] getParentCategories(ISelection selection, IPeerModel node) {
- Assert.isNotNull(selection);
- Assert.isNotNull(node);
-
- List<ICategory> categories = new ArrayList<ICategory>();
-
- // Get all tree pathes of the given node
- if (selection instanceof ITreeSelection) {
- TreePath[] pathes = ((ITreeSelection)selection).getPathsFor(node);
- for (TreePath path : pathes) {
- // Loop through the parent pathes to find the category element
- TreePath parentPath = path.getParentPath();
- while (parentPath != null) {
- if (parentPath.getLastSegment() instanceof ICategory
- && !categories.contains(parentPath.getLastSegment())) {
- categories.add((ICategory)parentPath.getLastSegment());
- break;
- }
- parentPath = parentPath.getParentPath();
- }
- }
- }
-
- return categories.toArray(new ICategory[categories.size()]);
- }
-
- /**
- * Internal helper class to describe the delete operation to perform.
- */
- private static class Operation {
- // The operation types
- public enum TYPE { Remove, Unlink }
-
- // The element to operate on
- public IPeerModel node;
- // The operation type to perform
- public TYPE type;
- // In case of an "unlink" operation, the parent category
- // is required.
- public ICategory parentCategory;
-
- /**
- * Constructor.
- */
- public Operation() {
- }
-
- /**
- * Executes the operation.
- *
- * @throws Exception if the operation fails.
- */
- public void execute() throws Exception {
- Assert.isNotNull(node);
- Assert.isNotNull(type);
-
- if (TYPE.Remove.equals(type)) {
- IURIPersistenceService service = ServiceManager.getInstance().getService(IURIPersistenceService.class);
- if (service == null) {
- throw new IOException("Persistence service instance unavailable."); //$NON-NLS-1$
- }
- service.delete(node, null);
- }
- else if (TYPE.Unlink.equals(type)) {
- Assert.isNotNull(parentCategory);
-
- ICategoryManager manager = Managers.getCategoryManager();
- Assert.isNotNull(manager);
-
- ICategorizable categorizable = (ICategorizable)node.getAdapter(ICategorizable.class);
- if (categorizable == null) categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(node, ICategorizable.class);
- Assert.isNotNull(categorizable);
-
- manager.remove(parentCategory.getId(), categorizable.getId());
- }
- }
- }
-
- /**
- * Deletes all elements from the given selection and invokes the
- * given callback once done.
- *
- * @param selection The selection. Must not be <code>null</code>.
- * @param callback The callback. Must not be <code>null</code>.
- */
- public void delete(final ISelection selection, final ICallback callback) {
- Assert.isNotNull(selection);
- Assert.isNotNull(callback);
-
- // The callback needs to be invoked in any case. However, if called
- // from an asynchronous callback, set this flag to false.
- boolean invokeCallback = true;
-
- // The selection must be a structured selection and must not be empty
- if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
- // Determine the operations to perform for each of the selected elements
- Operation[] operations = selection2operations((IStructuredSelection)selection);
-
- // Seek confirmation for the "remove" operations. If the user deny it,
- // everything, including the "unlink" operations are cancelled.
- boolean confirmed = confirmDelete(operations);
-
- // Execute the operations
- if (confirmed) {
- // If one of the operation is a "remove" operation, the locator
- // model needs to be refreshed
- boolean refreshModel = false;
-
- try {
- for (Operation op : operations) {
- if (Operation.TYPE.Remove.equals(op.type)) {
- refreshModel = true;
- }
- op.execute();
- }
- } catch (Exception e) {
- // Create the status
- IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
- Messages.DeleteHandler_error_deleteFailed, e);
-
- // Fill in the status handler custom data
- IPropertiesContainer data = new PropertiesContainer();
- data.setProperty(IStatusHandlerConstants.PROPERTY_TITLE, Messages.DeleteHandler_error_title);
- data.setProperty(IStatusHandlerConstants.PROPERTY_CONTEXT_HELP_ID, IContextHelpIds.MESSAGE_DELETE_FAILED);
- data.setProperty(IStatusHandlerConstants.PROPERTY_CALLER, this);
-
- // Get the status handler
- IStatusHandler[] handler = StatusHandlerManager.getInstance().getHandler(selection);
- if (handler.length > 0) {
- handler[0].handleStatus(status, data, null);
- }
- }
-
- if (refreshModel) {
- // Get the locator model
- final ILocatorModel model = Model.getModel();
- if (model != null) {
- // Trigger a refresh of the model
- final ILocatorModelRefreshService service = model.getService(ILocatorModelRefreshService.class);
- if (service != null) {
- // Invoke the callback after the refresh
- invokeCallback = false;
- Protocol.invokeLater(new Runnable() {
- @Override
- public void run() {
- // Refresh the model now (must be executed within the TCF dispatch thread)
- service.refresh();
- // Invoke the callback
- callback.done(DeleteHandler.this, Status.OK_STATUS);
- }
- });
- }
- }
- }
- }
- }
-
- if (invokeCallback) {
- callback.done(this, Status.OK_STATUS);
- }
- }
-
- /**
- * Analyze the given selection and convert it to an list of operations
- * to perform.
- *
- * @param selection The selection. Must not be <code>null</code>.
- * @return The list of operations.
- */
- private Operation[] selection2operations(IStructuredSelection selection) {
- Assert.isNotNull(selection);
-
- List<Operation> operations = new ArrayList<Operation>();
-
- Iterator<?> iterator = selection.iterator();
- while (iterator.hasNext()) {
- Object element = iterator.next();
- Assert.isTrue(element instanceof IPeerModel);
- IPeerModel node = (IPeerModel)element;
-
- boolean isStatic = isStatic(node);
- ICategory[] categories = getParentCategories(selection, node);
-
- if (categories.length == 0 && isStatic) {
- Operation op = new Operation();
- op.node = node;
- op.type = Operation.TYPE.Remove;
- operations.add(op);
- } else {
- for (ICategory category : categories) {
- // If the parent category is "Favorites", it is always
- // an "unlink" operation
- if (IUIConstants.ID_CAT_FAVORITES.equals(category.getId())) {
- Operation op = new Operation();
- op.node = node;
- op.type = Operation.TYPE.Unlink;
- op.parentCategory = category;
- operations.add(op);
- }
- // If the parent category is "My Targets", is is an
- // "remove" operation for static peers and "unlink" for
- // dynamic peers
- else if (IUIConstants.ID_CAT_MY_TARGETS.equals(category.getId())) {
- Operation op = new Operation();
- op.node = node;
-
- if (isStatic) {
- op.type = Operation.TYPE.Remove;
- } else {
- op.type = Operation.TYPE.Unlink;
- op.parentCategory = category;
- }
-
- operations.add(op);
- }
- }
- }
- }
-
- return operations.toArray(new Operation[operations.size()]);
- }
-
- /**
- * Confirm the deletion with the user.
- *
- * @param state The state of delegation handler.
- * @return true if the user agrees to delete or it has confirmed previously.
- */
- private boolean confirmDelete(Operation[] operations) {
- Assert.isNotNull(operations);
-
- boolean confirmed = false;
-
- // Find all elements to remove
- List<Operation> toRemove = new ArrayList<Operation>();
- for (Operation op : operations) {
- if (Operation.TYPE.Remove.equals(op.type)) {
- toRemove.add(op);
- }
- }
-
- // If there are node to remove -> ask for confirmation
- if (!toRemove.isEmpty()) {
- String question = getConfirmQuestion(toRemove);
- Shell parent = shell != null ? shell : PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
- confirmed = MessageDialog.openQuestion(parent, Messages.DeleteHandlerDelegate_DialogTitle, question);
- } else {
- confirmed = true;
- }
-
- return confirmed;
- }
-
- /**
- * Get confirmation question displayed in the confirmation dialog.
- *
- * @param toRemove The list of nodes to remove.
- * @return The question to ask the user.
- */
- private String getConfirmQuestion(List<Operation> toRemove) {
- Assert.isNotNull(toRemove);
-
- String question;
- if (toRemove.size() == 1) {
- final Operation op = toRemove.get(0);
- final AtomicReference<String> name = new AtomicReference<String>();
-
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- name.set(op.node.getPeer().getName());
- }
- };
-
- if (Protocol.isDispatchThread()) runnable.run();
- else Protocol.invokeAndWait(runnable);
-
- question = NLS.bind(Messages.DeleteHandlerDelegate_MsgDeleteOnePeer, name.get());
- }
- else {
- question = NLS.bind(Messages.DeleteHandlerDelegate_MsgDeleteMultiplePeers, Integer.valueOf(toRemove.size()));
- }
- return question;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.ui.handler;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeSelection;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.te.runtime.callback.Callback;
+import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback;
+import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
+import org.eclipse.tcf.te.runtime.persistence.interfaces.IURIPersistenceService;
+import org.eclipse.tcf.te.runtime.properties.PropertiesContainer;
+import org.eclipse.tcf.te.runtime.services.ServiceManager;
+import org.eclipse.tcf.te.runtime.statushandler.StatusHandlerManager;
+import org.eclipse.tcf.te.runtime.statushandler.interfaces.IStatusHandler;
+import org.eclipse.tcf.te.runtime.statushandler.interfaces.IStatusHandlerConstants;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tcf.te.tcf.locator.interfaces.services.ILocatorModelRefreshService;
+import org.eclipse.tcf.te.tcf.locator.model.Model;
+import org.eclipse.tcf.te.tcf.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.ui.help.IContextHelpIds;
+import org.eclipse.tcf.te.tcf.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.views.Managers;
+import org.eclipse.tcf.te.ui.views.ViewsUtil;
+import org.eclipse.tcf.te.ui.views.interfaces.ICategory;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.views.interfaces.categories.ICategorizable;
+import org.eclipse.tcf.te.ui.views.interfaces.categories.ICategoryManager;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Delete handler implementation.
+ */
+public class DeleteHandler extends AbstractHandler {
+ // Remember the shell from the execution event
+ private Shell shell = null;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // Get the shell
+ shell = HandlerUtil.getActiveShell(event);
+ // Get the current selection
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ // Delete the selection
+ if (selection != null) {
+ delete(selection, new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ // Refresh the view
+ ViewsUtil.refresh(IUIConstants.ID_EXPLORER);
+ }
+ });
+ }
+ // Reset the shell
+ shell = null;
+
+ return null;
+ }
+
+ /**
+ * Tests if this delete handler can delete the elements of the given
+ * selection.
+ *
+ * @param selection The selection. Must not be <code>null</code>.
+ * @return <code>True</code> if the selection can be deleted by this handler, <code>false</code> otherwise.
+ */
+ public boolean canDelete(ISelection selection) {
+ Assert.isNotNull(selection);
+
+ boolean canDelete = false;
+
+ // The selection must be a structured selection and must not be empty
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ // Assume the selection to be deletable
+ canDelete = true;
+ // Iterate the selection. All elements must be of type IPeerModel
+ Iterator<?> iterator = ((IStructuredSelection)selection).iterator();
+ while (iterator.hasNext()) {
+ Object element = iterator.next();
+ if (!(element instanceof IPeerModel)) {
+ canDelete = false;
+ break;
+ }
+
+ // Determine if the selected peer model is static
+ boolean isStatic = isStatic((IPeerModel)element);
+ // Determine if the selected peer model represents an agent
+ // started by the current user
+ boolean isStartedByCurrentUser = isStartedByCurrentUser((IPeerModel)element);
+ // Static nodes can be handled the one way or the other.
+ // For dynamic nodes, "delete" means "remove from <category>",
+ // and this works only if the parent category is not "Neighborhood".
+ if (!isStatic) {
+ // Determine the parent categories for the selected node
+ ICategory[] categories = getParentCategories(selection, (IPeerModel)element);
+ for (ICategory category : categories) {
+ if (IUIConstants.ID_CAT_NEIGHBORHOOD.equals(category.getId())) {
+ canDelete = false;
+ break;
+ }
+ else if (IUIConstants.ID_CAT_MY_TARGETS.equals(category.getId()) && isStartedByCurrentUser) {
+ canDelete = false;
+ break;
+ }
+ }
+ }
+
+ if (!canDelete) {
+ break;
+ }
+ }
+ }
+
+ return canDelete;
+ }
+
+ /**
+ * Determines if the given peer model node is a static node.
+ *
+ * @param node The peer model node. Must not be <code>null</code>.
+ * @return <code>True</code> if the node is static, <code>false</code> otherwise.
+ */
+ private boolean isStatic(final IPeerModel node) {
+ Assert.isNotNull(node);
+
+ final AtomicBoolean isStatic = new AtomicBoolean();
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ String value = node.getPeer().getAttributes().get("static.transient"); //$NON-NLS-1$
+ isStatic.set(value != null && Boolean.parseBoolean(value.trim()));
+ }
+ };
+
+ if (Protocol.isDispatchThread()) {
+ runnable.run();
+ }
+ else {
+ Protocol.invokeAndWait(runnable);
+ }
+
+ return isStatic.get();
+ }
+
+ /**
+ * Determines if the given peer model node represents an agent started
+ * by the current user.
+ *
+ * @param node The peer model node. Must not be <code>null</code>.
+ * @return <code>True</code> if the node represents and agent started by the current user,
+ * <code>false</code> otherwise.
+ */
+ private boolean isStartedByCurrentUser(final IPeerModel node) {
+ Assert.isNotNull(node);
+
+ final AtomicReference<String> username = new AtomicReference<String>();
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ username.set(node.getPeer().getUserName());
+ }
+ };
+
+ if (Protocol.isDispatchThread()) {
+ runnable.run();
+ }
+ else {
+ Protocol.invokeAndWait(runnable);
+ }
+
+ return System.getProperty("user.name").equals(username.get()); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the parent categories of the selected node based on the
+ * given selection.
+ *
+ * @param selection The selection. Must not be <code>null</code>.
+ * @param node The peer model node. Must not be <code>null</code>.
+ *
+ * @return The list of parent categories of the selected node.
+ */
+ private ICategory[] getParentCategories(ISelection selection, IPeerModel node) {
+ Assert.isNotNull(selection);
+ Assert.isNotNull(node);
+
+ List<ICategory> categories = new ArrayList<ICategory>();
+
+ // Get all tree pathes of the given node
+ if (selection instanceof ITreeSelection) {
+ TreePath[] pathes = ((ITreeSelection)selection).getPathsFor(node);
+ for (TreePath path : pathes) {
+ // Loop through the parent pathes to find the category element
+ TreePath parentPath = path.getParentPath();
+ while (parentPath != null) {
+ if (parentPath.getLastSegment() instanceof ICategory
+ && !categories.contains(parentPath.getLastSegment())) {
+ categories.add((ICategory)parentPath.getLastSegment());
+ break;
+ }
+ parentPath = parentPath.getParentPath();
+ }
+ }
+ }
+
+ return categories.toArray(new ICategory[categories.size()]);
+ }
+
+ /**
+ * Internal helper class to describe the delete operation to perform.
+ */
+ private static class Operation {
+ // The operation types
+ public enum TYPE { Remove, Unlink }
+
+ // The element to operate on
+ public IPeerModel node;
+ // The operation type to perform
+ public TYPE type;
+ // In case of an "unlink" operation, the parent category
+ // is required.
+ public ICategory parentCategory;
+
+ /**
+ * Constructor.
+ */
+ public Operation() {
+ }
+
+ /**
+ * Executes the operation.
+ *
+ * @throws Exception if the operation fails.
+ */
+ public void execute() throws Exception {
+ Assert.isNotNull(node);
+ Assert.isNotNull(type);
+
+ if (TYPE.Remove.equals(type)) {
+ IURIPersistenceService service = ServiceManager.getInstance().getService(IURIPersistenceService.class);
+ if (service == null) {
+ throw new IOException("Persistence service instance unavailable."); //$NON-NLS-1$
+ }
+ service.delete(node, null);
+ }
+ else if (TYPE.Unlink.equals(type)) {
+ Assert.isNotNull(parentCategory);
+
+ ICategoryManager manager = Managers.getCategoryManager();
+ Assert.isNotNull(manager);
+
+ ICategorizable categorizable = (ICategorizable)node.getAdapter(ICategorizable.class);
+ if (categorizable == null) {
+ categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(node, ICategorizable.class);
+ }
+ Assert.isNotNull(categorizable);
+
+ manager.remove(parentCategory.getId(), categorizable.getId());
+ }
+ }
+ }
+
+ /**
+ * Deletes all elements from the given selection and invokes the
+ * given callback once done.
+ *
+ * @param selection The selection. Must not be <code>null</code>.
+ * @param callback The callback. Must not be <code>null</code>.
+ */
+ public void delete(final ISelection selection, final ICallback callback) {
+ Assert.isNotNull(selection);
+ Assert.isNotNull(callback);
+
+ // The callback needs to be invoked in any case. However, if called
+ // from an asynchronous callback, set this flag to false.
+ boolean invokeCallback = true;
+
+ // The selection must be a structured selection and must not be empty
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ // Determine the operations to perform for each of the selected elements
+ Operation[] operations = selection2operations((IStructuredSelection)selection);
+
+ // Seek confirmation for the "remove" operations. If the user deny it,
+ // everything, including the "unlink" operations are cancelled.
+ boolean confirmed = confirmDelete(operations);
+
+ // Execute the operations
+ if (confirmed) {
+ // If one of the operation is a "remove" operation, the locator
+ // model needs to be refreshed
+ boolean refreshModel = false;
+
+ try {
+ for (Operation op : operations) {
+ if (Operation.TYPE.Remove.equals(op.type)) {
+ refreshModel = true;
+ }
+ op.execute();
+ }
+ } catch (Exception e) {
+ // Create the status
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ Messages.DeleteHandler_error_deleteFailed, e);
+
+ // Fill in the status handler custom data
+ IPropertiesContainer data = new PropertiesContainer();
+ data.setProperty(IStatusHandlerConstants.PROPERTY_TITLE, Messages.DeleteHandler_error_title);
+ data.setProperty(IStatusHandlerConstants.PROPERTY_CONTEXT_HELP_ID, IContextHelpIds.MESSAGE_DELETE_FAILED);
+ data.setProperty(IStatusHandlerConstants.PROPERTY_CALLER, this);
+
+ // Get the status handler
+ IStatusHandler[] handler = StatusHandlerManager.getInstance().getHandler(selection);
+ if (handler.length > 0) {
+ handler[0].handleStatus(status, data, null);
+ }
+ }
+
+ if (refreshModel) {
+ // Get the locator model
+ final ILocatorModel model = Model.getModel();
+ if (model != null) {
+ // Trigger a refresh of the model
+ final ILocatorModelRefreshService service = model.getService(ILocatorModelRefreshService.class);
+ if (service != null) {
+ // Invoke the callback after the refresh
+ invokeCallback = false;
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ // Refresh the model now (must be executed within the TCF dispatch thread)
+ service.refresh();
+ // Invoke the callback
+ callback.done(DeleteHandler.this, Status.OK_STATUS);
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+
+ if (invokeCallback) {
+ callback.done(this, Status.OK_STATUS);
+ }
+ }
+
+ /**
+ * Analyze the given selection and convert it to an list of operations
+ * to perform.
+ *
+ * @param selection The selection. Must not be <code>null</code>.
+ * @return The list of operations.
+ */
+ private Operation[] selection2operations(IStructuredSelection selection) {
+ Assert.isNotNull(selection);
+
+ List<Operation> operations = new ArrayList<Operation>();
+
+ Iterator<?> iterator = selection.iterator();
+ while (iterator.hasNext()) {
+ Object element = iterator.next();
+ Assert.isTrue(element instanceof IPeerModel);
+ IPeerModel node = (IPeerModel)element;
+
+ boolean isStatic = isStatic(node);
+ ICategory[] categories = getParentCategories(selection, node);
+
+ if (categories.length == 0 && isStatic) {
+ Operation op = new Operation();
+ op.node = node;
+ op.type = Operation.TYPE.Remove;
+ operations.add(op);
+ } else {
+ for (ICategory category : categories) {
+ // If the parent category is "Favorites", it is always
+ // an "unlink" operation
+ if (IUIConstants.ID_CAT_FAVORITES.equals(category.getId())) {
+ Operation op = new Operation();
+ op.node = node;
+ op.type = Operation.TYPE.Unlink;
+ op.parentCategory = category;
+ operations.add(op);
+ }
+ // If the parent category is "My Targets", is is an
+ // "remove" operation for static peers and "unlink" for
+ // dynamic peers
+ else if (IUIConstants.ID_CAT_MY_TARGETS.equals(category.getId())) {
+ Operation op = new Operation();
+ op.node = node;
+
+ if (isStatic) {
+ op.type = Operation.TYPE.Remove;
+ } else {
+ op.type = Operation.TYPE.Unlink;
+ op.parentCategory = category;
+ }
+
+ operations.add(op);
+ }
+ else {
+ Operation op = new Operation();
+ op.node = node;
+ op.type = Operation.TYPE.Remove;
+
+ operations.add(op);
+ }
+ }
+ }
+ }
+
+ return operations.toArray(new Operation[operations.size()]);
+ }
+
+ /**
+ * Confirm the deletion with the user.
+ *
+ * @param state The state of delegation handler.
+ * @return true if the user agrees to delete or it has confirmed previously.
+ */
+ private boolean confirmDelete(Operation[] operations) {
+ Assert.isNotNull(operations);
+
+ boolean confirmed = false;
+
+ // Find all elements to remove
+ List<Operation> toRemove = new ArrayList<Operation>();
+ for (Operation op : operations) {
+ if (Operation.TYPE.Remove.equals(op.type)) {
+ toRemove.add(op);
+ }
+ }
+
+ // If there are node to remove -> ask for confirmation
+ if (!toRemove.isEmpty()) {
+ String question = getConfirmQuestion(toRemove);
+ Shell parent = shell != null ? shell : PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ confirmed = MessageDialog.openQuestion(parent, Messages.DeleteHandlerDelegate_DialogTitle, question);
+ } else {
+ confirmed = true;
+ }
+
+ return confirmed;
+ }
+
+ /**
+ * Get confirmation question displayed in the confirmation dialog.
+ *
+ * @param toRemove The list of nodes to remove.
+ * @return The question to ask the user.
+ */
+ private String getConfirmQuestion(List<Operation> toRemove) {
+ Assert.isNotNull(toRemove);
+
+ String question;
+ if (toRemove.size() == 1) {
+ final Operation op = toRemove.get(0);
+ final AtomicReference<String> name = new AtomicReference<String>();
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ name.set(op.node.getPeer().getName());
+ }
+ };
+
+ if (Protocol.isDispatchThread()) {
+ runnable.run();
+ }
+ else {
+ Protocol.invokeAndWait(runnable);
+ }
+
+ question = NLS.bind(Messages.DeleteHandlerDelegate_MsgDeleteOnePeer, name.get());
+ }
+ else {
+ question = NLS.bind(Messages.DeleteHandlerDelegate_MsgDeleteMultiplePeers, Integer.valueOf(toRemove.size()));
+ }
+ return question;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/navigator/ContentProviderDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/navigator/ContentProviderDelegate.java
index be4c2fe..fba43c4 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/navigator/ContentProviderDelegate.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/navigator/ContentProviderDelegate.java
@@ -129,12 +129,11 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
public void run() {
if (IUIConstants.ID_CAT_FAVORITES.equals(catID)) {
for (IPeerModel peer : peers) {
- // Check for filtered nodes (Value-add's and Proxies)
- if (isFiltered(peer)) continue;
-
- ICategorizable categorizable = (ICategorizable)peer.getAdapter(ICategorizable.class);
- if (categorizable == null) categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(peer, ICategorizable.class);
- Assert.isNotNull(categorizable);
+ ICategorizable categorizable = (ICategorizable)peer.getAdapter(ICategorizable.class);
+ if (categorizable == null) {
+ categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(peer, ICategorizable.class);
+ }
+ Assert.isNotNull(categorizable);
boolean isFavorite = Managers.getCategoryManager().belongsTo(catID, categorizable.getId());
if (isFavorite && !candidates.contains(peer)) {
@@ -145,11 +144,15 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
else if (IUIConstants.ID_CAT_MY_TARGETS.equals(catID)) {
for (IPeerModel peer : peers) {
// Check for filtered nodes (Value-add's and Proxies)
- if (isFiltered(peer)) continue;
+ if (isFiltered(peer)) {
+ continue;
+ }
ICategorizable categorizable = (ICategorizable)peer.getAdapter(ICategorizable.class);
- if (categorizable == null) categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(peer, ICategorizable.class);
- Assert.isNotNull(categorizable);
+ if (categorizable == null) {
+ categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(peer, ICategorizable.class);
+ }
+ Assert.isNotNull(categorizable);
String value = peer.getPeer().getAttributes().get("static.transient"); //$NON-NLS-1$
boolean isStatic = value != null && Boolean.parseBoolean(value.trim());
@@ -175,13 +178,17 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
else if (IUIConstants.ID_CAT_NEIGHBORHOOD.equals(catID)) {
for (IPeerModel peer : peers) {
// Check for filtered nodes (Value-add's and Proxies)
- if (isFiltered(peer)) continue;
+ if (isFiltered(peer)) {
+ continue;
+ }
- ICategorizable categorizable = (ICategorizable)peer.getAdapter(ICategorizable.class);
- if (categorizable == null) categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(peer, ICategorizable.class);
- Assert.isNotNull(categorizable);
+ ICategorizable categorizable = (ICategorizable)peer.getAdapter(ICategorizable.class);
+ if (categorizable == null) {
+ categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(peer, ICategorizable.class);
+ }
+ Assert.isNotNull(categorizable);
- String value = peer.getPeer().getAttributes().get("static.transient"); //$NON-NLS-1$
+ String value = peer.getPeer().getAttributes().get("static.transient"); //$NON-NLS-1$
boolean isStatic = value != null && Boolean.parseBoolean(value.trim());
boolean isNeighborhood = Managers.getCategoryManager().belongsTo(catID, categorizable.getId());
@@ -195,15 +202,31 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
isNeighborhood = true;
}
- if ((isNeighborhood || !isStatic) && !candidates.contains(peer)) {
+ if (isNeighborhood && !candidates.contains(peer)) {
candidates.add(peer);
}
}
}
- else if (catID == null) {
+ else if (catID != null) {
+ for (IPeerModel peer : peers) {
+ ICategorizable categorizable = (ICategorizable)peer.getAdapter(ICategorizable.class);
+ if (categorizable == null) {
+ categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(peer, ICategorizable.class);
+ }
+ Assert.isNotNull(categorizable);
+
+ boolean belongsTo = category.belongsTo(peer);
+ if (belongsTo) {
+ candidates.add(peer);
+ }
+ }
+ }
+ else {
for (IPeerModel peer : peers) {
// Check for filtered nodes (Value-add's and Proxies)
- if (isFiltered(peer)) continue;
+ if (isFiltered(peer)) {
+ continue;
+ }
candidates.add(peer);
}
}
@@ -255,11 +278,11 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreePathContentProvider#getChildren(org.eclipse.jface.viewers.TreePath)
*/
- @Override
- public Object[] getChildren(TreePath parentPath) {
- // getChildren is independent of the elements tree path
- return parentPath != null ? getChildren(parentPath.getLastSegment()) : NO_ELEMENTS;
- }
+ @Override
+ public Object[] getChildren(TreePath parentPath) {
+ // getChildren is independent of the elements tree path
+ return parentPath != null ? getChildren(parentPath.getLastSegment()) : NO_ELEMENTS;
+ }
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
@@ -272,7 +295,9 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
if (((IPeerModel)element).getPeer() instanceof IPeerRedirector) {
IPeer parentPeer = ((IPeerRedirector)((IPeerModel)element).getPeer()).getParent();
String parentPeerId = parentPeer.getID();
- if (!roots.containsKey(parentPeerId)) roots.put(parentPeer.getID(), new PeerRedirectorGroupNode(parentPeerId));
+ if (!roots.containsKey(parentPeerId)) {
+ roots.put(parentPeer.getID(), new PeerRedirectorGroupNode(parentPeerId));
+ }
return roots.get(parentPeerId);
}
@@ -317,8 +342,8 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreePathContentProvider#getParents(java.lang.Object)
*/
- @Override
- public TreePath[] getParents(Object element) {
+ @Override
+ public TreePath[] getParents(Object element) {
// Not sure if we ever have to calculate the _full_ tree path. The parent NavigatorContentServiceContentProvider
// is consuming only the last segment.
List<TreePath> pathes = new ArrayList<TreePath>();
@@ -327,16 +352,20 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
if (Managers.getCategoryManager().belongsTo(IUIConstants.ID_CAT_FAVORITES, ((IPeerModel)element).getPeerId())) {
// Get the "Favorites" category
ICategory favCategory = CategoriesExtensionPointManager.getInstance().getCategory(IUIConstants.ID_CAT_FAVORITES, false);
- if (favCategory != null) pathes.add(new TreePath(new Object[] { favCategory }));
+ if (favCategory != null) {
+ pathes.add(new TreePath(new Object[] { favCategory }));
+ }
}
// Determine the default parent
Object parent = getParent(element);
- if (parent != null) pathes.add(new TreePath(new Object[] { parent }));
- }
+ if (parent != null) {
+ pathes.add(new TreePath(new Object[] { parent }));
+ }
+ }
return pathes.toArray(new TreePath[pathes.size()]);
- }
+ }
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
@@ -367,11 +396,11 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreePathContentProvider#hasChildren(org.eclipse.jface.viewers.TreePath)
*/
- @Override
- public boolean hasChildren(TreePath path) {
- // hasChildren is independent of the elements tree path
- return path != null ? hasChildren(path.getLastSegment()) : false;
- }
+ @Override
+ public boolean hasChildren(TreePath path) {
+ // hasChildren is independent of the elements tree path
+ return path != null ? hasChildren(path.getLastSegment()) : false;
+ }
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
@@ -419,15 +448,15 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
}
/* (non-Javadoc)
- * @see org.eclipse.ui.navigator.ICommonContentProvider#init(org.eclipse.ui.navigator.ICommonContentExtensionSite)
- */
- @Override
- public void init(ICommonContentExtensionSite config) {
- Assert.isNotNull(config);
-
- // Make sure that the hidden "Redirected Peers" filter is active
- INavigatorContentService cs = config.getService();
- INavigatorFilterService fs = cs != null ? cs.getFilterService() : null;
+ * @see org.eclipse.ui.navigator.ICommonContentProvider#init(org.eclipse.ui.navigator.ICommonContentExtensionSite)
+ */
+ @Override
+ public void init(ICommonContentExtensionSite config) {
+ Assert.isNotNull(config);
+
+ // Make sure that the hidden "Redirected Peers" filter is active
+ INavigatorContentService cs = config.getService();
+ INavigatorFilterService fs = cs != null ? cs.getFilterService() : null;
if (fs != null && !fs.isActive(REDIRECT_PEERS_FILTER_ID)) {
if (fs instanceof NavigatorFilterService) {
final NavigatorFilterService navFilterService = (NavigatorFilterService)fs;
@@ -441,19 +470,19 @@ public class ContentProviderDelegate implements ICommonContentProvider, ITreePat
});
}
}
- }
+ }
/* (non-Javadoc)
- * @see org.eclipse.ui.navigator.IMementoAware#restoreState(org.eclipse.ui.IMemento)
- */
- @Override
- public void restoreState(IMemento aMemento) {
- }
+ * @see org.eclipse.ui.navigator.IMementoAware#restoreState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void restoreState(IMemento aMemento) {
+ }
/* (non-Javadoc)
- * @see org.eclipse.ui.navigator.IMementoAware#saveState(org.eclipse.ui.IMemento)
- */
- @Override
- public void saveState(IMemento aMemento) {
- }
+ * @see org.eclipse.ui.navigator.IMementoAware#saveState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void saveState(IMemento aMemento) {
+ }
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/categories/Category.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/categories/Category.java
index 8e51033..2d24354 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/categories/Category.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/categories/Category.java
@@ -1,130 +1,149 @@
-/*******************************************************************************
- * Copyright (c) 2012 Wind River Systems, Inc. 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:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tcf.te.ui.views.categories;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.tcf.te.runtime.extensions.ExecutableExtension;
-import org.eclipse.tcf.te.runtime.interfaces.IDisposable;
-import org.eclipse.tcf.te.ui.views.interfaces.ICategory;
-import org.eclipse.ui.IMemento;
-import org.eclipse.ui.IPersistableElement;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-
-/**
- * Default category implementation.
- */
-public class Category extends ExecutableExtension implements ICategory, IDisposable, IPersistableElement {
- // The category image / image descriptor
- private ImageDescriptor descriptor = null;
- private Image image = null;
- // The sorting rank
- private int rank = -1;
-
- /* (non-Javadoc)
- * @see org.eclipse.tcf.te.runtime.extensions.ExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
- */
- @Override
- public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
- super.setInitializationData(config, propertyName, data);
-
- // Read the icon attribute and create the image
- String attrIcon = config.getAttribute("icon");//$NON-NLS-1$
- if (attrIcon != null) {
- descriptor = AbstractUIPlugin.imageDescriptorFromPlugin(config.getNamespaceIdentifier(), attrIcon);
- if (descriptor != null) {
- image = JFaceResources.getResources().createImageWithDefault(descriptor);
- }
- }
-
- // Read the rank attribute
- String attrRank = config.getAttribute("rank"); //$NON-NLS-1$
- if (attrRank != null) {
- try {
- rank = Integer.valueOf(attrRank).intValue();
- } catch (NumberFormatException e) { /* ignored on purpose */ }
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
- */
- @Override
- public Object getAdapter(Class adapter) {
- if(adapter == IPersistableElement.class) {
- return this;
- }
- return super.getAdapter(adapter);
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
- */
- @Override
- public void saveState(IMemento memento) {
- memento.putString("id", this.getId()); //$NON-NLS-1$
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.ui.IPersistableElement#getFactoryId()
- */
- @Override
- public String getFactoryId() {
- return "org.eclipse.tcf.te.ui.views.categoryFactory"; //$NON-NLS-1$
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.tcf.te.runtime.interfaces.IDisposable#dispose()
- */
- @Override
- public void dispose() {
- if (descriptor != null) {
- JFaceResources.getResources().destroyImage(descriptor);
- descriptor = null;
- }
- image = null;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.tcf.te.ui.views.interfaces.ICategory#getImage()
- */
- @Override
- public Image getImage() {
- return image;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.tcf.te.ui.views.interfaces.ICategory#getRank()
- */
- @Override
- public int getRank() {
- return rank;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- StringBuffer buffer = new StringBuffer(getLabel());
- buffer.append(" ["); //$NON-NLS-1$
- buffer.append(getId());
- buffer.append("] {rank="); //$NON-NLS-1$
- buffer.append(getRank());
- buffer.append("}"); //$NON-NLS-1$
- return buffer.toString();
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.categories;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.runtime.extensions.ExecutableExtension;
+import org.eclipse.tcf.te.runtime.interfaces.IDisposable;
+import org.eclipse.tcf.te.ui.views.Managers;
+import org.eclipse.tcf.te.ui.views.interfaces.ICategory;
+import org.eclipse.tcf.te.ui.views.interfaces.categories.ICategorizable;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableElement;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * Default category implementation.
+ */
+public class Category extends ExecutableExtension implements ICategory, IDisposable, IPersistableElement {
+ // The category image / image descriptor
+ private ImageDescriptor descriptor = null;
+ private Image image = null;
+ // The sorting rank
+ private int rank = -1;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.ExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+ super.setInitializationData(config, propertyName, data);
+
+ // Read the icon attribute and create the image
+ String attrIcon = config.getAttribute("icon");//$NON-NLS-1$
+ if (attrIcon != null) {
+ descriptor = AbstractUIPlugin.imageDescriptorFromPlugin(config.getNamespaceIdentifier(), attrIcon);
+ if (descriptor != null) {
+ image = JFaceResources.getResources().createImageWithDefault(descriptor);
+ }
+ }
+
+ // Read the rank attribute
+ String attrRank = config.getAttribute("rank"); //$NON-NLS-1$
+ if (attrRank != null) {
+ try {
+ rank = Integer.valueOf(attrRank).intValue();
+ } catch (NumberFormatException e) { /* ignored on purpose */ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ if(adapter == IPersistableElement.class) {
+ return this;
+ }
+ return super.getAdapter(adapter);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void saveState(IMemento memento) {
+ memento.putString("id", this.getId()); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.IPersistableElement#getFactoryId()
+ */
+ @Override
+ public String getFactoryId() {
+ return "org.eclipse.tcf.te.ui.views.categoryFactory"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.interfaces.IDisposable#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (descriptor != null) {
+ JFaceResources.getResources().destroyImage(descriptor);
+ descriptor = null;
+ }
+ image = null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.interfaces.ICategory#getImage()
+ */
+ @Override
+ public Image getImage() {
+ return image;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.interfaces.ICategory#getRank()
+ */
+ @Override
+ public int getRank() {
+ return rank;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.interfaces.ICategory#belongsTo(java.lang.Object)
+ */
+ @Override
+ public boolean belongsTo(Object element) {
+ ICategorizable categorizable = null;
+ if (element instanceof IAdaptable) {
+ categorizable = (ICategorizable)((IAdaptable)element).getAdapter(ICategorizable.class);
+ }
+ if (categorizable == null) {
+ categorizable = (ICategorizable)Platform.getAdapterManager().getAdapter(element, ICategorizable.class);
+ }
+ return categorizable != null ? Managers.getCategoryManager().belongsTo(getId(), categorizable.getId()) : false;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer(getLabel());
+ buffer.append(" ["); //$NON-NLS-1$
+ buffer.append(getId());
+ buffer.append("] {rank="); //$NON-NLS-1$
+ buffer.append(getRank());
+ buffer.append("}"); //$NON-NLS-1$
+ return buffer.toString();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/ICategory.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/ICategory.java
index a550b00..9f6d0e5 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/ICategory.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/ICategory.java
@@ -1,33 +1,41 @@
-/*******************************************************************************
- * Copyright (c) 2012 Wind River Systems, Inc. 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:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tcf.te.ui.views.interfaces;
-
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.tcf.te.runtime.interfaces.extensions.IExecutableExtension;
-
-/**
- * Main view category node.
- */
-public interface ICategory extends IExecutableExtension {
-
- /**
- * Returns the category image.
- *
- * @return The category image or <code>null</code>.
- */
- public Image getImage();
-
- /**
- * Returns the sorting rank.
- *
- * @return The sorting rank, or a value less than -1 to fallback to alphabetical sorting.
- */
- public int getRank();
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.interfaces;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.runtime.interfaces.extensions.IExecutableExtension;
+
+/**
+ * Main view category node.
+ */
+public interface ICategory extends IExecutableExtension {
+
+ /**
+ * Returns the category image.
+ *
+ * @return The category image or <code>null</code>.
+ */
+ public Image getImage();
+
+ /**
+ * Returns the sorting rank.
+ *
+ * @return The sorting rank, or a value less than -1 to fallback to alphabetical sorting.
+ */
+ public int getRank();
+
+ /**
+ * Check whether the given categorizable element belongs to this category.
+ * @param element The categorizable element.
+ * @return <code>true</code> if the element should be shown within this category.
+ */
+ public boolean belongsTo(Object element);
+
+}