1 package org
.argeo
.suite
.e4
.parts
;
3 import static org
.argeo
.eclipse
.ui
.EclipseUiUtils
.notEmpty
;
5 import javax
.annotation
.PostConstruct
;
6 import javax
.annotation
.PreDestroy
;
7 import javax
.inject
.Inject
;
8 import javax
.jcr
.NodeIterator
;
9 import javax
.jcr
.Repository
;
10 import javax
.jcr
.RepositoryException
;
11 import javax
.jcr
.Session
;
12 import javax
.jcr
.observation
.Event
;
13 import javax
.jcr
.observation
.EventIterator
;
14 import javax
.jcr
.observation
.EventListener
;
15 import javax
.jcr
.query
.Query
;
16 import javax
.jcr
.query
.QueryResult
;
18 import org
.apache
.commons
.logging
.Log
;
19 import org
.apache
.commons
.logging
.LogFactory
;
20 import org
.argeo
.activities
.ActivitiesService
;
21 import org
.argeo
.cms
.util
.CmsUtils
;
22 import org
.argeo
.connect
.ConnectException
;
23 import org
.argeo
.connect
.ConnectTypes
;
24 import org
.argeo
.connect
.resources
.ResourcesService
;
25 import org
.argeo
.connect
.ui
.ConnectUiConstants
;
26 import org
.argeo
.connect
.ui
.Refreshable
;
27 import org
.argeo
.connect
.ui
.SystemWorkbenchService
;
28 import org
.argeo
.connect
.ui
.util
.BasicNodeListContentProvider
;
29 import org
.argeo
.connect
.ui
.util
.JcrViewerDClickListener
;
30 import org
.argeo
.connect
.ui
.widgets
.DelayedText
;
31 import org
.argeo
.connect
.util
.ConnectJcrUtils
;
32 import org
.argeo
.connect
.util
.XPathUtils
;
33 import org
.argeo
.eclipse
.ui
.EclipseUiUtils
;
34 import org
.argeo
.jcr
.JcrUtils
;
35 import org
.argeo
.people
.PeopleService
;
36 import org
.eclipse
.e4
.ui
.di
.Focus
;
37 import org
.eclipse
.jface
.layout
.TableColumnLayout
;
38 import org
.eclipse
.jface
.viewers
.ColumnWeightData
;
39 import org
.eclipse
.jface
.viewers
.ILabelProvider
;
40 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
41 import org
.eclipse
.jface
.viewers
.TableViewer
;
42 import org
.eclipse
.swt
.SWT
;
43 import org
.eclipse
.swt
.events
.KeyEvent
;
44 import org
.eclipse
.swt
.events
.KeyListener
;
45 import org
.eclipse
.swt
.events
.ModifyEvent
;
46 import org
.eclipse
.swt
.events
.ModifyListener
;
47 import org
.eclipse
.swt
.layout
.GridData
;
48 import org
.eclipse
.swt
.layout
.GridLayout
;
49 import org
.eclipse
.swt
.widgets
.Composite
;
50 import org
.eclipse
.swt
.widgets
.Table
;
51 import org
.eclipse
.swt
.widgets
.TableColumn
;
52 import org
.eclipse
.swt
.widgets
.Text
;
54 /** A table with a quick search field. */
55 public class QuickSearchView
implements Refreshable
{
56 private final static Log log
= LogFactory
.getLog(QuickSearchView
.class);
57 // public static final String ID = AsUiPlugin.PLUGIN_ID + ".quickSearchView";
59 /* DEPENDENCY INJECTION */
61 private Repository repository
;
63 private ResourcesService resourcesService
;
65 private ActivitiesService activitiesService
;
67 private PeopleService peopleService
;
69 private SystemWorkbenchService systemWorkbenchService
;
72 private TableViewer entityViewer
;
73 private Text filterTxt
;
75 private Session session
;
78 // public void init(IViewSite site) throws PartInitException {
83 public void createPartControl(Composite parent
) {
84 session
= ConnectJcrUtils
.login(repository
);
86 parent
.setLayout(new GridLayout());
87 addFilterPanel(parent
);
88 entityViewer
= createListPart(parent
, new EntitySingleColumnLabelProvider(resourcesService
, activitiesService
,
89 peopleService
, systemWorkbenchService
));
90 refreshFilteredList();
93 session
.getWorkspace().getObservationManager().addEventListener(new EventListener() {
96 public void onEvent(EventIterator events
) {
97 parent
.getDisplay().asyncExec(() -> refreshFilteredList());
99 }, Event
.PROPERTY_CHANGED
| Event
.NODE_ADDED
| Event
.NODE_REMOVED
| Event
.PROPERTY_ADDED
, "/", true, null,
100 new String
[] { ConnectTypes
.CONNECT_ENTITY
}, true);
101 } catch (RepositoryException e
) {
102 throw new ConnectException("Cannot add JCR observer", e
);
107 private void addFilterPanel(Composite parent
) {
108 // Use a delayed text: the query won't be done until the user stop
110 int style
= SWT
.BORDER
| SWT
.SEARCH
| SWT
.ICON_CANCEL
;
111 DelayedText delayedText
= new DelayedText(parent
, style
, ConnectUiConstants
.SEARCH_TEXT_DELAY
);
112 filterTxt
= delayedText
.getText();
113 filterTxt
.setLayoutData(EclipseUiUtils
.fillWidth());
115 // final ServerPushSession pushSession = new ServerPushSession();
116 delayedText
.addDelayedModifyListener(null, new ModifyListener() {
117 private static final long serialVersionUID
= 5003010530960334977L;
119 public void modifyText(ModifyEvent event
) {
120 delayedText
.getText().getDisplay().asyncExec(new Runnable() {
123 refreshFilteredList();
126 // pushSession.stop();
130 // Jump to the first item of the list using the down arrow
131 filterTxt
.addKeyListener(new KeyListener() {
132 private static final long serialVersionUID
= -4523394262771183968L;
135 public void keyReleased(KeyEvent e
) {
139 public void keyPressed(KeyEvent e
) {
140 // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0;
141 // boolean altPressed = (e.stateMask & SWT.ALT) != 0;
142 if (e
.keyCode
== SWT
.ARROW_DOWN
|| e
.keyCode
== SWT
.TAB
) {
143 Object first
= entityViewer
.getElementAt(0);
145 entityViewer
.getTable().setFocus();
146 entityViewer
.setSelection(new StructuredSelection(first
), true);
154 protected TableViewer
createListPart(Composite parent
, ILabelProvider labelProvider
) {
155 parent
.setLayout(new GridLayout());
157 Composite tableComposite
= new Composite(parent
, SWT
.NONE
);
158 GridData gd
= new GridData(GridData
.HORIZONTAL_ALIGN_FILL
| GridData
.GRAB_VERTICAL
159 | GridData
.VERTICAL_ALIGN_FILL
| GridData
.GRAB_HORIZONTAL
);
160 tableComposite
.setLayoutData(gd
);
162 TableViewer v
= new TableViewer(tableComposite
);
163 v
.setLabelProvider(labelProvider
);
165 TableColumn singleColumn
= new TableColumn(v
.getTable(), SWT
.V_SCROLL
);
166 TableColumnLayout tableColumnLayout
= new TableColumnLayout();
167 tableColumnLayout
.setColumnData(singleColumn
, new ColumnWeightData(85));
168 tableComposite
.setLayout(tableColumnLayout
);
170 // Corresponding table & style
171 Table table
= v
.getTable();
172 table
.setLinesVisible(true);
173 table
.setHeaderVisible(false);
174 CmsUtils
.markup(table
);
175 CmsUtils
.setItemHeight(table
, 26);
177 v
.setContentProvider(new BasicNodeListContentProvider());
178 v
.addDoubleClickListener(new JcrViewerDClickListener(systemWorkbenchService
));
183 public void dispose() {
184 JcrUtils
.logoutQuietly(session
);
188 public void setFocus() {
189 refreshFilteredList();
190 filterTxt
.setFocus();
194 public void forceRefresh(Object object
) {
195 refreshFilteredList();
198 protected void refreshFilteredList() {
200 String filter
= filterTxt
.getText();
201 // Prevents the query on the full repository
202 // if (isEmpty(filter)) {
203 // entityViewer.setInput(null);
208 String xpathQueryStr
= "//element(*, " + ConnectTypes
.CONNECT_ENTITY
+ ")";
209 String xpathFilter
= XPathUtils
.getFreeTextConstraint(filter
);
210 if (notEmpty(xpathFilter
))
211 xpathQueryStr
+= "[" + xpathFilter
+ "]";
213 // boolean doOrder = orderResultsBtn != null
214 // && !(orderResultsBtn.isDisposed())
215 // && orderResultsBtn.getSelection();
217 // xpathQueryStr += " order by jcr:title";
220 long begin
= System
.currentTimeMillis();
221 Query xpathQuery
= XPathUtils
.createQuery(session
, xpathQueryStr
);
223 xpathQuery
.setLimit(ConnectUiConstants
.SEARCH_DEFAULT_LIMIT
);
224 QueryResult result
= xpathQuery
.execute();
226 NodeIterator nit
= result
.getNodes();
227 entityViewer
.setInput(JcrUtils
.nodeIteratorToList(nit
));
228 if (log
.isDebugEnabled()) {
229 long end
= System
.currentTimeMillis();
230 log
.debug("Quick Search - Found: " + nit
.getSize() + " in " + (end
- begin
)
231 + " ms by executing XPath query (" + xpathQueryStr
+ ").");
233 } catch (RepositoryException e
) {
234 throw new ConnectException("Unable to list entities", e
);
238 // public void setRepository(Repository repository) {
239 // this.repository = repository;
242 // public void setResourcesService(ResourcesService resourcesService) {
243 // this.resourcesService = resourcesService;
246 // public void setActivitiesService(ActivitiesService activitiesService) {
247 // this.activitiesService = activitiesService;
250 // public void setPeopleService(PeopleService peopleService) {
251 // this.peopleService = peopleService;
254 // public void setSystemWorkbenchService(SystemWorkbenchService systemWorkbenchService) {
255 // this.systemWorkbenchService = systemWorkbenchService;