1
2
3
4
5
6
7
8
9
10 package com.sri.emo.controller.nodefilter;
11
12 import com.jcorporate.expresso.core.controller.*;
13 import com.jcorporate.expresso.core.db.DBException;
14 import com.jcorporate.expresso.core.dbobj.MultiDBObject;
15 import com.jcorporate.expresso.core.dbobj.ValidValue;
16 import com.jcorporate.expresso.core.security.SuperUser;
17 import com.jcorporate.expresso.services.dbobj.RowGroupPerms;
18 import com.jcorporate.expresso.services.dbobj.UserGroup;
19 import com.sri.common.controller.AbstractDBController;
20 import com.sri.common.util.QueryUtils;
21 import com.sri.emo.annotations.NodeTag;
22 import com.sri.emo.controller.NodeAction;
23 import com.sri.emo.dbobj.Attribute;
24 import com.sri.emo.dbobj.Node;
25 import com.sri.emo.dbobj.NodeType;
26
27 import java.util.*;
28
29
30 /***
31 * Provides a session storage wrapper around the filter criteria.
32 *
33 * @author Michael Rimov
34 * @author Larry Hamel
35 */
36 public class NodeFilter implements FilterKeyConstants {
37
38
39 private ExpressoRequest request;
40 private Map filters = null;
41 public static final String IS_TAG_RADIO = "isTag";
42 public static final String IS_LAST_EDITOR_RADIO = "isLastEd";
43 private static final String TAG_OR_LAST_EDITOR_TEXT = "TAG_OR_LAST_ED_TEXT";
44
45
46
47
48 /***
49 * Constructs a filter for the given request
50 */
51 public NodeFilter(ExpressoRequest request) {
52 this.request = request;
53 }
54
55 /***
56 * @return true if filtering criteria exists
57 */
58 public boolean isFiltered() throws ControllerException, DBException {
59 Map filterMap = getCriteria();
60 return (filterMap != null && !filterMap.isEmpty()) || getFilterAttribute() != null;
61 }
62
63 /***
64 * Retrieve the criteria stored in the session. This object
65 * <em>always</em> generates a new copy of the criteria
66 *
67 * @return map of criteria, never null
68 */
69 private Map getCriteria() throws ControllerException {
70
71 Map result = null;
72 if (filters != null) {
73 result = filters;
74 } else {
75
76 result = (Map) request.getSession().getPersistentAttribute(FILTER_KEY);
77 if (result == null) {
78 filters = result = new HashMap();
79 }
80 }
81
82 return result;
83 }
84
85 /***
86 * Sets the new search criteria
87 *
88 * @param newCriteria
89 */
90 private void setCriteria(final Map newCriteria) throws ControllerException {
91 assert newCriteria != null;
92 request.getSession().setPersistentAttribute(FILTER_KEY, newCriteria);
93 filters = null;
94 }
95
96
97 /***
98 * attribute filtering involves some field of an attribute
99 * associated with a given node
100 *
101 * @return attribute that will filter, or null if no filtering is needed
102 */
103 public Attribute getFilterAttribute() throws DBException {
104 Attribute attrib = new Attribute();
105 AbstractDBController.populateDBObject(attrib, request);
106
107
108
109
110
111
112 String rememberType = attrib.getParentNodeType();
113 String id = attrib.getParentNodeId();
114 attrib.setParentNodeId((String) null);
115 attrib.setParentNodeType((String) null);
116
117 if (attrib.isEmpty()) {
118 return null;
119 }
120
121 attrib.setParentNodeType(rememberType);
122 attrib.setParentNodeId(id);
123
124 return attrib;
125 }
126
127 /***
128 * add filtering for last editor
129 */
130 public void addLasteditorFilter(Node samplenode) throws ControllerException, DBException {
131 String lastEd = (String) getCriteria().get(FILTER_LAST_EDITOR);
132 if (lastEd != null && lastEd.length() > 0) {
133 lastEd = lastEd.trim();
134 samplenode.setNodeOwner("%" + lastEd + "%");
135 }
136 }
137
138 public boolean isFilteringWords() throws ControllerException {
139 return getCriteria().get(FILTER_WORDS) != null;
140 }
141
142 /***
143 * add any filters to the multiDBObject supplied. may add nothing, depending on criteria
144 *
145 * @param multi a multiobject with already-added sample node object
146 * @param samplenode
147 */
148 public void addFiltersToMulti(MultiDBObject multi, Node samplenode) throws ControllerException, DBException {
149 StringBuffer where = new StringBuffer();
150
151
152 if (isFilteringWords()) {
153 String words = (String) getCriteria().get(FILTER_WORDS);
154 words = words.trim();
155 String[] wordarr = words.split("//W");
156
157 String[] fieldsToSearch = new String[]{Node.NODE_ANNOTATION, Node.NODE_COMMENT, Node.NODE_TITLE};
158
159 where.append(QueryUtils.keywordMatchClause(wordarr, fieldsToSearch));
160 }
161
162 if (isFilteringTags()) {
163 multi.addDBObj(NodeTag.class.getName(), NodeTag.TAGS_TABLE);
164 multi.setForeignKey(NodeTag.TAGS_TABLE, NodeTag.TAG_PARENT_NODE,
165 Node.NODE_TABLE, Node.NODE_ID);
166 multi.setFieldsToRetrieveToNone(NodeTag.TAGS_TABLE);
167
168 addAnd(where);
169
170 String tags = (String) getCriteria().get(FILTER_TAGS);
171 tags = tags.trim();
172 String[] wordarr = tags.split("//W");
173 where.append(QueryUtils.keywordMatchClause(wordarr, NodeTag.TAG_VALUE));
174 }
175
176 if (isFilteringGroups()) {
177 multi.addDBObj(RowGroupPerms.class.getName(), RowGroupPerms.GROUP_PERMISSIONS_TABLE_NAME);
178 multi.setFieldsToRetrieveToNone(RowGroupPerms.GROUP_PERMISSIONS_TABLE_NAME);
179
180
181
182
183 addAnd(where);
184
185 where.append(
186 QueryUtils.fieldEqualsValueClause(
187 RowGroupPerms.TABLE_NAME, Node.NODE_TABLE, true, false));
188
189
190
191
192 addAnd(where);
193
194
195 where.append(RowGroupPerms.ROW_KEY);
196 where.append(" = ");
197 where.append("CAST( ");
198 where.append(Node.NODE_TABLE);
199 where.append(".");
200 where.append(Node.NODE_ID);
201 where.append(" AS CHAR ) ");
202
203 addAnd(where);
204
205 String grp = (String) getCriteria().get(FILTER_GROUP);
206 where.append(
207 QueryUtils.fieldEqualsValueClause(
208 RowGroupPerms.GROUP, grp, true, false));
209 }
210
211
212 if (where.length() > 0) {
213
214 addAnd(where);
215
216
217 String prestatement = multi.getSQLSelectStatement();
218 int whereStart = prestatement.indexOf("WHERE");
219 if (whereStart >= 0) {
220 where.append(prestatement.substring(whereStart + "WHERE".length()));
221 }
222
223
224
225
226
227
228
229
230
231
232
233
234 multi.setCustomWhereClause(where.toString(), true);
235 }
236 }
237
238 private void addAnd(StringBuffer where) {
239 if (where.length() > 0) {
240 where.append(" AND ");
241 }
242 }
243
244 private boolean isFilteringGroups() throws ControllerException {
245 return getCriteria().get(FILTER_GROUP) != null;
246 }
247
248 private boolean isFilteringTags() throws ControllerException {
249 return getCriteria().get(FILTER_TAGS) != null;
250 }
251
252 public MultiDBObject getMulti(Node samplenode) throws DBException, ControllerException {
253 MultiDBObject multi = new MultiDBObject();
254 multi.setDataContext(request.getDataContext());
255 multi.setSelectDistinct(true);
256 multi.addDBObj(samplenode, Node.NODE_TABLE);
257
258 Attribute attrib = getFilterAttribute();
259 if (attrib != null) {
260
261
262 attrib.setField(Attribute.NODE_ID, samplenode.getNodeId());
263 attrib.setField(Attribute.NODE_TYPE, samplenode.getNodeType());
264
265 multi.addDBObj(attrib, Attribute.TABLE_NAME);
266 multi.setForeignKey(
267 Attribute.TABLE_NAME, Attribute.NODE_ID,
268 Node.NODE_TABLE, Node.NODE_ID);
269
270 multi.setFieldsToRetrieveToNone(Attribute.TABLE_NAME);
271 }
272
273
274 addLasteditorFilter(samplenode);
275
276
277
278
279
280 addFiltersToMulti(multi, samplenode);
281
282
283 return multi;
284 }
285
286 public void addInputs(ExpressoResponse response)
287 throws DBException, ControllerException {
288
289
290 Input groupInput = new Input();
291 groupInput.setName(FILTER_GROUP);
292 groupInput.setValidValues(getGroupValidValues());
293 if (isFilteringGroups()) {
294 groupInput.setDefaultValue((String) getCriteria().get(FILTER_GROUP));
295 }
296 response.add(groupInput);
297
298
299 Input tagOrLastEditorRadio = new Input(TAG_OR_LAST_EDITOR_RADIO);
300 tagOrLastEditorRadio.setType(Input.ATTRIBUTE_RADIO_VERTICAL);
301 tagOrLastEditorRadio.addValidValue(IS_TAG_RADIO, "Tag");
302 tagOrLastEditorRadio.addValidValue(IS_LAST_EDITOR_RADIO, "Last Editor");
303 tagOrLastEditorRadio.setDefaultValue(IS_TAG_RADIO);
304 if (isFilteringLastEditor()) {
305 tagOrLastEditorRadio.setDefaultValue(IS_LAST_EDITOR_RADIO);
306 }
307 response.add(tagOrLastEditorRadio);
308
309
310 Input words = new Input(FILTER_WORDS);
311 words.setType(Input.ATTRIBUTE_TEXTLINE);
312 if (isFilteringWords()) {
313 words.setDefaultValue((String) getCriteria().get(FILTER_WORDS));
314 }
315 response.add(words);
316
317 Input tagOrLastEd = new Input(TAG_OR_LAST_EDITOR_TEXT);
318 tagOrLastEd.setType(Input.ATTRIBUTE_TEXTLINE);
319 if (isFilteringTags()) {
320 tagOrLastEd.setDefaultValue((String) getCriteria().get(FILTER_TAGS));
321 } else if (isFilteringLastEditor()) {
322 tagOrLastEd.setDefaultValue((String) getCriteria().get(FILTER_LAST_EDITOR));
323 }
324 response.add(tagOrLastEd);
325
326 String nodeTypeName = request.getParameter(NodeType.NODE_TYPE_NAME);
327 Transition submit = new Transition("Filter", "Filter", NodeAction.class, DoFilterNodes.STATE_NAME);
328 submit.addParam(Node.NODE_TYPE, request.getParameter(Node.NODE_TYPE));
329 if ( nodeTypeName != null ) {
330 submit.addParam(NodeType.NODE_TYPE_NAME, nodeTypeName);
331 }
332 Attribute attrib = getFilterAttribute();
333 if (attrib != null) {
334 List list = attrib.getMetaData().getFieldNamesList();
335 for (Iterator iterator = list.iterator(); iterator.hasNext();) {
336 String name = (String) iterator.next();
337 if (!attrib.getMetaData().isVirtual(name) && !attrib.isFieldNull(name)) {
338 submit.addParam(name, attrib.getField(name));
339 }
340 }
341 }
342 NodeAction.checkEmbedded(request, submit);
343
344 response.add(submit);
345 }
346
347 private List getGroupValidValues() throws DBException {
348 UserGroup groups = new UserGroup(SuperUser.INSTANCE);
349 List groupValidValues = groups.getValues();
350 ListIterator listIterator = new ArrayList(groupValidValues).listIterator();
351
352
353 while (listIterator.hasNext()) {
354 ValidValue validValue = (ValidValue) listIterator.next();
355 if (UserGroup.UNKNOWN_USERS_GROUP.equals(validValue.getKey())) {
356 groupValidValues.remove(validValue);
357 }
358 if (UserGroup.NOT_REG_USERS_GROUP.equals(validValue.getKey())) {
359 groupValidValues.remove(validValue);
360 }
361 if (UserGroup.ADMIN_GROUP.equals(validValue.getKey())) {
362 groupValidValues.remove(validValue);
363 }
364 if (UserGroup.DEMO_GROUP.equals(validValue.getKey())) {
365 groupValidValues.remove(validValue);
366 }
367 }
368 groupValidValues.add(0, new ValidValue("", "Any"));
369 return groupValidValues;
370 }
371
372 private boolean isFilteringLastEditor() throws ControllerException {
373 return getCriteria().get(FILTER_LAST_EDITOR) != null;
374 }
375
376 /***
377 * get criteria from request and replace in session
378 */
379 public void saveNewCriteria() throws ControllerException {
380
381 decodeTagOrLastEditor();
382
383 Map map = new HashMap();
384 for (int i = 0; i < ALL_FILTER_KEYS.length; i++) {
385 String key = ALL_FILTER_KEYS[i];
386 String val = request.getParameter(key);
387 if (val != null) {
388 val = val.trim();
389 if (val.length() > 0) map.put(key, val);
390 }
391 }
392
393 setCriteria(map);
394 }
395
396 private void decodeTagOrLastEditor() throws ControllerException {
397 String tagEditorText = request.getParameter(TAG_OR_LAST_EDITOR_TEXT);
398 if (tagEditorText != null && tagEditorText.length() > 0) {
399
400 String radio = request.getParameter(TAG_OR_LAST_EDITOR_RADIO);
401 boolean isTag = true;
402 if (IS_LAST_EDITOR_RADIO.equals(radio)) {
403 isTag = false;
404 }
405
406 if (isTag) {
407 request.setParameter(FILTER_TAGS, tagEditorText);
408 } else {
409 request.setParameter(FILTER_LAST_EDITOR, tagEditorText);
410 }
411 }
412 }
413 }