]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/processors/FilterSelectionRequestQueryProcessor.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.browsing.ui.common / src / org / simantics / browsing / ui / common / processors / FilterSelectionRequestQueryProcessor.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.browsing.ui.common.processors;\r
13 \r
14 import java.util.Collection;\r
15 import java.util.Collections;\r
16 import java.util.HashMap;\r
17 import java.util.Map;\r
18 import java.util.regex.Matcher;\r
19 import java.util.regex.Pattern;\r
20 \r
21 import org.eclipse.core.runtime.Assert;\r
22 import org.simantics.browsing.ui.BuiltinKeys;\r
23 import org.simantics.browsing.ui.GraphExplorer;\r
24 import org.simantics.browsing.ui.NodeContext;\r
25 import org.simantics.browsing.ui.NodeContext.PrimitiveQueryKey;\r
26 import org.simantics.browsing.ui.NodeQueryManager;\r
27 import org.simantics.browsing.ui.PrimitiveQueryUpdater;\r
28 import org.simantics.browsing.ui.SelectionRequest;\r
29 import org.simantics.browsing.ui.common.views.DefaultFilterStrategy;\r
30 import org.simantics.browsing.ui.common.views.IFilterStrategy;\r
31 import org.simantics.browsing.ui.content.Labeler;\r
32 import org.simantics.utils.datastructures.Pair;\r
33 \r
34 /**\r
35  */\r
36 public class FilterSelectionRequestQueryProcessor extends AbstractPrimitiveQueryProcessor<Collection<SelectionRequest>>\r
37         implements ProcessorLifecycle {\r
38 \r
39     HashMap<NodeContext, String> filters = new HashMap<NodeContext, String>();\r
40     HashMap<NodeContext, Pair<PrimitiveQueryKey<?>, PrimitiveQueryUpdater>> updaters = new HashMap<NodeContext, Pair<PrimitiveQueryKey<?>, PrimitiveQueryUpdater>>();\r
41 \r
42     IFilterStrategy filterStrategy;\r
43 \r
44     public FilterSelectionRequestQueryProcessor() {\r
45         this(new DefaultFilterStrategy());\r
46     }\r
47 \r
48     public FilterSelectionRequestQueryProcessor(IFilterStrategy filterStrategy) {\r
49         Assert.isNotNull(filterStrategy, "null filter strategy not allowed");\r
50         this.filterStrategy = filterStrategy;\r
51     }\r
52 \r
53     public IFilterStrategy getFilterStrategy() {\r
54         return filterStrategy;\r
55     }\r
56 \r
57     public void setFilterStrategy(IFilterStrategy filterStrategy) {\r
58         this.filterStrategy = filterStrategy;\r
59     }\r
60 \r
61     @Override\r
62     public String toString() {\r
63         return "SelectionRequestProcessor";\r
64     }\r
65 \r
66     @Override\r
67     public Object getIdentifier() {\r
68         return BuiltinKeys.SELECTION_REQUESTS;\r
69     }\r
70 \r
71     @Override\r
72     public Collection<SelectionRequest> query(PrimitiveQueryUpdater updater, NodeContext context,\r
73             PrimitiveQueryKey<Collection<SelectionRequest>> key) {\r
74         updaters.put(context, new Pair<PrimitiveQueryKey<?>, PrimitiveQueryUpdater>(key, updater));\r
75         return makeFilterRequest(updater, context, filters.get(context));\r
76     }\r
77 \r
78     // TODO: evaluate still if this is ok\r
79     private String adjustFilter(String filter) {\r
80         String[] tokens = filter.split(" ");\r
81 //      System.out.println("FilterSelectionRequestQueryProcessor.adjustFilter=" + filter);\r
82         StringBuilder b = new StringBuilder();\r
83         boolean first = true;\r
84         for(String token : tokens) {\r
85 //            System.out.println("FilterSelectionRequestQueryProcessor.token=" + token);\r
86             if(!token.startsWith("$")) {\r
87                 if(first) first = false;\r
88                 else b.append(" ");\r
89                 b.append(token);\r
90             }\r
91         }\r
92 \r
93         String result = b.toString();\r
94         if(result.isEmpty()) return "*";\r
95         else return result;\r
96     }\r
97 \r
98     private Collection<SelectionRequest> makeFilterRequest(PrimitiveQueryUpdater updater, NodeContext context, final String filter_) {\r
99         if (filter_ == null || filter_.isEmpty())\r
100             return null;\r
101 \r
102         final String filter = adjustFilter(filter_);\r
103         \r
104 //        System.out.println("filter for reg exp = " + filter_ + " -> " + filter);\r
105         \r
106         final String regExFilter = filterStrategy.toPatternString(filter);\r
107         if (regExFilter == null)\r
108             return null;\r
109 \r
110         final Pattern pattern = Pattern.compile(regExFilter);\r
111         final Matcher matcher = pattern.matcher("");\r
112 \r
113         return Collections.singletonList((SelectionRequest) new SelectionRequest() {\r
114             @Override\r
115             public Request getRequest() {\r
116                 return Request.FILTER;\r
117             }\r
118 \r
119             @Override\r
120             public boolean isIncluded(NodeQueryManager manager, Object object) {\r
121                 NodeContext context = (NodeContext)object;\r
122                 Labeler labeler = manager.query(context, BuiltinKeys.SELECTED_LABELER);\r
123 \r
124                 if (labeler == null)\r
125                     return false;\r
126                 Map<String, String> labels = labeler.getLabels();\r
127                 if (labels.isEmpty())\r
128                     return false;\r
129 \r
130                 // TODO: only visible columns!\r
131                 for(String s : labels.values()) {\r
132                     //System.out.println("matching " + s);\r
133                     if (s == null)\r
134                         continue;\r
135                     // TODO: remove forced lowercase and leave the case-insensitiveness up to the pattern\r
136                     matcher.reset(s.toLowerCase());\r
137                     if (matcher.matches()) {\r
138                         return false;\r
139                     }\r
140                 }\r
141 \r
142                 return true;\r
143             }\r
144 \r
145             @SuppressWarnings("unchecked")\r
146             @Override\r
147             public <T> T getData() {\r
148                 return (T)filter_;\r
149             }\r
150 \r
151         });\r
152     }\r
153 \r
154     public String getFilter(NodeContext context) {\r
155         return filters.get(context);\r
156     }\r
157 \r
158     /**\r
159      * @param context\r
160      * @param filter a regular expression adhering to {@link Pattern} or\r
161      *        <code>null</code> to disable filtering for the specified context\r
162      */\r
163     @SuppressWarnings("unchecked")\r
164     public void setFilter(NodeContext context, String filter) {\r
165         if (filter == null) {\r
166             filters.remove(context);\r
167         } else {\r
168             filters.put(context, filter);\r
169         }\r
170         Pair<PrimitiveQueryKey<?>, PrimitiveQueryUpdater> p = updaters.get(context);\r
171 \r
172         // FIXME: this is not valid or anything, but prevents NPE crashboombangs for now.\r
173         if (p == null)\r
174             return;\r
175 \r
176         if (p.second == null)\r
177             throw new IllegalArgumentException("context not found in cache");\r
178         p.second.scheduleReplace(context, (PrimitiveQueryKey<Collection<SelectionRequest>>) p.first, makeFilterRequest(p.second, context, filter));\r
179     }\r
180 \r
181     @Override\r
182     public void attached(GraphExplorer explorer) {\r
183     }\r
184 \r
185     @Override\r
186     public void detached(GraphExplorer explorer) {\r
187     }\r
188 \r
189     @Override\r
190     public void clear() {\r
191         filters.clear();\r
192         updaters.clear();\r
193     }\r
194 \r
195 }\r