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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.browsing.ui.common.processors;
\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
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
36 public class FilterSelectionRequestQueryProcessor extends AbstractPrimitiveQueryProcessor<Collection<SelectionRequest>>
\r
37 implements ProcessorLifecycle {
\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
42 IFilterStrategy filterStrategy;
\r
44 public FilterSelectionRequestQueryProcessor() {
\r
45 this(new DefaultFilterStrategy());
\r
48 public FilterSelectionRequestQueryProcessor(IFilterStrategy filterStrategy) {
\r
49 Assert.isNotNull(filterStrategy, "null filter strategy not allowed");
\r
50 this.filterStrategy = filterStrategy;
\r
53 public IFilterStrategy getFilterStrategy() {
\r
54 return filterStrategy;
\r
57 public void setFilterStrategy(IFilterStrategy filterStrategy) {
\r
58 this.filterStrategy = filterStrategy;
\r
62 public String toString() {
\r
63 return "SelectionRequestProcessor";
\r
67 public Object getIdentifier() {
\r
68 return BuiltinKeys.SELECTION_REQUESTS;
\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
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
93 String result = b.toString();
\r
94 if(result.isEmpty()) return "*";
\r
98 private Collection<SelectionRequest> makeFilterRequest(PrimitiveQueryUpdater updater, NodeContext context, final String filter_) {
\r
99 if (filter_ == null || filter_.isEmpty())
\r
102 final String filter = adjustFilter(filter_);
\r
104 // System.out.println("filter for reg exp = " + filter_ + " -> " + filter);
\r
106 final String regExFilter = filterStrategy.toPatternString(filter);
\r
107 if (regExFilter == null)
\r
110 final Pattern pattern = Pattern.compile(regExFilter);
\r
111 final Matcher matcher = pattern.matcher("");
\r
113 return Collections.singletonList((SelectionRequest) new SelectionRequest() {
\r
115 public Request getRequest() {
\r
116 return Request.FILTER;
\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
124 if (labeler == null)
\r
126 Map<String, String> labels = labeler.getLabels();
\r
127 if (labels.isEmpty())
\r
130 // TODO: only visible columns!
\r
131 for(String s : labels.values()) {
\r
132 //System.out.println("matching " + s);
\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
145 @SuppressWarnings("unchecked")
\r
147 public <T> T getData() {
\r
154 public String getFilter(NodeContext context) {
\r
155 return filters.get(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
163 @SuppressWarnings("unchecked")
\r
164 public void setFilter(NodeContext context, String filter) {
\r
165 if (filter == null) {
\r
166 filters.remove(context);
\r
168 filters.put(context, filter);
\r
170 Pair<PrimitiveQueryKey<?>, PrimitiveQueryUpdater> p = updaters.get(context);
\r
172 // FIXME: this is not valid or anything, but prevents NPE crashboombangs for now.
\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
182 public void attached(GraphExplorer explorer) {
\r
186 public void detached(GraphExplorer explorer) {
\r
190 public void clear() {
\r