--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.browsing.ui.common.processors;\r
+\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.eclipse.core.runtime.Assert;\r
+import org.simantics.browsing.ui.BuiltinKeys;\r
+import org.simantics.browsing.ui.GraphExplorer;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.NodeContext.PrimitiveQueryKey;\r
+import org.simantics.browsing.ui.NodeQueryManager;\r
+import org.simantics.browsing.ui.PrimitiveQueryUpdater;\r
+import org.simantics.browsing.ui.SelectionRequest;\r
+import org.simantics.browsing.ui.common.views.DefaultFilterStrategy;\r
+import org.simantics.browsing.ui.common.views.IFilterStrategy;\r
+import org.simantics.browsing.ui.content.Labeler;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+/**\r
+ */\r
+public class FilterSelectionRequestQueryProcessor extends AbstractPrimitiveQueryProcessor<Collection<SelectionRequest>>\r
+ implements ProcessorLifecycle {\r
+\r
+ HashMap<NodeContext, String> filters = new HashMap<NodeContext, String>();\r
+ HashMap<NodeContext, Pair<PrimitiveQueryKey<?>, PrimitiveQueryUpdater>> updaters = new HashMap<NodeContext, Pair<PrimitiveQueryKey<?>, PrimitiveQueryUpdater>>();\r
+\r
+ IFilterStrategy filterStrategy;\r
+\r
+ public FilterSelectionRequestQueryProcessor() {\r
+ this(new DefaultFilterStrategy());\r
+ }\r
+\r
+ public FilterSelectionRequestQueryProcessor(IFilterStrategy filterStrategy) {\r
+ Assert.isNotNull(filterStrategy, "null filter strategy not allowed");\r
+ this.filterStrategy = filterStrategy;\r
+ }\r
+\r
+ public IFilterStrategy getFilterStrategy() {\r
+ return filterStrategy;\r
+ }\r
+\r
+ public void setFilterStrategy(IFilterStrategy filterStrategy) {\r
+ this.filterStrategy = filterStrategy;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "SelectionRequestProcessor";\r
+ }\r
+\r
+ @Override\r
+ public Object getIdentifier() {\r
+ return BuiltinKeys.SELECTION_REQUESTS;\r
+ }\r
+\r
+ @Override\r
+ public Collection<SelectionRequest> query(PrimitiveQueryUpdater updater, NodeContext context,\r
+ PrimitiveQueryKey<Collection<SelectionRequest>> key) {\r
+ updaters.put(context, new Pair<PrimitiveQueryKey<?>, PrimitiveQueryUpdater>(key, updater));\r
+ return makeFilterRequest(updater, context, filters.get(context));\r
+ }\r
+\r
+ // TODO: evaluate still if this is ok\r
+ private String adjustFilter(String filter) {\r
+ String[] tokens = filter.split(" ");\r
+// System.out.println("FilterSelectionRequestQueryProcessor.adjustFilter=" + filter);\r
+ StringBuilder b = new StringBuilder();\r
+ boolean first = true;\r
+ for(String token : tokens) {\r
+// System.out.println("FilterSelectionRequestQueryProcessor.token=" + token);\r
+ if(!token.startsWith("$")) {\r
+ if(first) first = false;\r
+ else b.append(" ");\r
+ b.append(token);\r
+ }\r
+ }\r
+\r
+ String result = b.toString();\r
+ if(result.isEmpty()) return "*";\r
+ else return result;\r
+ }\r
+\r
+ private Collection<SelectionRequest> makeFilterRequest(PrimitiveQueryUpdater updater, NodeContext context, final String filter_) {\r
+ if (filter_ == null || filter_.isEmpty())\r
+ return null;\r
+\r
+ final String filter = adjustFilter(filter_);\r
+ \r
+// System.out.println("filter for reg exp = " + filter_ + " -> " + filter);\r
+ \r
+ final String regExFilter = filterStrategy.toPatternString(filter);\r
+ if (regExFilter == null)\r
+ return null;\r
+\r
+ final Pattern pattern = Pattern.compile(regExFilter);\r
+ final Matcher matcher = pattern.matcher("");\r
+\r
+ return Collections.singletonList((SelectionRequest) new SelectionRequest() {\r
+ @Override\r
+ public Request getRequest() {\r
+ return Request.FILTER;\r
+ }\r
+\r
+ @Override\r
+ public boolean isIncluded(NodeQueryManager manager, Object object) {\r
+ NodeContext context = (NodeContext)object;\r
+ Labeler labeler = manager.query(context, BuiltinKeys.SELECTED_LABELER);\r
+\r
+ if (labeler == null)\r
+ return false;\r
+ Map<String, String> labels = labeler.getLabels();\r
+ if (labels.isEmpty())\r
+ return false;\r
+\r
+ // TODO: only visible columns!\r
+ for(String s : labels.values()) {\r
+ //System.out.println("matching " + s);\r
+ if (s == null)\r
+ continue;\r
+ // TODO: remove forced lowercase and leave the case-insensitiveness up to the pattern\r
+ matcher.reset(s.toLowerCase());\r
+ if (matcher.matches()) {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T> T getData() {\r
+ return (T)filter_;\r
+ }\r
+\r
+ });\r
+ }\r
+\r
+ public String getFilter(NodeContext context) {\r
+ return filters.get(context);\r
+ }\r
+\r
+ /**\r
+ * @param context\r
+ * @param filter a regular expression adhering to {@link Pattern} or\r
+ * <code>null</code> to disable filtering for the specified context\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ public void setFilter(NodeContext context, String filter) {\r
+ if (filter == null) {\r
+ filters.remove(context);\r
+ } else {\r
+ filters.put(context, filter);\r
+ }\r
+ Pair<PrimitiveQueryKey<?>, PrimitiveQueryUpdater> p = updaters.get(context);\r
+\r
+ // FIXME: this is not valid or anything, but prevents NPE crashboombangs for now.\r
+ if (p == null)\r
+ return;\r
+\r
+ if (p.second == null)\r
+ throw new IllegalArgumentException("context not found in cache");\r
+ p.second.scheduleReplace(context, (PrimitiveQueryKey<Collection<SelectionRequest>>) p.first, makeFilterRequest(p.second, context, filter));\r
+ }\r
+\r
+ @Override\r
+ public void attached(GraphExplorer explorer) {\r
+ }\r
+\r
+ @Override\r
+ public void detached(GraphExplorer explorer) {\r
+ }\r
+\r
+ @Override\r
+ public void clear() {\r
+ filters.clear();\r
+ updaters.clear();\r
+ }\r
+\r
+}\r