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