/******************************************************************************* * 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.ArrayList; import java.util.Collection; import java.util.Collections; import org.simantics.browsing.ui.BuiltinKeys; import org.simantics.browsing.ui.NodeContext; import org.simantics.browsing.ui.NodeContext.QueryKey; import org.simantics.browsing.ui.NodeQueryManager; import org.simantics.browsing.ui.Tester; import org.simantics.browsing.ui.common.EvaluatorData; import org.simantics.browsing.ui.common.EvaluatorData.Evaluator; import org.simantics.browsing.ui.common.EvaluatorData.EvaluatorTree; import org.simantics.browsing.ui.common.Preference; import org.simantics.utils.datastructures.collections.CollectionUtils; /** * A base class for query processors that resolve a set of suitable factory * classes of a kind for a given INodeContext. * *

* The purpose of this class is to generically implement a basic logic for * resolving available factories (viewpoint/labeler/labeldecorator/comparator) * any given input. The implementation works based on an * EvaluatorData instance that is specified externally.The logic is * as follows: *

*
    *
  1. Get all possible Evaluators from the externally specified * EvaluatorData (see {@link EvaluatorData#get(Object)}).
  2. *
  3. For each Evaluator: * *
  4. *
  5. Sort the results in descending preference order, larger number equals * higher preference
  6. *
* *

* This class intended for sub-classing, please implement these methods: *

* * @author Tuukka Lehtonen * * @param the factory type to use * * @see ComparableFactoryResolver * @see LabelDecoratorFactoryResolver * @see ImageDecoratorFactoryResolver * @see LabelerFactoryResolver * @see ImagerFactoryResolver * @see ViewpointFactoryResolver */ public abstract class AbstractFactoryResolverQueryProcessor extends AbstractNodeQueryProcessor> { private final EvaluatorData data; private final QueryKey> identifier; public AbstractFactoryResolverQueryProcessor(EvaluatorData data, QueryKey> identifier) { this.data = data; this.identifier = identifier; } @Override public QueryKey> getIdentifier() { return identifier; } @Override public Collection query(final NodeQueryManager manager, final NodeContext context) { assert context != null; Object input = context.getConstant(BuiltinKeys.INPUT); assert input != null; Collection evals = data.get(input); if (evals.isEmpty()) return Collections.emptyList(); ArrayList> factories = new ArrayList>(4); for (Evaluator eval : evals) { evaluateTree(manager, context, getEvaluatorTree(eval), factories); } if (factories.isEmpty()) return Collections.emptyList(); if (factories.size() > 1) Collections.sort(factories); ArrayList result = new ArrayList(factories.size()); for (Preference p : factories) { result.add(p.object); } return result; } protected void evaluateTree(NodeQueryManager manager, NodeContext context, EvaluatorTree tree, Collection> result) { Tester test = tree.getTester(); if (test.test(manager, context)) { CollectionUtils.checkedAdd(tree.getAcceptedFactories(), result); Collection> children = tree.getChildren(); if (children == null) return; for (EvaluatorTree e : children) { evaluateTree(manager, context, e, result); } } } /** * @param evaluator * @return */ protected abstract EvaluatorTree getEvaluatorTree(Evaluator evaluator); }