| author | Tobias Schwarz | 2012-06-26 05:05:37 (EDT) |
|---|---|---|
| committer | Uwe Stieber | 2012-06-26 05:05:37 (EDT) |
| commit | 359418e7c9e14ea3dffe1ebf298d39d1b6cf95f7 (patch) (side-by-side diff) | |
| tree | 829bc12cd0cd7d43f7ad64d970be6175b1f980d7 | |
| parent | e490d8b26826c42bdec56289b11fc87108018b99 (diff) | |
| download | org.eclipse.tcf-359418e7c9e14ea3dffe1ebf298d39d1b6cf95f7.zip org.eclipse.tcf-359418e7c9e14ea3dffe1ebf298d39d1b6cf95f7.tar.gz org.eclipse.tcf-359418e7c9e14ea3dffe1ebf298d39d1b6cf95f7.tar.bz2 | |
Target Explorer: ADD generic category content handling
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); + +} |

