/* 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 org.activiti.designer.eclipse.navigator; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.Viewer; /** * @author Tiese Barrell */ public abstract class AbstractTreeContentProvider implements ITreeContentProvider, IResourceChangeListener, IResourceDeltaVisitor { protected static final Object[] NO_CHILDREN = new Object[0]; private final Map<IResource, List<TreeNode>> cachedModelMap = new HashMap<IResource, List<TreeNode>>(); private StructuredViewer viewer; public AbstractTreeContentProvider() { super(); ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); } @Override public void dispose() { cachedModelMap.clear(); ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); } @Override public void inputChanged(Viewer aViewer, Object oldInput, Object newInput) { if (oldInput != null && !oldInput.equals(newInput)) cachedModelMap.clear(); viewer = (StructuredViewer) aViewer; } @Override public Object[] getElements(Object inputElement) { return getChildren(inputElement); } @Override public Object getParent(Object element) { if (element instanceof TreeNode) { TreeNode data = (TreeNode) element; return data.getParent(); } return null; } @Override public Object[] getChildren(final Object parentElement) { Object[] result = null; if (parentElement instanceof TreeNode) { final TreeNode treeNode = (TreeNode) parentElement; result = treeNode.hasChildren() ? getChildrenAsArray(treeNode) : NO_CHILDREN; } else { result = getChildrenForElement(parentElement); } return result != null ? result : NO_CHILDREN; } @Override public boolean hasChildren(Object element) { if (element instanceof TreeNode) { return ((TreeNode) element).hasChildren(); } else { return hasChildrenForElement(element); } } protected final StructuredViewer getStructuredViewer() { return viewer; } protected final void addModelToCache(final IResource resource, final List<TreeNode> treeNodes) { cachedModelMap.put(resource, treeNodes); } protected final void removeModelFromCache(final IResource resource) { if (isModelCachedForResource(resource)) { cachedModelMap.remove(resource); } } protected final boolean isModelCachedForResource(final IResource resource) { return cachedModelMap.containsKey(resource); } protected final List<TreeNode> getCachedChildrenForResource(final IResource resource) { return cachedModelMap.get(resource); } /** * Invoked if the element is not a {@link TreeNode}. Subclasses must implement * this method to indicate whether they will provide children for elements * that are not {@link TreeNode}s. * * @param element * the element to determine children for * @return true if the element has children, false otherwise */ protected abstract boolean hasChildrenForElement(final Object element); /** * Invoked if the element is not a {@link TreeNode}. Subclasses must implement * this method to provide children for elements that are not {@link TreeNode} * s. * * @param element * the element to determine children for * @return an array of child objects */ protected abstract Object[] getChildrenForElement(final Object parentElement); protected Object[] getChildrenAsArray(final TreeNode treeNode) { Object[] result = null; final List<TreeNode> children = treeNode.getChildren(); if (children.size() > 0) { result = children.toArray(); } return result; } @Override public void resourceChanged(final IResourceChangeEvent event) { IResourceDelta delta = event.getDelta(); try { delta.accept(this); } catch (CoreException e) { e.printStackTrace(); } } }