/*******************************************************************************
 * 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.ArrayList;
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 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 = new ArrayList<Node>(nodeList.getLength());
                    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;
    }
}
