1 package org
.argeo
.suite
.e4
.parts
;
3 import static org
.argeo
.eclipse
.ui
.EclipseUiUtils
.notEmpty
;
7 import javax
.annotation
.PostConstruct
;
8 import javax
.annotation
.PreDestroy
;
9 import javax
.inject
.Inject
;
10 import javax
.jcr
.NodeIterator
;
11 import javax
.jcr
.Repository
;
12 import javax
.jcr
.RepositoryException
;
13 import javax
.jcr
.Session
;
14 import javax
.jcr
.observation
.Event
;
15 import javax
.jcr
.observation
.EventIterator
;
16 import javax
.jcr
.observation
.EventListener
;
17 import javax
.jcr
.query
.Query
;
18 import javax
.jcr
.query
.QueryResult
;
20 import org
.apache
.commons
.logging
.Log
;
21 import org
.apache
.commons
.logging
.LogFactory
;
22 import org
.argeo
.activities
.ActivitiesService
;
23 import org
.argeo
.cms
.util
.CmsUtils
;
24 import org
.argeo
.connect
.ConnectException
;
25 import org
.argeo
.connect
.ConnectTypes
;
26 import org
.argeo
.connect
.resources
.ResourcesService
;
27 import org
.argeo
.connect
.ui
.ConnectUiConstants
;
28 import org
.argeo
.connect
.ui
.Refreshable
;
29 import org
.argeo
.connect
.ui
.SystemWorkbenchService
;
30 import org
.argeo
.connect
.ui
.util
.BasicNodeListContentProvider
;
31 import org
.argeo
.connect
.ui
.util
.JcrViewerDClickListener
;
32 import org
.argeo
.connect
.ui
.widgets
.DelayedText
;
33 import org
.argeo
.connect
.util
.ConnectJcrUtils
;
34 import org
.argeo
.connect
.util
.XPathUtils
;
35 import org
.argeo
.eclipse
.ui
.EclipseUiUtils
;
36 import org
.argeo
.jcr
.JcrUtils
;
37 import org
.argeo
.people
.PeopleService
;
38 import org
.eclipse
.e4
.ui
.di
.Focus
;
39 import org
.eclipse
.e4
.ui
.workbench
.modeling
.ESelectionService
;
40 import org
.eclipse
.jface
.layout
.TableColumnLayout
;
41 import org
.eclipse
.jface
.viewers
.ColumnWeightData
;
42 import org
.eclipse
.jface
.viewers
.ILabelProvider
;
43 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
44 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
45 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
46 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
47 import org
.eclipse
.jface
.viewers
.TableViewer
;
48 import org
.eclipse
.swt
.SWT
;
49 import org
.eclipse
.swt
.events
.KeyEvent
;
50 import org
.eclipse
.swt
.events
.KeyListener
;
51 import org
.eclipse
.swt
.events
.ModifyEvent
;
52 import org
.eclipse
.swt
.events
.ModifyListener
;
53 import org
.eclipse
.swt
.layout
.GridData
;
54 import org
.eclipse
.swt
.layout
.GridLayout
;
55 import org
.eclipse
.swt
.widgets
.Composite
;
56 import org
.eclipse
.swt
.widgets
.Table
;
57 import org
.eclipse
.swt
.widgets
.TableColumn
;
58 import org
.eclipse
.swt
.widgets
.Text
;
60 /** A table with a quick search field. */
61 public class QuickSearchView
implements Refreshable
{
62 private final static Log log
= LogFactory
.getLog(QuickSearchView
.class);
63 // public static final String ID = AsUiPlugin.PLUGIN_ID + ".quickSearchView";
65 /* DEPENDENCY INJECTION */
67 private Repository repository
;
69 private ResourcesService resourcesService
;
71 private ActivitiesService activitiesService
;
73 private PeopleService peopleService
;
75 private SystemWorkbenchService systemWorkbenchService
;
78 private ESelectionService selectionService
;
81 private TableViewer entityViewer
;
82 private Text filterTxt
;
84 private Session session
;
87 // public void init(IViewSite site) throws PartInitException {
92 public void createPartControl(Composite parent
) {
93 session
= ConnectJcrUtils
.login(repository
);
95 parent
.setLayout(new GridLayout());
96 addFilterPanel(parent
);
97 entityViewer
= createListPart(parent
, new EntitySingleColumnLabelProvider(resourcesService
, activitiesService
,
98 peopleService
, systemWorkbenchService
));
99 refreshFilteredList();
102 // new String[] { ConnectTypes.CONNECT_ENTITY }
103 session
.getWorkspace().getObservationManager().addEventListener(new EventListener() {
106 public void onEvent(EventIterator events
) {
107 parent
.getDisplay().asyncExec(() -> refreshFilteredList());
109 }, Event
.PROPERTY_CHANGED
| Event
.NODE_ADDED
| Event
.NODE_REMOVED
| Event
.PROPERTY_ADDED
, "/", true, null,
111 } catch (RepositoryException e
) {
112 throw new ConnectException("Cannot add JCR observer", e
);
117 private void addFilterPanel(Composite parent
) {
118 // Use a delayed text: the query won't be done until the user stop
120 int style
= SWT
.BORDER
| SWT
.SEARCH
| SWT
.ICON_CANCEL
;
121 DelayedText delayedText
= new DelayedText(parent
, style
, ConnectUiConstants
.SEARCH_TEXT_DELAY
);
122 filterTxt
= delayedText
.getText();
123 filterTxt
.setLayoutData(EclipseUiUtils
.fillWidth());
125 // final ServerPushSession pushSession = new ServerPushSession();
126 delayedText
.addDelayedModifyListener(null, new ModifyListener() {
127 private static final long serialVersionUID
= 5003010530960334977L;
129 public void modifyText(ModifyEvent event
) {
130 delayedText
.getText().getDisplay().asyncExec(new Runnable() {
133 refreshFilteredList();
136 // pushSession.stop();
140 // Jump to the first item of the list using the down arrow
141 filterTxt
.addKeyListener(new KeyListener() {
142 private static final long serialVersionUID
= -4523394262771183968L;
145 public void keyReleased(KeyEvent e
) {
149 public void keyPressed(KeyEvent e
) {
150 // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0;
151 // boolean altPressed = (e.stateMask & SWT.ALT) != 0;
152 if (e
.keyCode
== SWT
.ARROW_DOWN
|| e
.keyCode
== SWT
.TAB
) {
153 Object first
= entityViewer
.getElementAt(0);
155 entityViewer
.getTable().setFocus();
156 entityViewer
.setSelection(new StructuredSelection(first
), true);
164 protected TableViewer
createListPart(Composite parent
, ILabelProvider labelProvider
) {
165 parent
.setLayout(new GridLayout());
167 Composite tableComposite
= new Composite(parent
, SWT
.NONE
);
168 GridData gd
= new GridData(GridData
.HORIZONTAL_ALIGN_FILL
| GridData
.GRAB_VERTICAL
169 | GridData
.VERTICAL_ALIGN_FILL
| GridData
.GRAB_HORIZONTAL
);
170 tableComposite
.setLayoutData(gd
);
172 TableViewer v
= new TableViewer(tableComposite
);
173 v
.setLabelProvider(labelProvider
);
175 TableColumn singleColumn
= new TableColumn(v
.getTable(), SWT
.V_SCROLL
);
176 TableColumnLayout tableColumnLayout
= new TableColumnLayout();
177 tableColumnLayout
.setColumnData(singleColumn
, new ColumnWeightData(85));
178 tableComposite
.setLayout(tableColumnLayout
);
180 // Corresponding table & style
181 Table table
= v
.getTable();
182 table
.setLinesVisible(true);
183 table
.setHeaderVisible(false);
184 CmsUtils
.markup(table
);
185 CmsUtils
.setItemHeight(table
, 26);
187 v
.setContentProvider(new BasicNodeListContentProvider());
188 v
.addDoubleClickListener(new JcrViewerDClickListener(systemWorkbenchService
));
189 v
.addSelectionChangedListener(new ISelectionChangedListener() {
190 public void selectionChanged(SelectionChangedEvent event
) {
191 IStructuredSelection selection
= (IStructuredSelection
) event
.getSelection();
192 List
<?
> lst
= selection
.toList();
193 if (lst
!= null && !lst
.isEmpty())
194 selectionService
.setSelection(selection
.toList());
196 selectionService
.setSelection(null);
203 public void dispose() {
204 JcrUtils
.logoutQuietly(session
);
208 public void setFocus() {
209 refreshFilteredList();
210 filterTxt
.setFocus();
214 public void forceRefresh(Object object
) {
215 refreshFilteredList();
218 protected void refreshFilteredList() {
220 String filter
= filterTxt
.getText();
221 // Prevents the query on the full repository
222 // if (isEmpty(filter)) {
223 // entityViewer.setInput(null);
228 String xpathQueryStr
= "//element(*, " + ConnectTypes
.CONNECT_ENTITY
+ ")";
229 String xpathFilter
= XPathUtils
.getFreeTextConstraint(filter
);
230 if (notEmpty(xpathFilter
))
231 xpathQueryStr
+= "[" + xpathFilter
+ "]";
233 // boolean doOrder = orderResultsBtn != null
234 // && !(orderResultsBtn.isDisposed())
235 // && orderResultsBtn.getSelection();
237 // xpathQueryStr += " order by jcr:title";
240 long begin
= System
.currentTimeMillis();
241 // session.refresh(false);
242 Query xpathQuery
= XPathUtils
.createQuery(session
, xpathQueryStr
);
244 xpathQuery
.setLimit(ConnectUiConstants
.SEARCH_DEFAULT_LIMIT
);
245 QueryResult result
= xpathQuery
.execute();
247 NodeIterator nit
= result
.getNodes();
248 entityViewer
.setInput(JcrUtils
.nodeIteratorToList(nit
));
249 if (log
.isTraceEnabled()) {
250 long end
= System
.currentTimeMillis();
251 log
.trace("Quick Search - Found: " + nit
.getSize() + " in " + (end
- begin
)
252 + " ms by executing XPath query (" + xpathQueryStr
+ ").");
254 } catch (RepositoryException e
) {
255 throw new ConnectException("Unable to list entities", e
);
259 // public void setRepository(Repository repository) {
260 // this.repository = repository;
263 // public void setResourcesService(ResourcesService resourcesService) {
264 // this.resourcesService = resourcesService;
267 // public void setActivitiesService(ActivitiesService activitiesService) {
268 // this.activitiesService = activitiesService;
271 // public void setPeopleService(PeopleService peopleService) {
272 // this.peopleService = peopleService;
275 // public void setSystemWorkbenchService(SystemWorkbenchService
276 // systemWorkbenchService) {
277 // this.systemWorkbenchService = systemWorkbenchService;