1 /*******************************************************************************
2  * Copyright (c) 2002, 2005 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM - Initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.core.tools;
15 
16 import org.eclipse.jface.viewers.ITreeContentProvider;
17 import org.eclipse.jface.viewers.Viewer;
18 
19 /**
20  * An abstract base class for hierarchical content providers. Uses
21  * <code>TreeContentProviderNode</code> objects to keep a hierarchical
22  * data model. Subclasses must provide an implementation for the
23  * <code>#rebuild(Object)</code> operation in order to define how the data model
24  * will be built upon a given input provided by the viewer.
25  */
26 
27 public abstract class AbstractTreeContentProvider implements ITreeContentProvider {
28 
29 	/**
30 	 * Flag for omitting the root or not when providing the contents.
31 	 */
32 	private boolean omitRoot;
33 
34 	/**
35 	 * The root node.
36 	 */
37 	private TreeContentProviderNode rootNode;
38 
39 	/**
40 	 * Constructs a AbstractTreeContentProvider.
41 	 *
42 	 * @param omitRoot if true, the root node will be omitted when providing
43 	 * contents.
44 	 */
AbstractTreeContentProvider(boolean omitRoot)45 	protected AbstractTreeContentProvider(boolean omitRoot) {
46 		this.omitRoot = omitRoot;
47 	}
48 
49 	/**
50 	 * Constructs a AbstractTreeContentProvider that will omit the root node when
51 	 * providing contents.
52 	 *
53 	 * @see #AbstractTreeContentProvider(boolean)
54 	 */
AbstractTreeContentProvider()55 	protected AbstractTreeContentProvider() {
56 		this(true);
57 	}
58 
59 	/**
60 	 * Returns the child elements of the given parent element.
61 	 *
62 	 * @return an array containing <code>parentElement</code>'s children.
63 	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(
64 	 * java.lang.Object)
65 	 * @see org.eclipse.core.tools.TreeContentProviderNode#getChildren()
66 	 */
67 	@Override
getChildren(Object parentElement)68 	public Object[] getChildren(Object parentElement) {
69 		if (!(parentElement instanceof TreeContentProviderNode))
70 			return null;
71 
72 		TreeContentProviderNode treeNode = (TreeContentProviderNode) parentElement;
73 		return treeNode.getChildren();
74 	}
75 
76 	/**
77 	 * Returns the parent for the given element, or <code>null</code>
78 	 * indicating that the parent can't be computed.
79 	 *
80 	 * @return <code>element</code>'s parent node or null, if it is a root node
81 	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(
82 	 * java.lang.Object)
83 	 * @see org.eclipse.core.tools.TreeContentProviderNode#getParent()
84 	 */
85 	@Override
getParent(Object element)86 	public Object getParent(Object element) {
87 		if (!(element instanceof TreeContentProviderNode))
88 			return null;
89 
90 		TreeContentProviderNode treeNode = (TreeContentProviderNode) element;
91 		return treeNode.getParent();
92 	}
93 
94 	/**
95 	 * Returns whether the given element has children.
96 	 *
97 	 * @return true, if <code>element</code> has children, false otherwise
98 	 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(
99 	 * java.lang.Object)
100 	 * @see org.eclipse.core.tools.TreeContentProviderNode#hasChildren()
101 	 */
102 	@Override
hasChildren(Object element)103 	public boolean hasChildren(Object element) {
104 		return element instanceof TreeContentProviderNode && ((TreeContentProviderNode) element).hasChildren();
105 	}
106 
107 	/**
108 	 * Returns the elements to display in the viewer
109 	 * when its input is set to the given element.
110 	 *
111 	 * @return this content provider root element's children
112 	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(
113 	 * java.lang.Object)
114 	 */
115 	@Override
getElements(Object inputElement)116 	public Object[] getElements(Object inputElement) {
117 		if (rootNode == null)
118 			return new Object[0];
119 
120 		return omitRoot ? rootNode.getChildren() : new Object[] {rootNode};
121 	}
122 
123 	/**
124 	 * Disposes of this content provider.
125 	 * This is called by the viewer when it is disposed.
126 	 *
127 	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
128 	 */
129 	@Override
dispose()130 	public void dispose() {
131 		rootNode = null;
132 	}
133 
134 	/**
135 	 * Helper method that creates a root node given a node name and value.
136 	 *
137 	 * @param name the name of the node
138 	 * @param value the value of the node. May be null.
139 	 * @return the tree node created
140 	 * @see TreeContentProviderNode#TreeContentProviderNode(String, Object)
141 	 */
createNode(String name, Object value)142 	protected TreeContentProviderNode createNode(String name, Object value) {
143 		return new TreeContentProviderNode(name, value);
144 	}
145 
146 	/**
147 	 * Helper method that creates a root node given a node name and no value.
148 	 *
149 	 * @param name the name of the node
150 	 * @return the tree node created
151 	 * @see TreeContentProviderNode#TreeContentProviderNode(String)
152 	 */
createNode(String name)153 	protected TreeContentProviderNode createNode(String name) {
154 		return new TreeContentProviderNode(name);
155 	}
156 
157 	/**
158 	 * Notifies this content provider that the given viewer's input
159 	 * has been switched to a different element.
160 	 * Rebuilds this content provider's state from a given resource.
161 	 *
162 	 * @param viewer the viewer
163 	 * @param oldInput ignored
164 	 * @param input the new input. If null, clears this content provider. If not,
165 	 * is passed in a call to <code>rebuild(Object)</code>.
166 	 * @see
167 	 * org.eclipse.jface.viewers.IContentProvider#inputChanged(
168 	 * org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
169 	 * @see #rebuild(Viewer, Object)
170 	 */
171 	@Override
inputChanged(Viewer viewer, Object oldInput, final Object input)172 	public void inputChanged(Viewer viewer, Object oldInput, final Object input) {
173 		if (input == null) {
174 			rootNode = createNode("root"); //$NON-NLS-1$
175 			return;
176 		}
177 
178 		if (!acceptInput(input))
179 			return;
180 
181 		rootNode = createNode("root"); //$NON-NLS-1$
182 		rebuild(viewer, input);
183 	}
184 
185 	/**
186 	 * Reconstructs this content provider data model upon the provided input object.
187 	 *
188 	 * @param input the new input object - must not be null
189 	 * @param viewer the corresponding viewer
190 	 */
rebuild(Viewer viewer, Object input)191 	protected abstract void rebuild(Viewer viewer, Object input);
192 
193 	/**
194 	 * Returns true if the provided input is accepted by this content provider.
195 	 *
196 	 * @param input an input object
197 	 * @return boolean true if the provided object is accepted, false otherwise
198 	 */
acceptInput(Object input)199 	protected abstract boolean acceptInput(Object input);
200 
201 	/**
202 	 * Returns the rootNode.
203 	 *
204 	 * @return this content provider root node
205 	 */
getRootNode()206 	protected TreeContentProviderNode getRootNode() {
207 		return rootNode;
208 	}
209 
210 }
211