| /******************************************************************************* |
| * Copyright (c) 2001, 2007 Oracle Corporation and others. |
| * 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: |
| * Oracle Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.jsf.core.tagmatcher; |
| |
| import org.eclipse.jst.jsf.common.sets.AxiomaticSet; |
| import org.w3c.dom.Node; |
| |
| /** |
| * An algorithm that can be applied at a particular DOM node. The result |
| * may be expressed as a boolean or a set of matching nodes. The following |
| * are equivalent: |
| * |
| * false and empty set |
| * true and non-empty set |
| * |
| * Concrete implementations must be idempotent on evaluate(): |
| * |
| * 1) evaluate(node) must always return the same set if called repeatedly on |
| * the same node in the same DOM tree. |
| * 2) evaluate must be able to be called on any number of nodes in order and always |
| * produce the same result independent of what was called before and in what order. |
| * |
| * <p><b>Provisional API - subject to change</b></p> |
| * |
| * @author cbateman |
| * |
| */ |
| public abstract class TagMatchingAlgorithm |
| { |
| private boolean _isInvalid; // = false; |
| |
| private boolean _isInitialized; |
| /** |
| * The expression being passed to the algorithm |
| */ |
| protected final String _expression; |
| |
| /** |
| * Constructor. |
| * |
| * @param expression |
| */ |
| protected TagMatchingAlgorithm(String expression) |
| { |
| _expression = expression; |
| } |
| |
| /** |
| * Called exactly once to initialize any pre-evaluation setup for |
| * the expression set for the algorithm. This is public to allow |
| * the client control when this initialization occurs in case it is expensive. |
| * evaluate() will call this method automatically if it has never been called |
| * @throws InvalidExpressionException if the underlying algorithm throws an |
| * exception during init |
| * @throws IllegalStateException if it has already been determined that the |
| * expression is invalid. |
| */ |
| public final void initialize() |
| { |
| if (_isInvalid) |
| { |
| throw new IllegalStateException("Expression: "+_expression+" has already been determined to be invalid"); |
| } |
| |
| if (!_isInitialized) |
| { |
| try |
| { |
| doInitialize(); |
| } |
| catch (Exception e) |
| { |
| _isInvalid = true; |
| throw new InvalidExpressionException(e); |
| } |
| _isInitialized = true; |
| } |
| } |
| |
| /** |
| * @param applyTo |
| * @return the set matching the configured expression applied to applyTo |
| * using the algorithm represented by this instance. |
| * @throws InvalidExpressionException of a problem occurs initializing the expression |
| * @throws EvaluationException if the internal algorithm throws an exception while |
| * evaluating. |
| * @throws IllegalStateException if evaluate is called again once InvalidExpressionException |
| * has already been thrown. |
| */ |
| public final AxiomaticSet evaluate(Node applyTo) |
| { |
| initialize(); |
| return doEvaluate(applyTo); |
| } |
| |
| /** |
| * Implementers must override to the evaluation of the target,expression pair |
| * @param target |
| * @return the algorithm evaluated with |
| */ |
| protected abstract AxiomaticSet doEvaluate(Node target); |
| |
| /** |
| * Do any initialization that is required before the algorithm is used |
| * to evaluate an expression on any node. This will get called exactly once and |
| * is guaranteed to be called, at latest, immediately before doEvaluate |
| * |
| * Method may throw runtime exceptions. These will be repropagated as |
| * InvalidExpressionException's with the original exception wrapped. |
| * @throws Exception |
| */ |
| protected abstract void doInitialize() throws Exception; |
| } |