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