View Javadoc
1   package org.argeo.people.web.pages;
2   
3   import java.util.List;
4   import java.util.Map;
5   
6   import javax.jcr.Node;
7   import javax.jcr.Property;
8   import javax.jcr.RepositoryException;
9   import javax.jcr.Session;
10  import javax.jcr.query.Query;
11  import javax.jcr.query.QueryManager;
12  
13  import org.argeo.cms.ui.CmsUiProvider;
14  import org.argeo.cms.util.CmsUtils;
15  import org.argeo.connect.resources.ResourcesService;
16  import org.argeo.connect.util.ConnectJcrUtils;
17  import org.argeo.eclipse.ui.EclipseUiUtils;
18  import org.argeo.jcr.JcrUtils;
19  import org.argeo.people.PeopleException;
20  import org.argeo.people.PeopleService;
21  import org.argeo.people.web.providers.SearchEntitiesLP;
22  import org.eclipse.jface.layout.TableColumnLayout;
23  import org.eclipse.jface.viewers.ColumnWeightData;
24  import org.eclipse.jface.viewers.DoubleClickEvent;
25  import org.eclipse.jface.viewers.IDoubleClickListener;
26  import org.eclipse.jface.viewers.ILabelProvider;
27  import org.eclipse.jface.viewers.IStructuredContentProvider;
28  import org.eclipse.jface.viewers.IStructuredSelection;
29  import org.eclipse.jface.viewers.TableViewer;
30  import org.eclipse.jface.viewers.Viewer;
31  import org.eclipse.swt.SWT;
32  import org.eclipse.swt.events.ModifyEvent;
33  import org.eclipse.swt.events.ModifyListener;
34  import org.eclipse.swt.layout.GridLayout;
35  import org.eclipse.swt.widgets.Composite;
36  import org.eclipse.swt.widgets.Control;
37  import org.eclipse.swt.widgets.Table;
38  import org.eclipse.swt.widgets.TableColumn;
39  import org.eclipse.swt.widgets.Text;
40  
41  /** Generic page to display a list of filtered nodes, base on their type */
42  public class PeopleQueryPage implements CmsUiProvider {
43  
44  	private PeopleService peopleService;
45  	private ResourcesService resourcesService;
46  	private Map<String, String> iconPathes;
47  
48  	public PeopleQueryPage(PeopleService peopleService, ResourcesService resourcesService,
49  			Map<String, String> iconPathes) {
50  		this.peopleService = peopleService;
51  		this.resourcesService = resourcesService;
52  		this.iconPathes = iconPathes;
53  	}
54  
55  	@Override
56  	public Control createUi(Composite parent, Node context) {
57  		Composite body = new Composite(parent, SWT.NO_FOCUS);
58  		body.setLayoutData(EclipseUiUtils.fillAll());
59  		populateBodyPanel(body, context);
60  		parent.layout();
61  		return body;
62  	}
63  
64  	public void populateBodyPanel(Composite parent, final Node context) {
65  		parent.setLayout(new GridLayout());
66  		final Text entityFilterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
67  		entityFilterTxt.setLayoutData(EclipseUiUtils.fillWidth());
68  		// entityFilterTxt.setMessage(PeopleMsg.searchEntities.lead());
69  
70  		Composite tableComposite = new Composite(parent, SWT.NONE);
71  		tableComposite.setLayoutData(EclipseUiUtils.fillAll());
72  		final TableViewer entityViewer = createListPart(tableComposite);
73  
74  		entityFilterTxt.addModifyListener(new ModifyListener() {
75  			private static final long serialVersionUID = 1L;
76  
77  			public void modifyText(ModifyEvent event) {
78  				// might be better to use an asynchronous Refresh();
79  				refreshFilteredList(entityViewer, entityFilterTxt.getText(), context);
80  			}
81  		});
82  		refreshFilteredList(entityViewer, entityFilterTxt.getText(), context);
83  	}
84  
85  	protected TableViewer createListPart(Composite parent) {
86  		final TableViewer v = new TableViewer(parent);
87  		TableColumn singleColumn = new TableColumn(v.getTable(), SWT.V_SCROLL);
88  		TableColumnLayout tableColumnLayout = new TableColumnLayout();
89  		tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85));
90  		parent.setLayout(tableColumnLayout);
91  
92  		// Corresponding table & style
93  		Table table = v.getTable();
94  		table.setLinesVisible(true);
95  		table.setHeaderVisible(false);
96  		CmsUtils.markup(table);
97  		CmsUtils.setItemHeight(table, 23);
98  		v.setContentProvider(new BasicContentProvider());
99  		ILabelProvider labelProvider = new SearchEntitiesLP(resourcesService, peopleService, table.getDisplay(),
100 				iconPathes);
101 		v.setLabelProvider(labelProvider);
102 		v.addDoubleClickListener(new IDoubleClickListener() {
103 			@Override
104 			public void doubleClick(DoubleClickEvent event) {
105 				Object firstObj = ((IStructuredSelection) event.getSelection()).getFirstElement();
106 				String path = ConnectJcrUtils.getPath((Node) firstObj);
107 				CmsUtils.getCmsView().navigateTo(path);
108 			}
109 		});
110 		return v;
111 	}
112 
113 	protected void refreshFilteredList(TableViewer entityViewer, String filter, Node context) {
114 		try {
115 			// Do not load all contacts when no filter is present
116 			// if (ConnectJcrUtils.isEmptyString(filter)) {
117 			// entityViewer.setInput(null);
118 			// return;
119 			// }
120 
121 			Session session = context.getSession();
122 			QueryManager queryManager = session.getWorkspace().getQueryManager();
123 
124 			String statement = context.getProperty(Property.JCR_STATEMENT).getString();
125 			String selectorName = statement.substring(statement.indexOf('['), statement.indexOf(']') + 1);
126 
127 			String language = context.getProperty(Property.JCR_LANGUAGE).getString();
128 			if (!Query.JCR_SQL2.equals(language))
129 				throw new PeopleException("Unknown language type " + language);
130 			if (EclipseUiUtils.notEmpty(filter))
131 				statement += " WHERE CONTAINS(" + selectorName + ".*, '*" + filter + "*')";
132 			Query query = queryManager.createQuery(statement, language);
133 
134 			query.getBindVariableNames();
135 			entityViewer.setInput(JcrUtils.nodeIteratorToList(query.execute().getNodes()));
136 		} catch (RepositoryException e) {
137 			throw new PeopleException("Unable to list entities for context " + context + " and filter " + filter, e);
138 		}
139 	}
140 
141 	private class BasicContentProvider implements IStructuredContentProvider {
142 		private static final long serialVersionUID = 1L;
143 		// we keep a cache of the Nodes in the content provider to be able to
144 		// manage long request
145 		private List<Node> nodes;
146 
147 		public void dispose() {
148 		}
149 
150 		// We expect a list of nodes as a new input
151 		@SuppressWarnings("unchecked")
152 		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
153 			nodes = (List<Node>) newInput;
154 		}
155 
156 		public Object[] getElements(Object arg0) {
157 			return nodes.toArray();
158 		}
159 	}
160 }