diff options
Diffstat (limited to 'src/plugins/db.core/src/com/motorolamobility/studio/android/db/core/ui/AbstractTreeNode.java')
-rw-r--r-- | src/plugins/db.core/src/com/motorolamobility/studio/android/db/core/ui/AbstractTreeNode.java | 459 |
1 files changed, 459 insertions, 0 deletions
diff --git a/src/plugins/db.core/src/com/motorolamobility/studio/android/db/core/ui/AbstractTreeNode.java b/src/plugins/db.core/src/com/motorolamobility/studio/android/db/core/ui/AbstractTreeNode.java new file mode 100644 index 0000000..f7191e5 --- /dev/null +++ b/src/plugins/db.core/src/com/motorolamobility/studio/android/db/core/ui/AbstractTreeNode.java @@ -0,0 +1,459 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.motorolamobility.studio.android.db.core.ui; + +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ILazyTreeContentProvider; +import org.eclipse.osgi.util.NLS; +import org.osgi.framework.Bundle; + +import com.motorola.studio.android.common.log.StudioLogger; +import com.motorolamobility.studio.android.db.core.DbCoreActivator; +import com.motorolamobility.studio.android.db.core.event.DatabaseModelEvent; +import com.motorolamobility.studio.android.db.core.event.DatabaseModelEvent.EVENT_TYPE; +import com.motorolamobility.studio.android.db.core.event.DatabaseModelEventManager; +import com.motorolamobility.studio.android.db.core.i18n.DbCoreNLS; +import com.motorolamobility.studio.android.db.core.ui.view.SaveStateManager; + +/** + * Node abstraction to be contributed/implemented through extension point com.motorolamobility.studio.android.db.core.dbRootNode. + */ +public abstract class AbstractTreeNode implements ITreeNode +{ + /** + * Property value used to check if the node has an error status. + */ + public static final String PROP_VALUE_NODE_STATUS_ERROR = + "com.motorolamobility.studio.android.db.core.nodeStatusError"; //$NON-NLS-1$ + + /** + * Property name used to test the status of the node. + */ + public static final String PROP_NAME_NODE_STATUS = + "com.motorolamobility.studio.android.db.core.nodeStatus"; //$NON-NLS-1$ + + private static final String DEFAULT_ICON_PATH = "icons/obj16/plate16.png"; //$NON-NLS-1$ + + /* + * id, name, and icon will come from extension point com.motorolamobility.studio.android.db.core.dbRootNode + */ + private String id; + + private String name; + + private ITreeNode parent; + + private ImageDescriptor icon = DbCoreActivator.imageDescriptorFromPlugin( + DbCoreActivator.PLUGIN_ID, DEFAULT_ICON_PATH); + + private IStatus nodeStatus = Status.OK_STATUS; + + /** + * We need to guarantee the order of the inserted items to use {@link ILazyTreeContentProvider} + * We need to guarantee the change operations are thread-safe by using synchronized list + */ + private final List<ITreeNode> children = new CopyOnWriteArrayList<ITreeNode>(); + + private volatile boolean isLoading = false; + + private String tooltip; + + /** + * Default constructor + * + * Warning: If the node comes is declared through extension point com.motorolamobility.studio.android.db.core.dbRootNode + * this constructor is mandatory to exist and be the unique to be used. + */ + public AbstractTreeNode() + { + this(null, null, null); + } + + public AbstractTreeNode(ITreeNode parent) + { + this(null, null, parent); + } + + public AbstractTreeNode(String id, String name, ITreeNode parent) + { + this(id, name, parent, null); + } + + public AbstractTreeNode(String id, String name, ITreeNode parent, ImageDescriptor icon) + { + this.id = id; + this.name = name; + this.parent = parent; + this.icon = icon; + + if (this instanceof ISaveStateTreeNode) + { + ISaveStateTreeNode saveStateTreeNode = (ISaveStateTreeNode) this; + SaveStateManager saveStateManager = SaveStateManager.getInstance(); + saveStateManager.registerSaveStateNode(saveStateTreeNode); + IEclipsePreferences prefNode = saveStateManager.getPrefNode(); + if (prefNode != null) + { + saveStateTreeNode.restoreState(prefNode); + } + } + } + + public final void refreshAsync() + { + refreshAsync(true); + } + + public final void refreshAsync(final boolean canRefreshYesResponse) + { + if (!isLoading()) + { + AbstractLoadingNodeJob loadingJob = + new AbstractLoadingNodeJob(NLS.bind( + DbCoreNLS.AbstractTreeNode_Loading_Job_Name, getName()), this) + { + @Override + protected IStatus run(IProgressMonitor monitor) + { + refresh(canRefreshYesResponse); + return Status.OK_STATUS; + } + }; + loadingJob.schedule(); + } + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#refresh() + */ + public abstract void refresh(); + + /** + * @param canRefreshYesResponse + */ + public void refresh(boolean canRefreshYesResponse) + { + refresh(); + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#getParent() + */ + public ITreeNode getParent() + { + return parent; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#setParent(com.motorolamobility.studio.android.db.core.ui.ITreeNode) + */ + public void setParent(ITreeNode parent) + { + this.parent = parent; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#getChildren() + */ + public List<ITreeNode> getChildren() + { + return children; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#clear() + */ + public void clear() + { + DatabaseModelEventManager.getInstance().fireEvent(this, EVENT_TYPE.CLEAR); + for (ITreeNode child : getChildren()) + { + child.cleanUp(); + child.clear(); + } + children.clear(); + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#getChild(int) + */ + public ITreeNode getChild(int index) + { + return children.size() > index ? children.get(index) : null; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#getChildById(String) + */ + public ITreeNode getChildById(String id) + { + ITreeNode foundChild = null; + for (ITreeNode node : children) + { + if ((node != null) && (node.getId() != null) && node.getId().equals(id)) + { + foundChild = node; + break; + } + } + return foundChild; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#getFilteredChildren(java.lang.String) + */ + public List<ITreeNode> getFilteredChildren(String regex) + { + List<ITreeNode> filteredChildren = new ArrayList<ITreeNode>(); + if (regex == null) + { + filteredChildren = getChildren(); + } + else + { + for (ITreeNode child : children) + { + if ((regex != null) && child.getId().matches(regex)) + { + filteredChildren.add(child); + } + } + } + return filteredChildren; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#putChild(java.lang.String, com.motorolamobility.studio.android.db.core.ui.AbstractTreeNode) + */ + public void putChild(ITreeNode treeNode) + { + treeNode.setParent(this); + //node does not exist yet as a child => add it + children.add(treeNode); + DatabaseModelEventManager.getInstance().fireEvent(treeNode, + DatabaseModelEvent.EVENT_TYPE.ADD); + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#putChildren(java.util.List) + */ + public void putChildren(List<ITreeNode> childrenList) + { + children.addAll(childrenList); + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#removeChild(ITreeNode) + */ + public void removeChild(ITreeNode node) + { + node.cleanUp(); + children.remove(node); + DatabaseModelEventManager.getInstance().fireEvent(node, + DatabaseModelEvent.EVENT_TYPE.REMOVE); + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#isLoading() + */ + public boolean isLoading() + { + return isLoading; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#setLoading(boolean) + */ + public void setLoading(boolean isLoading) + { + this.isLoading = isLoading; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#getId() + */ + public String getId() + { + return id; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#setId(java.lang.String) + */ + public void setId(String id) + { + this.id = id; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#getName() + */ + public String getName() + { + return name; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#setName(java.lang.String) + */ + public void setName(String name) + { + this.name = name; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#getIcon() + */ + public ImageDescriptor getIcon() + { + return icon; + } + + /** + * Retrieves an icon image descriptor from other Eclipse bundles (JDT, Datatools, ADT, etc). + * + * @param bundleId The id of the bundle where the icon should be retrieved from + * @param iconPath The path of the icon inside the bundle + * + * @return The image descriptor for the desired icon, or the default icon from the db code plugin + * in case the process of retrieving the desired icon fails + */ + protected final ImageDescriptor getSpecificIcon(String bundleId, String iconPath) + { + ImageDescriptor imgDesc = null; + + try + { + Bundle bundle = Platform.getBundle(bundleId); + URL path = bundle.getEntry("/"); //$NON-NLS-1$ + URL fullPathString = new URL(path, iconPath); + imgDesc = ImageDescriptor.createFromURL(fullPathString); + } + catch (Exception e) + { + StudioLogger.error(getClass(), "Error retrieving icon for tree node", e); //$NON-NLS-1$ + } + if (imgDesc == null) + { + imgDesc = getIcon(); + } + + return imgDesc; + + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#setIcon(org.eclipse.jface.resource.ImageDescriptor) + */ + public void setIcon(ImageDescriptor icon) + { + this.icon = icon; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#canRefresh() + */ + public IStatus canRefresh() + { + return Status.OK_STATUS; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#isLeaf() + */ + public abstract boolean isLeaf(); + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "AbstractTreeNode [id=" + id + ", name=" + name + ", parent=" + parent + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#clean() + */ + public void cleanUp() + { + for (ITreeNode node : children) + { + node.cleanUp(); + } + if (this instanceof ISaveStateTreeNode) + { + SaveStateManager.getInstance().unregisterSaveStateNode((ISaveStateTreeNode) this); + } + } + + public void setNodeStatus(IStatus status) + { + nodeStatus = status; + //update node label/icon/decoration given that its status has changed + DatabaseModelEventManager.getInstance().fireEvent(this, EVENT_TYPE.UPDATE); + } + + public IStatus getNodeStatus() + { + return nodeStatus; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionFilter#testAttribute(java.lang.Object, java.lang.String, java.lang.String) + */ + public boolean testAttribute(Object target, String name, String value) + { + boolean result = false; + + if (name.equals(PROP_NAME_NODE_STATUS)) + { + if (value.equals(PROP_VALUE_NODE_STATUS_ERROR)) + { + result = !getNodeStatus().isOK(); + } + } + + return result; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#setTooltip(java.lang.String) + */ + public void setTooltip(String tooltip) + { + this.tooltip = tooltip; + } + + /* (non-Javadoc) + * @see com.motorolamobility.studio.android.db.core.ui.ITreeNode#getTooltip() + */ + public String getTooltip() + { + return tooltip; + } + +} |