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.DynamicOperand;
13  import javax.jcr.query.qom.Ordering;
14  import javax.jcr.query.qom.QueryObjectModel;
15  import javax.jcr.query.qom.QueryObjectModelConstants;
16  import javax.jcr.query.qom.QueryObjectModelFactory;
17  import javax.jcr.query.qom.Selector;
18  import javax.jcr.query.qom.StaticOperand;
19  
20  import org.argeo.cms.ui.CmsUiProvider;
21  import org.argeo.cms.util.CmsUtils;
22  import org.argeo.connect.ConnectTypes;
23  import org.argeo.connect.resources.ResourcesService;
24  import org.argeo.connect.util.ConnectJcrUtils;
25  import org.argeo.jcr.JcrUtils;
26  import org.argeo.people.PeopleException;
27  import org.argeo.people.PeopleService;
28  import org.argeo.people.web.providers.SearchEntitiesLP;
29  import org.eclipse.jface.layout.TableColumnLayout;
30  import org.eclipse.jface.viewers.ColumnWeightData;
31  import org.eclipse.jface.viewers.DoubleClickEvent;
32  import org.eclipse.jface.viewers.IDoubleClickListener;
33  import org.eclipse.jface.viewers.ILabelProvider;
34  import org.eclipse.jface.viewers.IStructuredContentProvider;
35  import org.eclipse.jface.viewers.IStructuredSelection;
36  import org.eclipse.jface.viewers.TableViewer;
37  import org.eclipse.jface.viewers.Viewer;
38  import org.eclipse.swt.SWT;
39  import org.eclipse.swt.events.ModifyEvent;
40  import org.eclipse.swt.events.ModifyListener;
41  import org.eclipse.swt.layout.GridData;
42  import org.eclipse.swt.layout.GridLayout;
43  import org.eclipse.swt.widgets.Composite;
44  import org.eclipse.swt.widgets.Control;
45  import org.eclipse.swt.widgets.Label;
46  import org.eclipse.swt.widgets.Table;
47  import org.eclipse.swt.widgets.TableColumn;
48  import org.eclipse.swt.widgets.Text;
49  
50  /** Show all entities that have a given tag-like property */
51  public class TagLikeInstancePage implements CmsUiProvider {
52  
53  	/* DEPENDENCY INJECTION */
54  	private ResourcesService resourcesService;
55  	private PeopleService peopleService;
56  	private Map<String, String> iconPathes;
57  	private String propertyName;
58  
59  	@Override
60  	public Control createUi(Composite parent, Node context) {
61  		Composite body = new Composite(parent, SWT.NO_FOCUS);
62  		body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
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  		Label title = new Label(parent, SWT.WRAP);
71  		CmsUtils.markup(title);
72  		StringBuilder builder = new StringBuilder();
73  		builder.append("<b><big> ");
74  		builder.append(ConnectJcrUtils.get(context, Property.JCR_TITLE));
75  		builder.append("</big></b>");
76  		title.setText(builder.toString());
77  
78  		final Text entityFilterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
79  		entityFilterTxt.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
80  		// entityFilterTxt.setMessage(PeopleMsg.searchEntities.lead());
81  
82  		Composite tableComposite = new Composite(parent, SWT.NONE);
83  		tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
84  		final TableViewer entityViewer = createListPart(tableComposite);
85  
86  		entityFilterTxt.addModifyListener(new ModifyListener() {
87  			private static final long serialVersionUID = 1L;
88  
89  			public void modifyText(ModifyEvent event) {
90  				refreshFilteredList(entityViewer, entityFilterTxt.getText(), context);
91  			}
92  		});
93  		refreshFilteredList(entityViewer, entityFilterTxt.getText(), context);
94  	}
95  
96  	protected TableViewer createListPart(Composite parent) {
97  		final TableViewer v = new TableViewer(parent);
98  		TableColumn singleColumn = new TableColumn(v.getTable(), SWT.V_SCROLL);
99  		TableColumnLayout tableColumnLayout = new TableColumnLayout();
100 		tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85));
101 		parent.setLayout(tableColumnLayout);
102 
103 		// Corresponding table & style
104 		Table table = v.getTable();
105 		table.setLinesVisible(true);
106 		table.setHeaderVisible(false);
107 		CmsUtils.markup(table);
108 		CmsUtils.setItemHeight(table, 23);
109 		v.setContentProvider(new BasicContentProvider());
110 		ILabelProvider labelProvider = new SearchEntitiesLP(resourcesService, peopleService, table.getDisplay(),
111 				iconPathes);
112 		v.setLabelProvider(labelProvider);
113 		v.addDoubleClickListener(new IDoubleClickListener() {
114 			@Override
115 			public void doubleClick(DoubleClickEvent event) {
116 				Object firstObj = ((IStructuredSelection) event.getSelection()).getFirstElement();
117 				String path = ConnectJcrUtils.getPath((Node) firstObj);
118 				CmsUtils.getCmsView().navigateTo(path);
119 			}
120 		});
121 		return v;
122 	}
123 
124 	protected void refreshFilteredList(TableViewer entityViewer, String filter, Node context) {
125 		try {
126 			Session session = context.getSession();
127 			QueryManager queryManager = session.getWorkspace().getQueryManager();
128 			QueryObjectModelFactory factory = queryManager.getQOMFactory();
129 			String path = "/"; // peopleService.getDefaultBasePath();
130 			String value = context.getProperty(Property.JCR_TITLE).getString();
131 
132 			Selector source = factory.selector(ConnectTypes.CONNECT_ENTITY, ConnectTypes.CONNECT_ENTITY);
133 
134 			// Reduce to the business sub tree
135 			Constraint descCst = factory.descendantNode(source.getSelectorName(), path);
136 
137 			// only entities with correct tag like value
138 			StaticOperand so = factory.literal(session.getValueFactory().createValue(value));
139 			DynamicOperand dyo = factory.propertyValue(source.getSelectorName(), propertyName);
140 			Constraint tagCst = factory.comparison(dyo, QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO, so);
141 
142 			Constraint defaultC = factory.and(tagCst, descCst);
143 
144 			// Apply filtering
145 			for (String token : filter.trim().split(" ")) {
146 				StaticOperand so2 = factory.literal(session.getValueFactory().createValue("*" + token + "*"));
147 				Constraint currC = factory.fullTextSearch(source.getSelectorName(), null, so2);
148 				defaultC = factory.and(defaultC, currC);
149 			}
150 
151 			Ordering order = factory.ascending(factory.propertyValue(source.getSelectorName(), Property.JCR_TITLE));
152 			QueryObjectModel query = factory.createQuery(source, defaultC, new Ordering[] { order }, null);
153 			entityViewer.setInput(JcrUtils.nodeIteratorToList(query.execute().getNodes()));
154 		} catch (RepositoryException e) {
155 			throw new PeopleException("Unable to list entities for context " + context + " and filter " + filter, e);
156 		}
157 	}
158 
159 	private class BasicContentProvider implements IStructuredContentProvider {
160 		private static final long serialVersionUID = 1L;
161 		// we keep a cache of the Nodes in the content provider to be able to
162 		// manage long request
163 		private List<Node> nodes;
164 
165 		public void dispose() {
166 		}
167 
168 		// We expect a list of nodes as a new input
169 		@SuppressWarnings("unchecked")
170 		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
171 			nodes = (List<Node>) newInput;
172 		}
173 
174 		public Object[] getElements(Object arg0) {
175 			return nodes.toArray();
176 		}
177 	}
178 
179 	/* DEPENDENCY INJECTION */
180 	public void setPeopleService(PeopleService peopleService) {
181 		this.peopleService = peopleService;
182 	}
183 
184 	public void setResourcesService(ResourcesService resourcesService) {
185 		this.resourcesService = resourcesService;
186 	}
187 
188 	public void setIconPathes(Map<String, String> iconPathes) {
189 		this.iconPathes = iconPathes;
190 	}
191 
192 	public void setPropertyName(String propertyName) {
193 		this.propertyName = propertyName;
194 	}
195 }