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.QueryManager;
11  import javax.jcr.query.qom.Constraint;
12  import javax.jcr.query.qom.Ordering;
13  import javax.jcr.query.qom.QueryObjectModel;
14  import javax.jcr.query.qom.QueryObjectModelFactory;
15  import javax.jcr.query.qom.Selector;
16  import javax.jcr.query.qom.StaticOperand;
17  
18  import org.argeo.cms.ui.CmsUiProvider;
19  import org.argeo.cms.util.CmsUtils;
20  import org.argeo.connect.ConnectTypes;
21  import org.argeo.connect.resources.ResourcesService;
22  import org.argeo.connect.util.ConnectJcrUtils;
23  import org.argeo.eclipse.ui.EclipseUiUtils;
24  import org.argeo.jcr.JcrUtils;
25  import org.argeo.people.PeopleException;
26  import org.argeo.people.PeopleService;
27  import org.argeo.people.web.providers.SearchEntitiesLP;
28  import org.eclipse.jface.layout.TableColumnLayout;
29  import org.eclipse.jface.viewers.ColumnWeightData;
30  import org.eclipse.jface.viewers.DoubleClickEvent;
31  import org.eclipse.jface.viewers.IDoubleClickListener;
32  import org.eclipse.jface.viewers.ILabelProvider;
33  import org.eclipse.jface.viewers.IStructuredContentProvider;
34  import org.eclipse.jface.viewers.IStructuredSelection;
35  import org.eclipse.jface.viewers.TableViewer;
36  import org.eclipse.jface.viewers.Viewer;
37  import org.eclipse.swt.SWT;
38  import org.eclipse.swt.events.ModifyEvent;
39  import org.eclipse.swt.events.ModifyListener;
40  import org.eclipse.swt.layout.GridLayout;
41  import org.eclipse.swt.widgets.Composite;
42  import org.eclipse.swt.widgets.Control;
43  import org.eclipse.swt.widgets.Table;
44  import org.eclipse.swt.widgets.TableColumn;
45  import org.eclipse.swt.widgets.Text;
46  
47  /**
48   * Generic page to display a filtered list of entities. TODO check if not
49   * duplicated with PeopleQueryPage
50   */
51  public class PeopleSearchPage implements CmsUiProvider {
52  
53  	/* DEPENDENCY INJECTION */
54  	private PeopleService peopleService;
55  	private ResourcesService resourcesService;
56  
57  	private Map<String, String> iconPathes;
58  
59  	@Override
60  	public Control createUi(Composite parent, Node context) {
61  		Composite body = new Composite(parent, SWT.NO_FOCUS);
62  		body.setLayoutData(EclipseUiUtils.fillAll());
63  		populateBodyPanel(body, context);
64  		parent.layout();
65  		return body;
66  	}
67  
68  	public void populateBodyPanel(Composite parent, final Node context) {
69  		parent.setLayout(new GridLayout());
70  		final Text entityFilterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
71  		entityFilterTxt.setLayoutData(EclipseUiUtils.fillWidth());
72  		// entityFilterTxt.setMessage(PeopleMsg.searchEntities.lead());
73  		Composite tableComposite = new Composite(parent, SWT.NONE);
74  		tableComposite.setLayoutData(EclipseUiUtils.fillAll());
75  		final TableViewer entityViewer = createListPart(tableComposite);
76  
77  		entityFilterTxt.addModifyListener(new ModifyListener() {
78  			private static final long serialVersionUID = 1L;
79  
80  			public void modifyText(ModifyEvent event) {
81  				// might be better to use an asynchronous Refresh();
82  				refreshFilteredList(entityViewer, entityFilterTxt.getText(), context);
83  			}
84  		});
85  		refreshFilteredList(entityViewer, entityFilterTxt.getText(), context);
86  	}
87  
88  	protected TableViewer createListPart(Composite parent) {
89  		final TableViewer v = new TableViewer(parent);
90  		TableColumn singleColumn = new TableColumn(v.getTable(), SWT.V_SCROLL);
91  		TableColumnLayout tableColumnLayout = new TableColumnLayout();
92  		tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85));
93  		parent.setLayout(tableColumnLayout);
94  
95  		// Corresponding table & style
96  		Table table = v.getTable();
97  		table.setLinesVisible(true);
98  		table.setHeaderVisible(false);
99  		CmsUtils.markup(table);
100 		CmsUtils.setItemHeight(table, 23);
101 		v.setContentProvider(new BasicContentProvider());
102 		ILabelProvider labelProvider = new SearchEntitiesLP(resourcesService, peopleService, table.getDisplay(),
103 				iconPathes);
104 		v.setLabelProvider(labelProvider);
105 		v.addDoubleClickListener(new IDoubleClickListener() {
106 			@Override
107 			public void doubleClick(DoubleClickEvent event) {
108 				Object firstObj = ((IStructuredSelection) event.getSelection()).getFirstElement();
109 				String path = ConnectJcrUtils.getPath((Node) firstObj);
110 				CmsUtils.getCmsView().navigateTo("display" + path);
111 			}
112 		});
113 		return v;
114 	}
115 
116 	protected void refreshFilteredList(TableViewer entityViewer, String filter, Node context) {
117 		try {
118 			// Do not load all contacts when no filter is present
119 			// if (ConnectJcrUtils.isEmptyString(filter)) {
120 			// entityViewer.setInput(null);
121 			// return;
122 			// }
123 
124 			Session session = context.getSession();
125 			QueryManager queryManager = session.getWorkspace().getQueryManager();
126 			QueryObjectModelFactory factory = queryManager.getQOMFactory();
127 			String path = context.getPath();
128 
129 			Selector source = factory.selector(ConnectTypes.CONNECT_ENTITY, ConnectTypes.CONNECT_ENTITY);
130 
131 			Constraint defaultC = factory.descendantNode(source.getSelectorName(), path);
132 			String[] strs = filter.trim().split(" ");
133 			for (String token : strs) {
134 				StaticOperand so = factory.literal(session.getValueFactory().createValue("*" + token + "*"));
135 				Constraint currC = factory.fullTextSearch(source.getSelectorName(), null, so);
136 				if (defaultC == null)
137 					defaultC = currC;
138 				else
139 					defaultC = factory.and(defaultC, currC);
140 			}
141 
142 			Ordering order = factory.ascending(factory.propertyValue(source.getSelectorName(), Property.JCR_TITLE));
143 			QueryObjectModel query = factory.createQuery(source, defaultC, new Ordering[] { order }, null);
144 			entityViewer.setInput(JcrUtils.nodeIteratorToList(query.execute().getNodes()));
145 		} catch (RepositoryException e) {
146 			throw new PeopleException("Unable to list entities for context " + context + " and filter " + filter, e);
147 		}
148 	}
149 
150 	private class BasicContentProvider implements IStructuredContentProvider {
151 		private static final long serialVersionUID = 1L;
152 
153 		private List<Node> nodes;
154 
155 		// We expect a list of nodes as a new input
156 		@SuppressWarnings("unchecked")
157 		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
158 			nodes = (List<Node>) newInput;
159 		}
160 
161 		public Object[] getElements(Object arg0) {
162 			return nodes.toArray();
163 		}
164 
165 		public void dispose() {
166 		}
167 	}
168 
169 	/* DEPENDENCY INJECTION */
170 	public void setResourcesService(ResourcesService resourcesService) {
171 		this.resourcesService = resourcesService;
172 	}
173 
174 	public void setPeopleService(PeopleService peopleService) {
175 		this.peopleService = peopleService;
176 	}
177 
178 	public void setIconPathes(Map<String, String> iconPathes) {
179 		this.iconPathes = iconPathes;
180 	}
181 }