1 package org
.argeo
.cms
.ui
.workbench
.jcr
;
5 import javax
.jcr
.Property
;
6 import javax
.jcr
.PropertyType
;
7 import javax
.jcr
.Repository
;
8 import javax
.jcr
.RepositoryException
;
9 import javax
.jcr
.RepositoryFactory
;
10 import javax
.jcr
.Session
;
11 import javax
.jcr
.Value
;
12 import javax
.jcr
.observation
.Event
;
13 import javax
.jcr
.observation
.EventListener
;
14 import javax
.jcr
.observation
.ObservationManager
;
16 import org
.argeo
.api
.NodeConstants
;
17 import org
.argeo
.api
.security
.Keyring
;
18 import org
.argeo
.cms
.ui
.jcr
.DefaultRepositoryRegister
;
19 import org
.argeo
.cms
.ui
.jcr
.JcrBrowserUtils
;
20 import org
.argeo
.cms
.ui
.jcr
.JcrDClickListener
;
21 import org
.argeo
.cms
.ui
.jcr
.NodeContentProvider
;
22 import org
.argeo
.cms
.ui
.jcr
.NodeLabelProvider
;
23 import org
.argeo
.cms
.ui
.jcr
.PropertiesContentProvider
;
24 import org
.argeo
.cms
.ui
.jcr
.RepositoryRegister
;
25 import org
.argeo
.cms
.ui
.jcr
.model
.SingleJcrNodeElem
;
26 import org
.argeo
.cms
.ui
.workbench
.WorkbenchUiPlugin
;
27 import org
.argeo
.eclipse
.ui
.EclipseUiException
;
28 import org
.argeo
.eclipse
.ui
.TreeParent
;
29 import org
.argeo
.eclipse
.ui
.jcr
.AsyncUiEventListener
;
30 import org
.argeo
.eclipse
.ui
.jcr
.util
.NodeViewerComparer
;
31 import org
.eclipse
.jface
.action
.MenuManager
;
32 import org
.eclipse
.jface
.viewers
.ColumnLabelProvider
;
33 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
34 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
35 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
36 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
37 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
38 import org
.eclipse
.jface
.viewers
.TableViewer
;
39 import org
.eclipse
.jface
.viewers
.TableViewerColumn
;
40 import org
.eclipse
.jface
.viewers
.TreeViewer
;
41 import org
.eclipse
.swt
.SWT
;
42 import org
.eclipse
.swt
.custom
.SashForm
;
43 import org
.eclipse
.swt
.layout
.FillLayout
;
44 import org
.eclipse
.swt
.layout
.GridData
;
45 import org
.eclipse
.swt
.layout
.GridLayout
;
46 import org
.eclipse
.swt
.widgets
.Composite
;
47 import org
.eclipse
.swt
.widgets
.Display
;
48 import org
.eclipse
.swt
.widgets
.Menu
;
49 import org
.eclipse
.ui
.part
.ViewPart
;
52 * Basic View to display a sash form to browse a JCR compliant multiple
53 * repository environment
55 public class JcrBrowserView
extends ViewPart
{
56 public final static String ID
= WorkbenchUiPlugin
.PLUGIN_ID
+ ".jcrBrowserView";
57 private boolean sortChildNodes
= true;
59 /* DEPENDENCY INJECTION */
60 private Keyring keyring
;
61 private RepositoryRegister repositoryRegister
= new DefaultRepositoryRegister();
62 private RepositoryFactory repositoryFactory
;
63 private Repository nodeRepository
;
65 // Current user session on the "Argeo node" default workspace
66 private Session userSession
;
69 private TreeViewer nodesViewer
;
70 private NodeContentProvider nodeContentProvider
;
71 private TableViewer propertiesViewer
;
72 private EventListener resultsObserver
;
75 public void createPartControl(Composite parent
) {
76 parent
.setLayout(new FillLayout());
77 SashForm sashForm
= new SashForm(parent
, SWT
.VERTICAL
);
78 sashForm
.setSashWidth(4);
79 sashForm
.setLayout(new FillLayout());
81 // Create the tree on top of the view
82 Composite top
= new Composite(sashForm
, SWT
.NONE
);
83 GridLayout gl
= new GridLayout(1, false);
87 this.userSession
= this.nodeRepository
.login(NodeConstants
.HOME_WORKSPACE
);
88 } catch (RepositoryException e
) {
89 throw new EclipseUiException("Cannot open user session", e
);
92 nodeContentProvider
= new NodeContentProvider(userSession
, keyring
, repositoryRegister
, repositoryFactory
,
96 nodesViewer
= createNodeViewer(top
, nodeContentProvider
);
98 // context menu : it is completely defined in the plugin.xml file.
99 MenuManager menuManager
= new MenuManager();
100 Menu menu
= menuManager
.createContextMenu(nodesViewer
.getTree());
102 nodesViewer
.getTree().setMenu(menu
);
103 getSite().registerContextMenu(menuManager
, nodesViewer
);
104 getSite().setSelectionProvider(nodesViewer
);
106 nodesViewer
.setInput(getViewSite());
108 // Create the property viewer on the bottom
109 Composite bottom
= new Composite(sashForm
, SWT
.NONE
);
110 bottom
.setLayout(new GridLayout(1, false));
111 propertiesViewer
= createPropertiesViewer(bottom
);
113 sashForm
.setWeights(getWeights());
114 nodesViewer
.setComparer(new NodeViewerComparer());
117 public void refresh(Object obj
) {
118 // Enable full refresh from a command when no element of the tree is
121 Object
[] elements
= nodeContentProvider
.getElements(null);
122 for (Object el
: elements
) {
123 if (el
instanceof TreeParent
)
124 JcrBrowserUtils
.forceRefreshIfNeeded((TreeParent
) el
);
125 getNodeViewer().refresh(el
);
128 getNodeViewer().refresh(obj
);
132 * To be overridden to adapt size of form and result frames.
134 protected int[] getWeights() {
135 return new int[] { 70, 30 };
138 protected TreeViewer
createNodeViewer(Composite parent
, final ITreeContentProvider nodeContentProvider
) {
140 final TreeViewer tmpNodeViewer
= new TreeViewer(parent
, SWT
.MULTI
);
142 tmpNodeViewer
.getTree().setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
144 tmpNodeViewer
.setContentProvider(nodeContentProvider
);
145 tmpNodeViewer
.setLabelProvider(new NodeLabelProvider());
146 tmpNodeViewer
.addSelectionChangedListener(new ISelectionChangedListener() {
147 public void selectionChanged(SelectionChangedEvent event
) {
148 if (!event
.getSelection().isEmpty()) {
149 IStructuredSelection sel
= (IStructuredSelection
) event
.getSelection();
150 Object firstItem
= sel
.getFirstElement();
151 if (firstItem
instanceof SingleJcrNodeElem
)
152 propertiesViewer
.setInput(((SingleJcrNodeElem
) firstItem
).getNode());
154 propertiesViewer
.setInput(getViewSite());
159 resultsObserver
= new TreeObserver(tmpNodeViewer
.getTree().getDisplay());
162 ObservationManager observationManager
= userSession
.getWorkspace().getObservationManager();
163 observationManager
.addEventListener(resultsObserver
, Event
.PROPERTY_ADDED
| Event
.PROPERTY_CHANGED
, "/",
164 true, null, null, false);
165 } catch (RepositoryException e
) {
166 throw new EclipseUiException("Cannot register listeners", e
);
169 tmpNodeViewer
.addDoubleClickListener(new JcrDClickListener(tmpNodeViewer
));
170 return tmpNodeViewer
;
173 protected TableViewer
createPropertiesViewer(Composite parent
) {
174 propertiesViewer
= new TableViewer(parent
);
175 propertiesViewer
.getTable().setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
176 propertiesViewer
.getTable().setHeaderVisible(true);
177 propertiesViewer
.setContentProvider(new PropertiesContentProvider());
178 TableViewerColumn col
= new TableViewerColumn(propertiesViewer
, SWT
.NONE
);
179 col
.getColumn().setText("Name");
180 col
.getColumn().setWidth(200);
181 col
.setLabelProvider(new ColumnLabelProvider() {
182 private static final long serialVersionUID
= -6684361063107478595L;
184 public String
getText(Object element
) {
186 return ((Property
) element
).getName();
187 } catch (RepositoryException e
) {
188 throw new EclipseUiException("Unexpected exception in label provider", e
);
192 col
= new TableViewerColumn(propertiesViewer
, SWT
.NONE
);
193 col
.getColumn().setText("Value");
194 col
.getColumn().setWidth(400);
195 col
.setLabelProvider(new ColumnLabelProvider() {
196 private static final long serialVersionUID
= -8201994187693336657L;
198 public String
getText(Object element
) {
200 Property property
= (Property
) element
;
201 if (property
.getType() == PropertyType
.BINARY
)
203 else if (property
.isMultiple()) {
204 StringBuffer buf
= new StringBuffer("[");
205 Value
[] values
= property
.getValues();
206 for (int i
= 0; i
< values
.length
; i
++) {
209 buf
.append(values
[i
].getString());
212 return buf
.toString();
214 return property
.getValue().getString();
215 } catch (RepositoryException e
) {
216 throw new EclipseUiException("Unexpected exception in label provider", e
);
220 col
= new TableViewerColumn(propertiesViewer
, SWT
.NONE
);
221 col
.getColumn().setText("Type");
222 col
.getColumn().setWidth(200);
223 col
.setLabelProvider(new ColumnLabelProvider() {
224 private static final long serialVersionUID
= -6009599998150286070L;
226 public String
getText(Object element
) {
227 return JcrBrowserUtils
.getPropertyTypeAsString((Property
) element
);
230 propertiesViewer
.setInput(getViewSite());
231 return propertiesViewer
;
235 public void dispose() {
239 protected TreeViewer
getNodeViewer() {
244 * Resets the tree content provider
246 * @param sortChildNodes
247 * if true the content provider will use a comparer to sort nodes
248 * that might slow down the display
250 public void setSortChildNodes(boolean sortChildNodes
) {
251 this.sortChildNodes
= sortChildNodes
;
252 ((NodeContentProvider
) nodesViewer
.getContentProvider()).setSortChildren(sortChildNodes
);
253 nodesViewer
.setInput(getViewSite());
256 /** Notifies the current view that a node has been added */
257 public void nodeAdded(TreeParent parentNode
) {
258 // insure that Ui objects have been correctly created:
259 JcrBrowserUtils
.forceRefreshIfNeeded(parentNode
);
260 getNodeViewer().refresh(parentNode
);
261 getNodeViewer().expandToLevel(parentNode
, 1);
264 /** Notifies the current view that a node has been removed */
265 public void nodeRemoved(TreeParent parentNode
) {
266 IStructuredSelection newSel
= new StructuredSelection(parentNode
);
267 getNodeViewer().setSelection(newSel
, true);
269 IStructuredSelection tmpSel
= (IStructuredSelection
) getNodeViewer().getSelection();
270 getNodeViewer().refresh(tmpSel
.getFirstElement());
273 class TreeObserver
extends AsyncUiEventListener
{
275 public TreeObserver(Display display
) {
280 protected Boolean
willProcessInUiThread(List
<Event
> events
) throws RepositoryException
{
281 for (Event event
: events
) {
282 if (getLog().isTraceEnabled())
283 getLog().debug("Received event " + event
);
284 String path
= event
.getPath();
285 int index
= path
.lastIndexOf('/');
286 String propertyName
= path
.substring(index
+ 1);
287 if (getLog().isTraceEnabled())
288 getLog().debug("Concerned property " + propertyName
);
293 protected void onEventInUiThread(List
<Event
> events
) throws RepositoryException
{
294 if (getLog().isTraceEnabled())
295 getLog().trace("Refresh result list");
296 nodesViewer
.refresh();
301 public boolean getSortChildNodes() {
302 return sortChildNodes
;
306 public void setFocus() {
307 getNodeViewer().getTree().setFocus();
310 /* DEPENDENCY INJECTION */
311 public void setRepositoryRegister(RepositoryRegister repositoryRegister
) {
312 this.repositoryRegister
= repositoryRegister
;
315 public void setKeyring(Keyring keyring
) {
316 this.keyring
= keyring
;
319 public void setRepositoryFactory(RepositoryFactory repositoryFactory
) {
320 this.repositoryFactory
= repositoryFactory
;
323 public void setNodeRepository(Repository nodeRepository
) {
324 this.nodeRepository
= nodeRepository
;