]> git.argeo.org Git - gpl/argeo-jcr.git/blob - swt/org.argeo.cms.jcr.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java
Move legacy code and icons to Argeo JCR
[gpl/argeo-jcr.git] / swt / org.argeo.cms.jcr.e4 / src / org / argeo / cms / e4 / jcr / JcrBrowserView.java
1 package org.argeo.cms.e4.jcr;
2
3 import java.util.List;
4
5 import javax.annotation.PostConstruct;
6 import javax.annotation.PreDestroy;
7 import javax.inject.Inject;
8 import javax.jcr.Property;
9 import javax.jcr.PropertyType;
10 import javax.jcr.Repository;
11 import javax.jcr.RepositoryException;
12 import javax.jcr.RepositoryFactory;
13 import javax.jcr.Session;
14 import javax.jcr.Value;
15 import javax.jcr.observation.Event;
16 import javax.jcr.observation.EventListener;
17 import javax.jcr.observation.ObservationManager;
18
19 import org.argeo.api.cms.CmsConstants;
20 import org.argeo.cms.security.CryptoKeyring;
21 import org.argeo.cms.security.Keyring;
22 import org.argeo.cms.swt.CmsException;
23 import org.argeo.cms.swt.CmsSwtUtils;
24 import org.argeo.cms.ui.jcr.JcrBrowserUtils;
25 import org.argeo.cms.ui.jcr.NodeContentProvider;
26 import org.argeo.cms.ui.jcr.NodeLabelProvider;
27 import org.argeo.cms.ui.jcr.OsgiRepositoryRegister;
28 import org.argeo.cms.ui.jcr.PropertiesContentProvider;
29 import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem;
30 import org.argeo.cms.ux.widgets.TreeParent;
31 import org.argeo.eclipse.ui.EclipseUiException;
32 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
33 import org.argeo.eclipse.ui.jcr.util.NodeViewerComparer;
34 import org.argeo.jcr.JcrUtils;
35 import org.eclipse.e4.core.contexts.IEclipseContext;
36 import org.eclipse.e4.core.di.annotations.Optional;
37 import org.eclipse.e4.ui.services.EMenuService;
38 import org.eclipse.e4.ui.workbench.modeling.EPartService;
39 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
40 import org.eclipse.jface.viewers.ColumnLabelProvider;
41 import org.eclipse.jface.viewers.IBaseLabelProvider;
42 import org.eclipse.jface.viewers.ISelectionChangedListener;
43 import org.eclipse.jface.viewers.IStructuredSelection;
44 import org.eclipse.jface.viewers.ITreeContentProvider;
45 import org.eclipse.jface.viewers.SelectionChangedEvent;
46 import org.eclipse.jface.viewers.StructuredSelection;
47 import org.eclipse.jface.viewers.TableViewer;
48 import org.eclipse.jface.viewers.TableViewerColumn;
49 import org.eclipse.jface.viewers.TreeViewer;
50 import org.eclipse.swt.SWT;
51 import org.eclipse.swt.custom.SashForm;
52 import org.eclipse.swt.layout.FillLayout;
53 import org.eclipse.swt.layout.GridData;
54 import org.eclipse.swt.widgets.Composite;
55 import org.eclipse.swt.widgets.Display;
56
57 /**
58 * Basic View to display a sash form to browse a JCR compliant multiple
59 * repository environment
60 */
61 public class JcrBrowserView {
62 final static String ID = "org.argeo.cms.e4.jcrbrowser";
63 final static String NODE_VIEWER_POPUP_MENU_ID = "org.argeo.cms.e4.popupmenu.nodeViewer";
64
65 private boolean sortChildNodes = true;
66
67 /* DEPENDENCY INJECTION */
68 @Inject
69 @Optional
70 private Keyring keyring;
71 @Inject
72 private RepositoryFactory repositoryFactory;
73 @Inject
74 private Repository nodeRepository;
75
76 // Current user session on the home repository default workspace
77 private Session userSession;
78
79 private OsgiRepositoryRegister repositoryRegister = new OsgiRepositoryRegister();
80
81 // This page widgets
82 private TreeViewer nodesViewer;
83 private NodeContentProvider nodeContentProvider;
84 private TableViewer propertiesViewer;
85 private EventListener resultsObserver;
86
87 @PostConstruct
88 public void createPartControl(Composite parent, IEclipseContext context, EPartService partService,
89 ESelectionService selectionService, EMenuService menuService) {
90 repositoryRegister.init();
91
92 parent.setLayout(new FillLayout());
93 SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
94 // sashForm.setSashWidth(4);
95 // sashForm.setLayout(new FillLayout());
96
97 // Create the tree on top of the view
98 Composite top = new Composite(sashForm, SWT.NONE);
99 // GridLayout gl = new GridLayout(1, false);
100 top.setLayout(CmsSwtUtils.noSpaceGridLayout());
101
102 try {
103 this.userSession = this.nodeRepository.login(CmsConstants.HOME_WORKSPACE);
104 } catch (RepositoryException e) {
105 throw new CmsException("Cannot open user session", e);
106 }
107
108 nodeContentProvider = new NodeContentProvider(userSession, keyring, repositoryRegister, repositoryFactory,
109 sortChildNodes);
110
111 // nodes viewer
112 nodesViewer = createNodeViewer(top, nodeContentProvider);
113
114 // context menu : it is completely defined in the plugin.xml file.
115 // MenuManager menuManager = new MenuManager();
116 // Menu menu = menuManager.createContextMenu(nodesViewer.getTree());
117
118 // nodesViewer.getTree().setMenu(menu);
119
120 nodesViewer.setInput("");
121
122 // Create the property viewer on the bottom
123 Composite bottom = new Composite(sashForm, SWT.NONE);
124 bottom.setLayout(CmsSwtUtils.noSpaceGridLayout());
125 propertiesViewer = createPropertiesViewer(bottom);
126
127 sashForm.setWeights(getWeights());
128 nodesViewer.setComparer(new NodeViewerComparer());
129 nodesViewer.addSelectionChangedListener(new ISelectionChangedListener() {
130 public void selectionChanged(SelectionChangedEvent event) {
131 IStructuredSelection selection = (IStructuredSelection) event.getSelection();
132 selectionService.setSelection(selection.toList());
133 }
134 });
135 nodesViewer.addDoubleClickListener(new JcrE4DClickListener(nodesViewer, partService));
136 menuService.registerContextMenu(nodesViewer.getControl(), NODE_VIEWER_POPUP_MENU_ID);
137 // getSite().registerContextMenu(menuManager, nodesViewer);
138 // getSite().setSelectionProvider(nodesViewer);
139 }
140
141 @PreDestroy
142 public void dispose() {
143 JcrUtils.logoutQuietly(userSession);
144 repositoryRegister.destroy();
145 }
146
147 public void refresh(Object obj) {
148 // Enable full refresh from a command when no element of the tree is
149 // selected
150 if (obj == null) {
151 Object[] elements = nodeContentProvider.getElements(null);
152 for (Object el : elements) {
153 if (el instanceof TreeParent)
154 JcrBrowserUtils.forceRefreshIfNeeded((TreeParent) el);
155 getNodeViewer().refresh(el);
156 }
157 } else
158 getNodeViewer().refresh(obj);
159 }
160
161 /**
162 * To be overridden to adapt size of form and result frames.
163 */
164 protected int[] getWeights() {
165 return new int[] { 70, 30 };
166 }
167
168 protected TreeViewer createNodeViewer(Composite parent, final ITreeContentProvider nodeContentProvider) {
169
170 final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
171
172 tmpNodeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
173
174 tmpNodeViewer.setContentProvider(nodeContentProvider);
175 tmpNodeViewer.setLabelProvider((IBaseLabelProvider) new NodeLabelProvider());
176 tmpNodeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
177 public void selectionChanged(SelectionChangedEvent event) {
178 if (!event.getSelection().isEmpty()) {
179 IStructuredSelection sel = (IStructuredSelection) event.getSelection();
180 Object firstItem = sel.getFirstElement();
181 if (firstItem instanceof SingleJcrNodeElem)
182 propertiesViewer.setInput(((SingleJcrNodeElem) firstItem).getNode());
183 } else {
184 propertiesViewer.setInput("");
185 }
186 }
187 });
188
189 resultsObserver = new TreeObserver(tmpNodeViewer.getTree().getDisplay());
190 if (keyring != null)
191 try {
192 ObservationManager observationManager = userSession.getWorkspace().getObservationManager();
193 observationManager.addEventListener(resultsObserver, Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, "/",
194 true, null, null, false);
195 } catch (RepositoryException e) {
196 throw new EclipseUiException("Cannot register listeners", e);
197 }
198
199 // tmpNodeViewer.addDoubleClickListener(new JcrDClickListener(tmpNodeViewer));
200 return tmpNodeViewer;
201 }
202
203 protected TableViewer createPropertiesViewer(Composite parent) {
204 propertiesViewer = new TableViewer(parent, SWT.NONE);
205 propertiesViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
206 propertiesViewer.getTable().setHeaderVisible(true);
207 propertiesViewer.setContentProvider(new PropertiesContentProvider());
208 TableViewerColumn col = new TableViewerColumn(propertiesViewer, SWT.NONE);
209 col.getColumn().setText("Name");
210 col.getColumn().setWidth(200);
211 col.setLabelProvider(new ColumnLabelProvider() {
212 private static final long serialVersionUID = -6684361063107478595L;
213
214 public String getText(Object element) {
215 try {
216 return ((Property) element).getName();
217 } catch (RepositoryException e) {
218 throw new EclipseUiException("Unexpected exception in label provider", e);
219 }
220 }
221 });
222 col = new TableViewerColumn(propertiesViewer, SWT.NONE);
223 col.getColumn().setText("Value");
224 col.getColumn().setWidth(400);
225 col.setLabelProvider(new ColumnLabelProvider() {
226 private static final long serialVersionUID = -8201994187693336657L;
227
228 public String getText(Object element) {
229 try {
230 Property property = (Property) element;
231 if (property.getType() == PropertyType.BINARY)
232 return "<binary>";
233 else if (property.isMultiple()) {
234 StringBuffer buf = new StringBuffer("[");
235 Value[] values = property.getValues();
236 for (int i = 0; i < values.length; i++) {
237 if (i != 0)
238 buf.append(", ");
239 buf.append(values[i].getString());
240 }
241 buf.append(']');
242 return buf.toString();
243 } else
244 return property.getValue().getString();
245 } catch (RepositoryException e) {
246 throw new EclipseUiException("Unexpected exception in label provider", e);
247 }
248 }
249 });
250 col = new TableViewerColumn(propertiesViewer, SWT.NONE);
251 col.getColumn().setText("Type");
252 col.getColumn().setWidth(200);
253 col.setLabelProvider(new ColumnLabelProvider() {
254 private static final long serialVersionUID = -6009599998150286070L;
255
256 public String getText(Object element) {
257 return JcrBrowserUtils.getPropertyTypeAsString((Property) element);
258 }
259 });
260 propertiesViewer.setInput("");
261 return propertiesViewer;
262 }
263
264 protected TreeViewer getNodeViewer() {
265 return nodesViewer;
266 }
267
268 /**
269 * Resets the tree content provider
270 *
271 * @param sortChildNodes if true the content provider will use a comparer to
272 * sort nodes that might slow down the display
273 */
274 public void setSortChildNodes(boolean sortChildNodes) {
275 this.sortChildNodes = sortChildNodes;
276 ((NodeContentProvider) nodesViewer.getContentProvider()).setSortChildren(sortChildNodes);
277 nodesViewer.setInput("");
278 }
279
280 /** Notifies the current view that a node has been added */
281 public void nodeAdded(TreeParent parentNode) {
282 // insure that Ui objects have been correctly created:
283 JcrBrowserUtils.forceRefreshIfNeeded(parentNode);
284 getNodeViewer().refresh(parentNode);
285 getNodeViewer().expandToLevel(parentNode, 1);
286 }
287
288 /** Notifies the current view that a node has been removed */
289 public void nodeRemoved(TreeParent parentNode) {
290 IStructuredSelection newSel = new StructuredSelection(parentNode);
291 getNodeViewer().setSelection(newSel, true);
292 // Force refresh
293 IStructuredSelection tmpSel = (IStructuredSelection) getNodeViewer().getSelection();
294 getNodeViewer().refresh(tmpSel.getFirstElement());
295 }
296
297 class TreeObserver extends AsyncUiEventListener {
298
299 public TreeObserver(Display display) {
300 super(display);
301 }
302
303 @Override
304 protected Boolean willProcessInUiThread(List<Event> events) throws RepositoryException {
305 for (Event event : events) {
306 if (getLog().isTraceEnabled())
307 getLog().debug("Received event " + event);
308 String path = event.getPath();
309 int index = path.lastIndexOf('/');
310 String propertyName = path.substring(index + 1);
311 if (getLog().isTraceEnabled())
312 getLog().debug("Concerned property " + propertyName);
313 }
314 return false;
315 }
316
317 protected void onEventInUiThread(List<Event> events) throws RepositoryException {
318 if (getLog().isTraceEnabled())
319 getLog().trace("Refresh result list");
320 nodesViewer.refresh();
321 }
322
323 }
324
325 public boolean getSortChildNodes() {
326 return sortChildNodes;
327 }
328
329 public void setFocus() {
330 getNodeViewer().getTree().setFocus();
331 }
332
333 /* DEPENDENCY INJECTION */
334 // public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
335 // this.repositoryRegister = repositoryRegister;
336 // }
337
338 public void setKeyring(CryptoKeyring keyring) {
339 this.keyring = keyring;
340 }
341
342 public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
343 this.repositoryFactory = repositoryFactory;
344 }
345
346 public void setNodeRepository(Repository nodeRepository) {
347 this.nodeRepository = nodeRepository;
348 }
349 }