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
.jface
.layout
.TableColumnLayout
;
37 import org
.eclipse
.jface
.viewers
.ColumnWeightData
;
38 import org
.eclipse
.jface
.viewers
.ILabelProvider
;
39 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
40 import org
.eclipse
.jface
.viewers
.TableViewer
;
41 import org
.eclipse
.swt
.SWT
;
42 import org
.eclipse
.swt
.events
.KeyEvent
;
43 import org
.eclipse
.swt
.events
.KeyListener
;
44 import org
.eclipse
.swt
.events
.ModifyEvent
;
45 import org
.eclipse
.swt
.events
.ModifyListener
;
46 import org
.eclipse
.swt
.layout
.GridData
;
47 import org
.eclipse
.swt
.layout
.GridLayout
;
48 import org
.eclipse
.swt
.widgets
.Composite
;
49 import org
.eclipse
.swt
.widgets
.Table
;
50 import org
.eclipse
.swt
.widgets
.TableColumn
;
51 import org
.eclipse
.swt
.widgets
.Text
;
53 /** A table with a quick search field. */
54 public class QuickSearchView
implements Refreshable
{
55 private final static Log log
= LogFactory
.getLog(QuickSearchView
.class);
56 // public static final String ID = AsUiPlugin.PLUGIN_ID + ".quickSearchView";
58 /* DEPENDENCY INJECTION */
60 private Repository repository
;
62 private ResourcesService resourcesService
;
64 private ActivitiesService activitiesService
;
66 private PeopleService peopleService
;
68 private SystemWorkbenchService systemWorkbenchService
;
71 private TableViewer entityViewer
;
72 private Text filterTxt
;
74 private Session session
;
77 // public void init(IViewSite site) throws PartInitException {
82 public void createPartControl(Composite parent
) {
83 session
= ConnectJcrUtils
.login(repository
);
85 parent
.setLayout(new GridLayout());
86 addFilterPanel(parent
);
87 entityViewer
= createListPart(parent
, new EntitySingleColumnLabelProvider(resourcesService
, activitiesService
,
88 peopleService
, systemWorkbenchService
));
89 refreshFilteredList();
92 session
.getWorkspace().getObservationManager().addEventListener(new EventListener() {
95 public void onEvent(EventIterator events
) {
96 parent
.getDisplay().asyncExec(() -> refreshFilteredList());
98 }, Event
.PROPERTY_CHANGED
| Event
.NODE_ADDED
| Event
.NODE_REMOVED
| Event
.PROPERTY_ADDED
, "/", true, null,
99 new String
[] { ConnectTypes
.CONNECT_ENTITY
}, true);
100 } catch (RepositoryException e
) {
101 throw new ConnectException("Cannot add JCR observer", e
);
106 private void addFilterPanel(Composite parent
) {
107 // Use a delayed text: the query won't be done until the user stop
109 int style
= SWT
.BORDER
| SWT
.SEARCH
| SWT
.ICON_CANCEL
;
110 DelayedText delayedText
= new DelayedText(parent
, style
, ConnectUiConstants
.SEARCH_TEXT_DELAY
);
111 filterTxt
= delayedText
.getText();
112 filterTxt
.setLayoutData(EclipseUiUtils
.fillWidth());
114 // final ServerPushSession pushSession = new ServerPushSession();
115 delayedText
.addDelayedModifyListener(null, new ModifyListener() {
116 private static final long serialVersionUID
= 5003010530960334977L;
118 public void modifyText(ModifyEvent event
) {
119 delayedText
.getText().getDisplay().asyncExec(new Runnable() {
122 refreshFilteredList();
125 // pushSession.stop();
129 // Jump to the first item of the list using the down arrow
130 filterTxt
.addKeyListener(new KeyListener() {
131 private static final long serialVersionUID
= -4523394262771183968L;
134 public void keyReleased(KeyEvent e
) {
138 public void keyPressed(KeyEvent e
) {
139 // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0;
140 // boolean altPressed = (e.stateMask & SWT.ALT) != 0;
141 if (e
.keyCode
== SWT
.ARROW_DOWN
|| e
.keyCode
== SWT
.TAB
) {
142 Object first
= entityViewer
.getElementAt(0);
144 entityViewer
.getTable().setFocus();
145 entityViewer
.setSelection(new StructuredSelection(first
), true);
153 protected TableViewer
createListPart(Composite parent
, ILabelProvider labelProvider
) {
154 parent
.setLayout(new GridLayout());
156 Composite tableComposite
= new Composite(parent
, SWT
.NONE
);
157 GridData gd
= new GridData(GridData
.HORIZONTAL_ALIGN_FILL
| GridData
.GRAB_VERTICAL
158 | GridData
.VERTICAL_ALIGN_FILL
| GridData
.GRAB_HORIZONTAL
);
159 tableComposite
.setLayoutData(gd
);
161 TableViewer v
= new TableViewer(tableComposite
);
162 v
.setLabelProvider(labelProvider
);
164 TableColumn singleColumn
= new TableColumn(v
.getTable(), SWT
.V_SCROLL
);
165 TableColumnLayout tableColumnLayout
= new TableColumnLayout();
166 tableColumnLayout
.setColumnData(singleColumn
, new ColumnWeightData(85));
167 tableComposite
.setLayout(tableColumnLayout
);
169 // Corresponding table & style
170 Table table
= v
.getTable();
171 table
.setLinesVisible(true);
172 table
.setHeaderVisible(false);
173 CmsUtils
.markup(table
);
174 CmsUtils
.setItemHeight(table
, 26);
176 v
.setContentProvider(new BasicNodeListContentProvider());
177 v
.addDoubleClickListener(new JcrViewerDClickListener(systemWorkbenchService
));
182 public void dispose() {
183 JcrUtils
.logoutQuietly(session
);
187 public void setFocus() {
188 refreshFilteredList();
189 filterTxt
.setFocus();
193 public void forceRefresh(Object object
) {
194 refreshFilteredList();
197 protected void refreshFilteredList() {
199 String filter
= filterTxt
.getText();
200 // Prevents the query on the full repository
201 // if (isEmpty(filter)) {
202 // entityViewer.setInput(null);
207 String xpathQueryStr
= "//element(*, " + ConnectTypes
.CONNECT_ENTITY
+ ")";
208 String xpathFilter
= XPathUtils
.getFreeTextConstraint(filter
);
209 if (notEmpty(xpathFilter
))
210 xpathQueryStr
+= "[" + xpathFilter
+ "]";
212 // boolean doOrder = orderResultsBtn != null
213 // && !(orderResultsBtn.isDisposed())
214 // && orderResultsBtn.getSelection();
216 // xpathQueryStr += " order by jcr:title";
219 long begin
= System
.currentTimeMillis();
220 Query xpathQuery
= XPathUtils
.createQuery(session
, xpathQueryStr
);
222 xpathQuery
.setLimit(ConnectUiConstants
.SEARCH_DEFAULT_LIMIT
);
223 QueryResult result
= xpathQuery
.execute();
225 NodeIterator nit
= result
.getNodes();
226 entityViewer
.setInput(JcrUtils
.nodeIteratorToList(nit
));
227 if (log
.isDebugEnabled()) {
228 long end
= System
.currentTimeMillis();
229 log
.debug("Quick Search - Found: " + nit
.getSize() + " in " + (end
- begin
)
230 + " ms by executing XPath query (" + xpathQueryStr
+ ").");
232 } catch (RepositoryException e
) {
233 throw new ConnectException("Unable to list entities", e
);
237 // public void setRepository(Repository repository) {
238 // this.repository = repository;
241 // public void setResourcesService(ResourcesService resourcesService) {
242 // this.resourcesService = resourcesService;
245 // public void setActivitiesService(ActivitiesService activitiesService) {
246 // this.activitiesService = activitiesService;
249 // public void setPeopleService(PeopleService peopleService) {
250 // this.peopleService = peopleService;
253 // public void setSystemWorkbenchService(SystemWorkbenchService systemWorkbenchService) {
254 // this.systemWorkbenchService = systemWorkbenchService;