/*
 * Copyright (C) 2010 Romain Deltour
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 */
package org.trancecode.xml.saxon;

import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;

import java.util.Map;
import java.util.Map.Entry;

import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XPathExecutable;
import net.sf.saxon.s9api.XPathSelector;
import net.sf.saxon.s9api.XdmNode;
import org.trancecode.annotation.Nullable;
import org.trancecode.logging.Logger;

/**
 * A utility class to evaluate an XSLT Match pattern against nodes.
 * <p>
 * The implementation is based on the s9api front-end to the Saxon pattern
 * engine (see this <a
 * href="http://markmail.org/message/cy6n4zffsh3zw5mz"/>saxon-help email
 * thread</a> for more information).
 * </p>
 * 
 * @see XPathCompiler#compilePattern(String)
 * @author Romain Deltour
 * @author Herve Quiroz
 */
public class SaxonPatternMatcher implements Predicate<XdmNode>
{
    private static final Map<String, String> NO_NAMESPACES = ImmutableMap.of();
    private static final Logger LOG = Logger.getLogger(SaxonPatternMatcher.class);

    private XPathExecutable xpathExec;

    /**
     * Creates a new matcher for the given XSLT match pattern.
     * 
     * @param processor
     *            The Saxon processor used to create the internal
     *            {@link XPathCompiler}
     * @param pattern
     *            The XSLT pattern evaluated by this matcher
     * @throws NullPointerException
     *             is <code>processor</code> or <code>pattern</code> is
     *             <code>null</code>
     */
    public SaxonPatternMatcher(final Processor processor, final String pattern)
    {
        this(processor, pattern, null);
    }

    /**
     * Creates a new matcher for the given XSLT match pattern.
     * 
     * @param processor
     *            The Saxon processor used to create the internal
     *            {@link XPathCompiler}
     * @param pattern
     *            The XSLT pattern evaluated by this matcher
     * @param namespaceContext
     *            A node from which to retrieve namespaces. values.
     * @throws NullPointerException
     *             is <code>processor</code> or <code>pattern</code> is
     *             <code>null</code>
     */
    public SaxonPatternMatcher(final Processor processor, final String pattern, @Nullable final XdmNode namespaceContext)
    {
        Preconditions.checkNotNull(processor);
        Preconditions.checkNotNull(pattern);

        final XPathCompiler xpathCompiler = processor.newXPathCompiler();
        if (namespaceContext != null)
        {
            for (final Entry<String, String> namespace : SaxonNamespaces.namespaceSequence(namespaceContext))
            {
                xpathCompiler.declareNamespace(namespace.getKey(), namespace.getValue());
            }
        }
        try
        {
            xpathExec = xpathCompiler.compilePattern(pattern);
        }
        catch (final SaxonApiException e)
        {
            throw new IllegalArgumentException(e.getMessage(), e);
        }
    }

    /**
     * Evaluates the given node against the XSLT pattern held by this matcher.
     * 
     * @return <code>true</code> iff <code>node</code> matches the pattern.
     * @throws NullPointerException
     *             is <code>node</code> is <code>null</code>
     */
    public boolean match(final XdmNode node)
    {
        Preconditions.checkNotNull(node);

        try
        {
            final XPathSelector s = xpathExec.load();
            s.setContextItem(node);
            return s.effectiveBooleanValue();
        }
        catch (final SaxonApiException e)
        {
            LOG.warn("Unexpected {class.simpleName}: {message}", e, e);
            return false;
        }
    }

    @Override
    public boolean apply(final XdmNode node)
    {
        return match(node);
    }
}

@@ -901,77 +901,8 @@
 te;%0A
-import com.google.common.collect.ImmutableMap;%0A%0Aimport java.util.Map;
 %0Aimp
@@ -1718,88 +1718,8 @@
 %3E%0A%7B%0A
-    private static final Map%3CString, String%3E NO_NAMESPACES = ImmutableMap.of();%0A
     

Remove unused variable