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