]> 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
fix a few bugs
[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.Arrays;
4 import java.util.List;
5
6 import javax.jcr.Property;
7 import javax.jcr.PropertyType;
8 import javax.jcr.RepositoryException;
9 import javax.jcr.Session;
10 import javax.jcr.observation.Event;
11 import javax.jcr.observation.EventListener;
12 import javax.jcr.observation.ObservationManager;
13
14 import org.argeo.ArgeoException;
15 import org.argeo.eclipse.ui.TreeParent;
16 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
17 import org.argeo.eclipse.ui.jcr.utils.NodeViewerComparer;
18 import org.argeo.eclipse.ui.jcr.views.AbstractJcrBrowser;
19 import org.argeo.jcr.RepositoryRegister;
20 import org.argeo.jcr.security.JcrKeyring;
21 import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
22 import org.argeo.jcr.ui.explorer.browser.NodeContentProvider;
23 import org.argeo.jcr.ui.explorer.browser.NodeLabelProvider;
24 import org.argeo.jcr.ui.explorer.browser.PropertiesContentProvider;
25 import org.argeo.jcr.ui.explorer.model.SingleJcrNode;
26 import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
27 import org.argeo.jcr.ui.explorer.utils.JcrUiUtils;
28 import org.eclipse.jface.action.MenuManager;
29 import org.eclipse.jface.viewers.ColumnLabelProvider;
30 import org.eclipse.jface.viewers.ISelectionChangedListener;
31 import org.eclipse.jface.viewers.IStructuredSelection;
32 import org.eclipse.jface.viewers.ITreeContentProvider;
33 import org.eclipse.jface.viewers.SelectionChangedEvent;
34 import org.eclipse.jface.viewers.StructuredSelection;
35 import org.eclipse.jface.viewers.TableViewer;
36 import org.eclipse.jface.viewers.TableViewerColumn;
37 import org.eclipse.jface.viewers.TreeViewer;
38 import org.eclipse.swt.SWT;
39 import org.eclipse.swt.custom.SashForm;
40 import org.eclipse.swt.layout.FillLayout;
41 import org.eclipse.swt.layout.GridData;
42 import org.eclipse.swt.layout.GridLayout;
43 import org.eclipse.swt.widgets.Composite;
44 import org.eclipse.swt.widgets.Display;
45 import org.eclipse.swt.widgets.Menu;
46
47 /**
48 * Basic View to display a sash form to browse a JCR compliant multirepository
49 * environment
50 */
51
52 public class GenericJcrBrowser extends AbstractJcrBrowser {
53 // private final static Log log =
54 // LogFactory.getLog(GenericJcrBrowser.class);
55 public final static String ID = JcrExplorerPlugin.ID + ".browserView";
56 private boolean sortChildNodes = false;
57
58 /* DEPENDENCY INJECTION */
59 private JcrKeyring jcrKeyring;
60 private RepositoryRegister repositoryRegister;
61
62 // This page widgets
63 private TreeViewer nodesViewer;
64 private NodeContentProvider nodeContentProvider;
65 private TableViewer propertiesViewer;
66 private EventListener resultsObserver;
67
68 // Manage documents
69 // private JcrFileProvider jcrFileProvider;
70 // private FileHandler fileHandler;
71
72 @Override
73 public void createPartControl(Composite parent) {
74
75 // look for session
76 Session nodeSession = jcrKeyring != null ? jcrKeyring.getSession()
77 : null;
78 // if (nodeSession == null) {
79 // Repository nodeRepository = JcrUtils.getRepositoryByAlias(
80 // repositoryRegister, ArgeoJcrConstants.ALIAS_NODE);
81 // if (nodeRepository != null)
82 // try {
83 // nodeSession = nodeRepository.login();
84 // // TODO : enhance that to enable multirepository listener.
85 // session = nodeSession;
86 // } catch (RepositoryException e1) {
87 // throw new ArgeoException("Cannot login to node repository");
88 // }
89 // }
90
91 // Instantiate the generic object that fits for
92 // both RCP & RAP
93 // Note that in RAP, it registers a service handler that provide the
94 // access to the files.
95 // jcrFileProvider = new JcrFileProvider();
96 // fileHandler = new FileHandler(jcrFileProvider);
97
98 parent.setLayout(new FillLayout());
99 SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
100 sashForm.setSashWidth(4);
101 sashForm.setLayout(new FillLayout());
102
103 // Create the tree on top of the view
104 Composite top = new Composite(sashForm, SWT.NONE);
105 GridLayout gl = new GridLayout(1, false);
106 top.setLayout(gl);
107
108 nodeContentProvider = new NodeContentProvider(jcrKeyring,
109 repositoryRegister);
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 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 protected TreeViewer createNodeViewer(Composite parent,
193 final ITreeContentProvider nodeContentProvider) {
194
195 final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
196
197 tmpNodeViewer.getTree().setLayoutData(
198 new GridData(SWT.FILL, SWT.FILL, true, true));
199
200 tmpNodeViewer.setContentProvider(nodeContentProvider);
201 tmpNodeViewer.setLabelProvider(new NodeLabelProvider());
202 tmpNodeViewer
203 .addSelectionChangedListener(new ISelectionChangedListener() {
204 public void selectionChanged(SelectionChangedEvent event) {
205 if (!event.getSelection().isEmpty()) {
206 IStructuredSelection sel = (IStructuredSelection) event
207 .getSelection();
208 Object firstItem = sel.getFirstElement();
209 if (firstItem instanceof SingleJcrNode)
210 propertiesViewer
211 .setInput(((SingleJcrNode) firstItem)
212 .getNode());
213 } else {
214 propertiesViewer.setInput(getViewSite());
215 }
216 }
217 });
218
219 resultsObserver = new TreeObserver(tmpNodeViewer.getTree().getDisplay());
220 if (jcrKeyring != null)
221 try {
222 ObservationManager observationManager = jcrKeyring.getSession()
223 .getWorkspace().getObservationManager();
224 observationManager.addEventListener(resultsObserver,
225 Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, "/",
226 true, null, null, false);
227 } catch (RepositoryException e) {
228 throw new ArgeoException("Cannot register listeners", e);
229 }
230
231 tmpNodeViewer
232 .addDoubleClickListener(new GenericNodeDoubleClickListener(
233 tmpNodeViewer));
234 return tmpNodeViewer;
235 }
236
237 @Override
238 protected TreeViewer getNodeViewer() {
239 return nodesViewer;
240 }
241
242 /** Notifies the current view that a node has been added */
243 public void nodeAdded(TreeParent parentNode) {
244 // insure that Ui objects have been correctly created:
245 JcrUiUtils.forceRefreshIfNeeded(parentNode);
246 getNodeViewer().refresh(parentNode);
247 getNodeViewer().expandToLevel(parentNode, 1);
248 }
249
250 /** Notifies the current view that a node has been added */
251 public void nodeRemoved(TreeParent parentNode) {
252 IStructuredSelection newSel = new StructuredSelection(parentNode);
253 getNodeViewer().setSelection(newSel, true);
254 // Force refresh
255 IStructuredSelection tmpSel = (IStructuredSelection) getNodeViewer()
256 .getSelection();
257 getNodeViewer().refresh(tmpSel.getFirstElement());
258 }
259
260 class TreeObserver extends AsyncUiEventListener {
261
262 public TreeObserver(Display display) {
263 super(display);
264 }
265
266 @Override
267 protected Boolean willProcessInUiThread(List<Event> events)
268 throws RepositoryException {
269 for (Event event : events) {
270 if (getLog().isTraceEnabled())
271 getLog().debug("Received event " + event);
272 String path = event.getPath();
273 int index = path.lastIndexOf('/');
274 String propertyName = path.substring(index + 1);
275 if (getLog().isTraceEnabled())
276 getLog().debug("Concerned property " + propertyName);
277 }
278 return false;
279 }
280
281 protected void onEventInUiThread(List<Event> events)
282 throws RepositoryException {
283 if (getLog().isTraceEnabled())
284 getLog().trace("Refresh result list");
285 nodesViewer.refresh();
286 }
287
288 }
289
290 public void setSortChildNodes(boolean sortChildNodes) {
291 this.sortChildNodes = sortChildNodes;
292 }
293
294 public boolean getSortChildNodes() {
295 return sortChildNodes;
296 }
297
298 /* DEPENDENCY INJECTION */
299 public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
300 this.repositoryRegister = repositoryRegister;
301 }
302
303 public void setJcrKeyring(JcrKeyring jcrKeyring) {
304 this.jcrKeyring = jcrKeyring;
305 }
306
307 }