Package org.exist.indexing.range

Source Code of org.exist.indexing.range.RangeIndexConfig$PathIterator

package org.exist.indexing.range;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.collation.CollationKeyAnalyzer;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.util.Version;
import org.exist.dom.NodeListImpl;
import org.exist.dom.QName;
import org.exist.storage.NodePath;
import org.exist.util.Collations;
import org.exist.util.DatabaseConfigurationException;
import org.exist.xquery.XPathException;
import org.exist.xquery.value.Type;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

public class RangeIndexConfig {

    private static final String CONFIG_ROOT = "range";
    private static final String CREATE_ELEM = "create";
    private static final String FIELD_ELEM = "field";

    private static final Logger LOG = Logger.getLogger(RangeIndexConfig.class);

    private Map<QName, RangeIndexConfigElement> paths = new TreeMap<QName, RangeIndexConfigElement>();

    private Analyzer analyzer;

    private PathIterator iterator = new PathIterator();

    public RangeIndexConfig(NodeList configNodes, Map<String, String> namespaces) {
        parse(configNodes, namespaces);
    }

    public RangeIndexConfig(RangeIndexConfig other) {
        this.paths = other.paths;
        this.analyzer = other.analyzer;
    }

    public RangeIndexConfigElement find(NodePath path) {
        for (RangeIndexConfigElement rice : paths.values()) {
            if (rice.find(path)) {
                return rice;
            }
        }
        return null;
    }

    private void parse(NodeList configNodes, Map<String, String> namespaces) {
        for(int i = 0; i < configNodes.getLength(); i++) {
            Node node = configNodes.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE && CONFIG_ROOT.equals(node.getLocalName())) {
                parseChildren(node.getChildNodes(), namespaces);
            }
        }
    }

    private void parseChildren(NodeList configNodes, Map<String, String> namespaces) {
        Node node;
        for(int i = 0; i < configNodes.getLength(); i++) {
            node = configNodes.item(i);
            if(node.getNodeType() == Node.ELEMENT_NODE && CREATE_ELEM.equals(node.getLocalName())) {
                try {
                    NodeList fields = getFields((Element) node);
                    RangeIndexConfigElement newConfig;
                    if (fields.getLength() > 0) {
                        newConfig = new ComplexRangeIndexConfigElement((Element) node, fields, namespaces);
                    } else {
                        newConfig = new RangeIndexConfigElement((Element) node, namespaces);
                    }
                    RangeIndexConfigElement idxConf = paths.get(newConfig.getNodePath().getLastComponent());
                    if (idxConf == null) {
                        paths.put(newConfig.getNodePath().getLastComponent(), newConfig);
                    } else {
                        idxConf.add(newConfig);
                    }
                } catch (DatabaseConfigurationException e) {
                    LOG.error("Invalid range index configuration: " + e.getMessage());
                }
            }
        }
        // default analyzer
        analyzer = new KeywordAnalyzer();
    }

    public Analyzer getDefaultAnalyzer() {
        return analyzer;
    }

    public Analyzer getAnalyzer(QName qname, String fieldName) {
        Analyzer analyzer = null;
        if (qname != null) {
            RangeIndexConfigElement idxConf = paths.get(qname);
            if (idxConf != null) {
                analyzer = idxConf.getAnalyzer(null);
            }
        } else {
            for (RangeIndexConfigElement idxConf: paths.values()) {
                if (idxConf.isComplex()) {
                    analyzer = idxConf.getAnalyzer(fieldName);
                    if (analyzer != null) {
                        break;
                    }
                }
            }
        }
        return analyzer;
    }

    public boolean isCaseSensitive(QName qname, String fieldName) {
        boolean caseSensitive = true;
        if (qname != null) {
            RangeIndexConfigElement idxConf = paths.get(qname);
            if (idxConf != null) {
                caseSensitive = idxConf.isCaseSensitive(fieldName);
            }
        } else {
            for (RangeIndexConfigElement idxConf: paths.values()) {
                if (idxConf.isComplex()) {
                    caseSensitive = idxConf.isCaseSensitive(fieldName);
                    if (!caseSensitive) {
                        break;
                    }
                }
            }
        }
        return caseSensitive;
    }

    public Iterator<RangeIndexConfigElement> getConfig(NodePath path) {
        iterator.reset(path);
        return iterator;
    }

    private NodeList getFields(Element root) {
        NodeListImpl fields = new NodeListImpl();
        NodeList children = root.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node node = children.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE && FIELD_ELEM.equals(node.getLocalName())) {
                fields.add(node);
            }
        }
        return fields;
    }

    public boolean matches(NodePath path) {
        RangeIndexConfigElement idxConf = paths.get(path.getLastComponent());
        while (idxConf != null) {
            if (idxConf.match(path))
                return true;
            idxConf = idxConf.getNext();
        }
        return false;
    }

    public int getType(String field) {
        for (RangeIndexConfigElement conf : paths.values()) {
            if (conf.isComplex()) {
                int type = conf.getType(field);
                if (type != Type.ITEM) {
                    return type;
                }
            }
        }
        return Type.ITEM;
    }

    private class PathIterator implements Iterator<RangeIndexConfigElement> {

        private RangeIndexConfigElement nextConfig;
        private NodePath path;
        private boolean atLast = false;

        protected void reset(NodePath path) {
            this.atLast = false;
            this.path = path;
            nextConfig = paths.get(path.getLastComponent());
            if (nextConfig == null) {
                atLast = true;
            }
        }

        @Override
        public boolean hasNext() {
            return (nextConfig != null);
        }

        @Override
        public RangeIndexConfigElement next() {
            if (nextConfig == null)
                return null;

            RangeIndexConfigElement currentConfig = nextConfig;
            nextConfig = nextConfig.getNext();
            if (nextConfig == null && !atLast) {
                atLast = true;
            }
            return currentConfig;
        }

        @Override
        public void remove() {
            //Nothing to do
        }

    }
}
TOP

Related Classes of org.exist.indexing.range.RangeIndexConfig$PathIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.