/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/
package org.ofbiz.base.util.string;

import java.beans.FeatureDescriptor;
import java.util.Iterator;
import java.util.List;

import javax.el.CompositeELResolver;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.PropertyNotWritableException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import javolution.util.FastList;

import org.apache.xerces.dom.NodeImpl;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.cache.UtilCache;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Defines property resolution behavior on Nodes. This resolver handles base objects that implement
 * org.w3c.dom.Node or org.apache.xerces.dom.NodeImpl. It accepts a String as a property and compiles
 * that String into an XPathExpression. The resulting value is the evaluation of the XPathExpression
 * in the context of the base Node. This resolver is currently only available in read-only mode, which
 * means that isReadOnly will always return true and {@link #setValue(ELContext, Object, Object, Object)}
 * will always throw PropertyNotWritableException. ELResolvers are combined together using {@link CompositeELResolver}
 * s, to define rich semantics for evaluating an expression. See the javadocs for {@link ELResolver}
 * for details.
 */
public class NodeELResolver extends ELResolver {
    private final XPath xpath;
    private final UtilCache<String, XPathExpression> exprCache = UtilCache.createUtilCache("nodeElResolver.ExpressionCache");
    private static final String module = NodeELResolver.class.getName();

    /**
     * Creates a new read-only NodeELResolver.
     */
    public NodeELResolver() {
        XPathFactory factory = XPathFactory.newInstance();
        xpath = factory.newXPath();
    }

    @Override
    public Class<?> getCommonPropertyType(ELContext context, Object base) {
        return isResolvable(base) ? String.class : null;
    }

    @Override
    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
        return null;
    }

    @Override
    public Class<?> getType(ELContext context, Object base, Object property) {
        if (context == null) {
            throw new NullPointerException("context is null");
        }
        Class<?> result = null;
        if (isResolvable(base)) {
            result = Node.class;
            context.setPropertyResolved(true);
        }
        return result;
    }

    @Override
    public Object getValue(ELContext context, Object base, Object property) {
        if (context == null) {
            throw new NullPointerException("context is null");
        }
        Object result = null;
        if (isResolvable(base)) {
            try {
                Node node = (Node) base;
                String propertyString = (String) property;
                XPathExpression expr = getXPathExpressionInstance(propertyString);
                NodeList nodeList = (NodeList) expr.evaluate(node, XPathConstants.NODESET);
                if (nodeList.getLength() == 0) {
                    return null;
                } else if (nodeList.getLength() == 1) {
                    result = nodeList.item(0);
                } else {
                    List<Node> newList = FastList.newInstance();
                    for (int i = 0; i < nodeList.getLength(); i++) {
                        newList.add(nodeList.item(i));
                    }
                    result = newList;
                }
                context.setPropertyResolved(true);
            } catch (XPathExpressionException e) {
                Debug.logError("An error occurred during XPath expression evaluation, error was: " + e, module);
            }
        }
        return result;
    }

    @Override
    public boolean isReadOnly(ELContext context, Object base, Object property) {
        if (context == null) {
            throw new NullPointerException("context is null");
        }
        if (isResolvable(base)) {
            context.setPropertyResolved(true);
        }
        return true;
    }

    @Override
    public void setValue(ELContext context, Object base, Object property, Object value) {
        if (context == null) {
            throw new NullPointerException("context is null");
        }
        if (isResolvable(base)) {
            throw new PropertyNotWritableException("resolver is read-only");
        }
    }

    private final boolean isResolvable(Object base) {
        return base != null && (base instanceof Node || base instanceof NodeImpl);
    }

    private XPathExpression getXPathExpressionInstance(String xPathString) {
        XPathExpression xpe = exprCache.get(xPathString);
        if (xpe == null) {
            synchronized (exprCache) {
                xpe = exprCache.get(xPathString);
                if (xpe == null) {
                    try {
                        xpe = xpath.compile(xPathString);
                        exprCache.put(xPathString, xpe);
                    } catch (XPathExpressionException e) {
                        Debug.logError("An error occurred during XPath expression compilation, error was: " + e, module);
                    }
                }
            }
        }
        return xpe;
    }
}
