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