]> git.argeo.org Git - lgpl/argeo-commons.git/blob - GenericJcrBrowser.java
1b62582b08232d1fd52c704399fe8046f42675a6
[lgpl/argeo-commons.git] / GenericJcrBrowser.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.jcr.ui.explorer.views;
17
18 import java.util.List;
19
20 import javax.jcr.Property;
21 import javax.jcr.PropertyType;
22 import javax.jcr.Repository;
23 import javax.jcr.RepositoryException;
24 import javax.jcr.RepositoryFactory;
25 import javax.jcr.Session;
26 import javax.jcr.Value;
27 import javax.jcr.observation.Event;
28 import javax.jcr.observation.EventListener;
29 import javax.jcr.observation.ObservationManager;
30
31 import org.argeo.ArgeoException;
32 import org.argeo.eclipse.ui.TreeParent;
33 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
34 import org.argeo.eclipse.ui.jcr.utils.NodeViewerComparer;
35 import org.argeo.eclipse.ui.jcr.views.AbstractJcrBrowser;
36 import org.argeo.jcr.RepositoryRegister;
37 import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
38 import org.argeo.jcr.ui.explorer.browser.NodeContentProvider;
39 import org.argeo.jcr.ui.explorer.browser.NodeLabelProvider;
40 import org.argeo.jcr.ui.explorer.browser.PropertiesContentProvider;
41 import org.argeo.jcr.ui.explorer.model.SingleJcrNode;
42 import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
43 import org.argeo.jcr.ui.explorer.utils.JcrUiUtils;
44 import org.argeo.util.security.Keyring;
45 import org.eclipse.jface.action.MenuManager;
46 import org.eclipse.jface.viewers.ColumnLabelProvider;
47 import org.eclipse.jface.viewers.ISelectionChangedListener;
48 import org.eclipse.jface.viewers.IStructuredSelection;
49 import org.eclipse.jface.viewers.ITreeContentProvider;
50 import org.eclipse.jface.viewers.SelectionChangedEvent;
51 import org.eclipse.jface.viewers.StructuredSelection;
52 import org.eclipse.jface.viewers.TableViewer;
53 import org.eclipse.jface.viewers.TableViewerColumn;
54 import org.eclipse.jface.viewers.TreeViewer;
55 import org.eclipse.swt.SWT;
56 import org.eclipse.swt.custom.SashForm;
57 import org.eclipse.swt.layout.FillLayout;
58 import org.eclipse.swt.layout.GridData;
59 import org.eclipse.swt.layout.GridLayout;
60 import org.eclipse.swt.widgets.Composite;
61 import org.eclipse.swt.widgets.Display;
62 import org.eclipse.swt.widgets.Menu;
63
64 /**
65 * Basic View to display a sash form to browse a JCR compliant multirepository
66 * environment
67 */
68 public class GenericJcrBrowser extends AbstractJcrBrowser {
69 public final static String ID = JcrExplorerPlugin.ID + ".browserView";
70 private boolean sortChildNodes = false;
71
72 /* DEPENDENCY INJECTION */
73 private Keyring keyring;
74 private RepositoryRegister repositoryRegister;
75 private RepositoryFactory repositoryFactory;
76 private Repository nodeRepository;
77 /**
78 * A session of the logged in user on the default workspace of the node
79 * repository.
80 */
81 private Session userSession;
82
83 // This page widgets
84 private TreeViewer nodesViewer;
85 private NodeContentProvider nodeContentProvider;
86 private TableViewer propertiesViewer;
87 private EventListener resultsObserver;
88
89 @Override
90 public void createPartControl(Composite parent) {
91 parent.setLayout(new FillLayout());
92 SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
93 sashForm.setSashWidth(4);
94 sashForm.setLayout(new FillLayout());
95
96 // Create the tree on top of the view
97 Composite top = new Composite(sashForm, SWT.NONE);
98 GridLayout gl = new GridLayout(1, false);
99 top.setLayout(gl);
100
101 try {
102 this.userSession = this.nodeRepository.login();
103 } catch (RepositoryException e) {
104 throw new ArgeoException("Cannot open user session", e);
105 }
106
107 nodeContentProvider = new NodeContentProvider(userSession, keyring,
108 repositoryRegister, repositoryFactory, sortChildNodes);
109
110 // nodes viewer
111 nodesViewer = createNodeViewer(top, nodeContentProvider);
112
113 // context menu : it is completely defined in the plugin.xml file.
114 MenuManager menuManager = new MenuManager();
115 Menu menu = menuManager.createContextMenu(nodesViewer.getTree());
116
117 nodesViewer.getTree().setMenu(menu);
118 getSite().registerContextMenu(menuManager, nodesViewer);
119 getSite().setSelectionProvider(nodesViewer);
120
121 nodesViewer.setInput(getViewSite());
122
123 // Create the property viewer on the bottom
124 Composite bottom = new Composite(sashForm, SWT.NONE);
125 bottom.setLayout(new GridLayout(1, false));
126 propertiesViewer = createPropertiesViewer(bottom);
127
128 sashForm.setWeights(getWeights());
129 nodesViewer.setComparer(new NodeViewerComparer());
130 }
131
132 /**
133 * To be overridden to adapt size of form and result frames.
134 */
135 protected int[] getWeights() {
136 return new int[] { 70, 30 };
137 }
138
139 protected TreeViewer createNodeViewer(Composite parent,
140 final ITreeContentProvider nodeContentProvider) {
141
142 final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
143
144 tmpNodeViewer.getTree().setLayoutData(
145 new GridData(SWT.FILL, SWT.FILL, true, true));
146
147 tmpNodeViewer.setContentProvider(nodeContentProvider);
148 tmpNodeViewer.setLabelProvider(new NodeLabelProvider());
149 tmpNodeViewer
150 .addSelectionChangedListener(new ISelectionChangedListener() {
151 public void selectionChanged(SelectionChangedEvent event) {
152 if (!event.getSelection().isEmpty()) {
153 IStructuredSelection sel = (IStructuredSelection) event
154 .getSelection();
155 Object firstItem = sel.getFirstElement();
156 if (firstItem instanceof SingleJcrNode)
157 propertiesViewer
158 .setInput(((SingleJcrNode) firstItem)
159 .getNode());
160 } else {
161 propertiesViewer.setInput(getViewSite());
162 }
163 }
164 });
165
166 resultsObserver = new TreeObserver(tmpNodeViewer.getTree().getDisplay());
167 if (keyring != null)
168 try {
169 ObservationManager observationManager = userSession
170 .getWorkspace().getObservationManager();
171 observationManager.addEventListener(resultsObserver,
172 Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, "/",
173 true, null, null, false);
174 } catch (RepositoryException e) {
175 throw new ArgeoException("Cannot register listeners", e);
176 }
177
178 tmpNodeViewer
179 .addDoubleClickListener(new GenericNodeDoubleClickListener(
180 tmpNodeViewer));
181 return tmpNodeViewer;
182 }
183
184 protected TableViewer createPropertiesViewer(Composite parent) {
185 propertiesViewer = new TableViewer(parent);
186 propertiesViewer.getTable().setLayoutData(
187 new GridData(SWT.FILL, SWT.FILL, true, true));
188 propertiesViewer.getTable().setHeaderVisible(true);
189 propertiesViewer.setContentProvider(new PropertiesContentProvider());
190 TableViewerColumn col = new TableViewerColumn(propertiesViewer,
191 SWT.NONE);
192 col.getColumn().setText("Name");
193 col.getColumn().setWidth(200);
194 col.setLabelProvider(new ColumnLabelProvider() {
195 public String getText(Object element) {
196 try {
197 return ((Property) element).getName();
198 } catch (RepositoryException e) {
199 throw new ArgeoException(
200 "Unexpected exception in label provider", e);
201 }
202 }
203 });
204 col = new TableViewerColumn(propertiesViewer, SWT.NONE);
205 col.getColumn().setText("Value");
206 col.getColumn().setWidth(400);
207 col.setLabelProvider(new ColumnLabelProvider() {
208 public String getText(Object element) {
209 try {
210 Property property = (Property) element;
211 if (property.getType() == PropertyType.BINARY)
212 return "<binary>";
213 else if (property.isMultiple()) {
214 StringBuffer buf = new StringBuffer("[");
215 Value[] values = property.getValues();
216 for (int i = 0; i < values.length; i++) {
217 if (i != 0)
218 buf.append(", ");
219 buf.append(values[i].getString());
220 }
221 buf.append(']');
222 return buf.toString();
223 } else
224 return property.getValue().getString();
225 } catch (RepositoryException e) {
226 throw new ArgeoException(
227 "Unexpected exception in label provider", e);
228 }
229 }
230 });
231 col = new TableViewerColumn(propertiesViewer, SWT.NONE);
232 col.getColumn().setText("Type");
233 col.getColumn().setWidth(200);
234 col.setLabelProvider(new ColumnLabelProvider() {
235 public String getText(Object element) {
236 try {
237 return PropertyType.nameFromValue(((Property) element)
238 .getType());
239 } catch (RepositoryException e) {
240 throw new ArgeoException(
241 "Unexpected exception in label provider", e);
242 }
243 }
244 });
245 propertiesViewer.setInput(getViewSite());
246 return propertiesViewer;
247 }
248
249 @Override
250 public void dispose() {
251 super.dispose();
252 }
253
254 @Override
255 protected TreeViewer getNodeViewer() {
256 return nodesViewer;
257 }
258
259 /** Notifies the current view that a node has been added */
260 public void nodeAdded(TreeParent parentNode) {
261 // insure that Ui objects have been correctly created:
262 JcrUiUtils.forceRefreshIfNeeded(parentNode);
263 getNodeViewer().refresh(parentNode);
264 getNodeViewer().expandToLevel(parentNode, 1);
265 }
266
267 /** Notifies the current view that a node has been added */
268 public void nodeRemoved(TreeParent parentNode) {
269 IStructuredSelection newSel = new StructuredSelection(parentNode);
270 getNodeViewer().setSelection(newSel, true);
271 // Force refresh
272 IStructuredSelection tmpSel = (IStructuredSelection) getNodeViewer()
273 .getSelection();
274 getNodeViewer().refresh(tmpSel.getFirstElement());
275 }
276
277 class TreeObserver extends AsyncUiEventListener {
278
279 public TreeObserver(Display display) {
280 super(display);
281 }
282
283 @Override
284 protected Boolean willProcessInUiThread(List<Event> events)
285 throws RepositoryException {
286 for (Event event : events) {
287 if (getLog().isTraceEnabled())
288 getLog().debug("Received event " + event);
289 String path = event.getPath();
290 int index = path.lastIndexOf('/');
291 String propertyName = path.substring(index + 1);
292 if (getLog().isTraceEnabled())
293 getLog().debug("Concerned property " + propertyName);
294 }
295 return false;
296 }
297
298 protected void onEventInUiThread(List<Event> events)
299 throws RepositoryException {
300 if (getLog().isTraceEnabled())
301 getLog().trace("Refresh result list");
302 nodesViewer.refresh();
303 }
304
305 }
306
307 public void setSortChildNodes(boolean sortChildNodes) {
308 this.sortChildNodes = sortChildNodes;
309 }
310
311 public boolean getSortChildNodes() {
312 return sortChildNodes;
313 }
314
315 /* DEPENDENCY INJECTION */
316 public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
317 this.repositoryRegister = repositoryRegister;
318 }
319
320 public void setKeyring(Keyring keyring) {
321 this.keyring = keyring;
322 }
323
324 public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
325 this.repositoryFactory = repositoryFactory;
326 }
327
328 public void setNodeRepository(Repository nodeRepository) {
329 this.nodeRepository = nodeRepository;
330 }
331
332 }