1 /*******************************************************************************
2  * Copyright (c) 2008 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 Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.equinox.internal.security.ui.storage.view;
15 
16 import org.eclipse.equinox.internal.security.ui.Activator;
17 import org.eclipse.equinox.internal.security.ui.nls.SecUIMessages;
18 import org.eclipse.equinox.internal.security.ui.storage.IStorageConst;
19 import org.eclipse.equinox.security.storage.ISecurePreferences;
20 import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
21 import org.eclipse.jface.action.*;
22 import org.eclipse.jface.resource.ImageDescriptor;
23 import org.eclipse.jface.viewers.*;
24 import org.eclipse.jface.window.Window;
25 import org.eclipse.swt.graphics.Image;
26 import org.eclipse.swt.widgets.Menu;
27 import org.eclipse.swt.widgets.Tree;
28 
29 /**
30  * View of nodes available on the secure preferences tree.
31  */
32 public class NodesView {
33 
34 	/**
35 	 * For tree viewer to work, the input must not be the same as the root node
36 	 * or it will get short circuit. Also input can not be null - so have to pass
37 	 * some dummy value as an input.
38 	 */
39 	final private static String defaultPrefs = "default"; //$NON-NLS-1$
40 
41 	protected ISecurePreferencesSelection parentView;
42 	protected TreeViewer nodeTreeViewer;
43 
44 	protected ViewContentProvider contentProvider;
45 
46 	protected Action addNodeAction;
47 	protected Action removeNodeAction;
48 	protected Action refreshNodesAction;
49 
50 	class ViewContentProvider implements ITreeContentProvider {
51 
inputChanged(Viewer v, Object oldInput, Object newInput)52 		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
53 			if (nodeTreeViewer != null) {
54 				nodeTreeViewer.setSelection(null);
55 				nodeTreeViewer.refresh();
56 			}
57 		}
58 
dispose()59 		public void dispose() {
60 			// nothing to do
61 		}
62 
getElements(Object parent)63 		public Object[] getElements(Object parent) {
64 			if (defaultPrefs.equals(parent))
65 				return new Object[] {SecurePreferencesFactory.getDefault()};
66 			return new Object[0];
67 		}
68 
getParent(Object child)69 		public Object getParent(Object child) {
70 			if (!(child instanceof ISecurePreferences))
71 				return null;
72 			ISecurePreferences node = (ISecurePreferences) child;
73 			ISecurePreferences parentNode = node.parent();
74 			if (parentNode == null)
75 				return null;
76 			return node.parent();
77 		}
78 
getChildren(Object parent)79 		public Object[] getChildren(Object parent) {
80 			if (!(parent instanceof ISecurePreferences))
81 				return new Object[0];
82 			ISecurePreferences node = (ISecurePreferences) parent;
83 			String[] childrenNames = node.childrenNames();
84 			ISecurePreferences[] result = new ISecurePreferences[childrenNames.length];
85 			for (int i = 0; i < childrenNames.length; i++)
86 				result[i] = node.node(childrenNames[i]);
87 			return result;
88 		}
89 
hasChildren(Object parent)90 		public boolean hasChildren(Object parent) {
91 			if (!(parent instanceof ISecurePreferences))
92 				return false;
93 			ISecurePreferences node = (ISecurePreferences) parent;
94 			String[] childrenNames = node.childrenNames();
95 			return (childrenNames.length > 0);
96 		}
97 	}
98 
99 	class ViewLabelProvider extends LabelProvider {
100 
getText(Object obj)101 		public String getText(Object obj) {
102 			if (!(obj instanceof ISecurePreferences))
103 				return obj.toString();
104 			ISecurePreferences node = (ISecurePreferences) obj;
105 			if (node.parent() == null)
106 				return '[' + SecUIMessages.rootNodeName + ']';
107 			return node.name();
108 		}
109 
getImage(Object obj)110 		public Image getImage(Object obj) {
111 			return null;
112 		}
113 	}
114 
NodesView(Tree nodeTree, final ISecurePreferencesSelection parentView)115 	public NodesView(Tree nodeTree, final ISecurePreferencesSelection parentView) {
116 		this.parentView = parentView;
117 
118 		nodeTreeViewer = new TreeViewer(nodeTree);
119 		contentProvider = new ViewContentProvider();
120 		nodeTreeViewer.setContentProvider(contentProvider);
121 		nodeTreeViewer.setLabelProvider(new ViewLabelProvider());
122 		nodeTreeViewer.setInput(defaultPrefs);
123 
124 		nodeTreeViewer.addSelectionChangedListener(event -> {
125 			TreeSelection selection = (TreeSelection) event.getSelection();
126 			Object selected = selection.getFirstElement();
127 			if (selected instanceof ISecurePreferences)
128 				parentView.setSelection((ISecurePreferences) selected);
129 			else
130 				parentView.setSelection(null);
131 		});
132 
133 		if (Activator.getDefault().debugStorageContents()) {
134 			makeActions();
135 			hookContextMenu();
136 		}
137 	}
138 
hookContextMenu()139 	private void hookContextMenu() {
140 		MenuManager menuMgr = new MenuManager(SecUIMessages.nodesContextMenu);
141 
142 		menuMgr.addMenuListener(manager -> {
143 			boolean canRemove = false;
144 			boolean canAdd = false;
145 			TreeSelection selection = (TreeSelection) nodeTreeViewer.getSelection();
146 			Object selected = selection.getFirstElement();
147 			if (selected instanceof ISecurePreferences) {
148 				ISecurePreferences node = (ISecurePreferences) selected;
149 				boolean isRoot = (node.parent() == null);
150 				boolean isInternal = node.absolutePath().startsWith(IStorageConst.PROVIDER_NODE);
151 				canRemove = (!isRoot && !isInternal);
152 				canAdd = !isInternal;
153 			}
154 			removeNodeAction.setEnabled(canRemove);
155 			addNodeAction.setEnabled(canAdd);
156 		});
157 		Menu menu = menuMgr.createContextMenu(nodeTreeViewer.getControl());
158 		nodeTreeViewer.getControl().setMenu(menu);
159 
160 		// fill context menu
161 		menuMgr.add(refreshNodesAction);
162 		menuMgr.add(new Separator());
163 		menuMgr.add(addNodeAction);
164 		menuMgr.add(removeNodeAction);
165 	}
166 
makeActions()167 	private void makeActions() {
168 		refreshNodesAction = new Action() {
169 			public void run() {
170 				nodeTreeViewer.refresh();
171 			}
172 		};
173 		refreshNodesAction.setText(SecUIMessages.refreshNodesCommand);
174 		refreshNodesAction.setToolTipText(SecUIMessages.refreshNodesCommandTip);
175 		refreshNodesAction.setImageDescriptor(ImageDescriptor.createFromFile(NodesView.class, "/icons/storage/node_refresh.gif")); //$NON-NLS-1$
176 
177 		addNodeAction = new Action() {
178 			public void run() {
179 				TreeSelection selection = (TreeSelection) nodeTreeViewer.getSelection();
180 				Object selected = selection.getFirstElement();
181 				if (selected instanceof ISecurePreferences) {
182 					ISecurePreferences node = (ISecurePreferences) selected;
183 
184 					NewNodeDialog nodeDialog = new NewNodeDialog(nodeTreeViewer.getControl().getShell());
185 					if (nodeDialog.open() != Window.OK)
186 						return;
187 					String name = nodeDialog.getNodeName();
188 					ISecurePreferences child = node.node(name);
189 					parentView.modified();
190 
191 					// expand and select new node
192 					ISecurePreferences parentNode = child.parent();
193 					if (parentNode != null)
194 						nodeTreeViewer.refresh(parentNode, false);
195 					else
196 						nodeTreeViewer.refresh(false);
197 					nodeTreeViewer.expandToLevel(child, 0);
198 					nodeTreeViewer.setSelection(new StructuredSelection(child), true);
199 				}
200 
201 			}
202 		};
203 		addNodeAction.setText(SecUIMessages.addNodeCommand);
204 		addNodeAction.setToolTipText(SecUIMessages.addNodeCommandTip);
205 		addNodeAction.setImageDescriptor(ImageDescriptor.createFromFile(NodesView.class, "/icons/storage/node_new.gif")); //$NON-NLS-1$
206 
207 		removeNodeAction = new Action() {
208 			public void run() {
209 				TreeSelection selection = (TreeSelection) nodeTreeViewer.getSelection();
210 				Object selected = selection.getFirstElement();
211 
212 				if (selected instanceof ISecurePreferences) {
213 					ISecurePreferences node = (ISecurePreferences) selected;
214 					ISecurePreferences parentNode = node.parent();
215 					if (parentNode == null)
216 						return; // can't remove root node
217 					node.removeNode();
218 					parentView.modified();
219 
220 					// refresh parent node and select it
221 					nodeTreeViewer.refresh(parentNode, false);
222 					nodeTreeViewer.setSelection(new StructuredSelection(parentNode), true);
223 				}
224 			}
225 		};
226 		removeNodeAction.setText(SecUIMessages.removeNodeCommand);
227 		removeNodeAction.setToolTipText(SecUIMessages.removeNodeCommandTip);
228 		removeNodeAction.setImageDescriptor(ImageDescriptor.createFromFile(NodesView.class, "/icons/storage/node_delete.gif")); //$NON-NLS-1$
229 	}
230 
setFocus()231 	public void setFocus() {
232 		nodeTreeViewer.getControl().setFocus();
233 	}
234 
postDeleted()235 	public void postDeleted() {
236 		if (contentProvider == null)
237 			return;
238 		nodeTreeViewer.setSelection(StructuredSelection.EMPTY);
239 		nodeTreeViewer.refresh();
240 	}
241 }
242