View Javadoc
1   package org.argeo.people.web.parts;
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.util.CmsUtils;
19  import org.argeo.connect.ConnectTypes;
20  import org.argeo.connect.resources.ResourcesService;
21  import org.argeo.eclipse.ui.EclipseUiUtils;
22  import org.argeo.jcr.JcrUtils;
23  import org.argeo.people.PeopleException;
24  import org.argeo.people.PeopleService;
25  import org.argeo.people.web.providers.SearchEntitiesLP;
26  import org.eclipse.jface.layout.TableColumnLayout;
27  import org.eclipse.jface.viewers.ColumnWeightData;
28  import org.eclipse.jface.viewers.ILabelProvider;
29  import org.eclipse.jface.viewers.IStructuredContentProvider;
30  import org.eclipse.jface.viewers.TableViewer;
31  import org.eclipse.jface.viewers.Viewer;
32  import org.eclipse.swt.SWT;
33  import org.eclipse.swt.events.ModifyEvent;
34  import org.eclipse.swt.events.ModifyListener;
35  import org.eclipse.swt.layout.GridLayout;
36  import org.eclipse.swt.widgets.Composite;
37  import org.eclipse.swt.widgets.Table;
38  import org.eclipse.swt.widgets.TableColumn;
39  import org.eclipse.swt.widgets.Text;
40  
41  /** Generic composite to display a filtered list of entities */
42  public class PeopleSearchCmp extends Composite {
43  	private static final long serialVersionUID = 8520892609661053149L;
44  
45  	private final PeopleService peopleService;
46  	private final ResourcesService resourceService;
47  	private final Map<String, String> iconPaths;
48  
49  	// We search only in this node subtree.
50  	private Node context;
51  
52  	// State full embedded controls
53  	private TableViewer viewer;
54  	private Text entityFilterTxt;
55  
56  	public PeopleSearchCmp(Composite parent, int style, ResourcesService resourceService, PeopleService peopleService,
57  			Map<String, String> iconPaths) {
58  		super(parent, style);
59  		this.peopleService = peopleService;
60  		this.resourceService = resourceService;
61  		this.iconPaths = iconPaths;
62  	}
63  
64  	public TableViewer getViewer() {
65  		return viewer;
66  	}
67  
68  	public void populate(Node context, boolean doDefaultQuery) {
69  		this.context = context;
70  		Composite parent = this;
71  		parent.setLayout(new GridLayout());
72  		entityFilterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
73  		entityFilterTxt.setLayoutData(EclipseUiUtils.fillWidth());
74  		Composite tableComposite = new Composite(parent, SWT.NONE);
75  		tableComposite.setLayoutData(EclipseUiUtils.fillAll());
76  		viewer = createListPart(tableComposite);
77  
78  		entityFilterTxt.addModifyListener(new ModifyListener() {
79  			private static final long serialVersionUID = 1L;
80  
81  			public void modifyText(ModifyEvent event) {
82  				refresh();
83  			}
84  		});
85  
86  		if (doDefaultQuery)
87  			refresh();
88  	}
89  
90  	protected TableViewer createListPart(Composite parent) {
91  		final TableViewer v = new TableViewer(parent);
92  		TableColumn singleColumn = new TableColumn(v.getTable(), SWT.V_SCROLL);
93  		TableColumnLayout tableColumnLayout = new TableColumnLayout();
94  		tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85));
95  		parent.setLayout(tableColumnLayout);
96  
97  		// Corresponding table & style
98  		Table table = v.getTable();
99  		table.setLinesVisible(true);
100 		table.setHeaderVisible(false);
101 		CmsUtils.markup(table);
102 		CmsUtils.setItemHeight(table, 23);
103 		v.setContentProvider(new BasicContentProvider());
104 		ILabelProvider labelProvider = new SearchEntitiesLP(resourceService, peopleService, table.getDisplay(),
105 				iconPaths);
106 		v.setLabelProvider(labelProvider);
107 		return v;
108 	}
109 
110 	protected void refresh() {
111 		String filter = entityFilterTxt.getText();
112 		try {
113 			Session session = context.getSession();
114 			QueryManager queryManager = session.getWorkspace().getQueryManager();
115 			QueryObjectModelFactory factory = queryManager.getQOMFactory();
116 			String path = context.getPath();
117 
118 			Selector source = factory.selector(ConnectTypes.CONNECT_ENTITY, ConnectTypes.CONNECT_ENTITY);
119 
120 			Constraint defaultC = factory.descendantNode(source.getSelectorName(), path);
121 
122 			if (EclipseUiUtils.notEmpty(filter)) {
123 				String[] strs = filter.trim().split(" ");
124 				for (String token : strs) {
125 					StaticOperand so = factory.literal(session.getValueFactory().createValue("*" + token + "*"));
126 					Constraint currC = factory.fullTextSearch(source.getSelectorName(), null, so);
127 					if (defaultC == null)
128 						defaultC = currC;
129 					else
130 						defaultC = factory.and(defaultC, currC);
131 				}
132 			}
133 
134 			Ordering order = factory.ascending(factory.propertyValue(source.getSelectorName(), Property.JCR_TITLE));
135 			QueryObjectModel query = factory.createQuery(source, defaultC, new Ordering[] { order }, null);
136 
137 			// TODO use a virtual table
138 			viewer.setInput(JcrUtils.nodeIteratorToList(query.execute().getNodes()));
139 
140 		} catch (RepositoryException e) {
141 			throw new PeopleException("Unable to list entities under " + context + " with filter: " + filter, e);
142 		}
143 	}
144 
145 	private class BasicContentProvider implements IStructuredContentProvider {
146 		private static final long serialVersionUID = 1L;
147 
148 		private List<Node> nodes;
149 
150 		// Expects a List<Node> 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 		public void dispose() {
161 		}
162 	}
163 }