Package org.expath.httpclient.model.exist

Source Code of org.expath.httpclient.model.exist.EXistElement$ElementIterator

/*
*  eXist EXPath
*  Copyright (C) 2011 Adam Retter <adam@existsolutions.com>
*  www.existsolutions.com
*  This program 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
*  of the License, or (at your option) any later version.
*  This program 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 program; if not, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*  $Id$
*/
package org.expath.httpclient.model.exist;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import org.exist.xquery.XPathException;
import org.exist.xquery.XQueryContext;
import org.exist.xquery.value.NodeValue;
import org.exist.xquery.value.ValueSequence;
import org.expath.httpclient.HttpClientException;
import org.expath.httpclient.HttpConstants;
import org.expath.httpclient.model.Attribute;
import org.expath.httpclient.model.Element;
import org.expath.httpclient.model.Sequence;
import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* @author Adam Retter <adam@existsolutions.com>
*/
public class EXistElement implements Element {

    private final NodeValue element;
    private final XQueryContext context;
   
    public EXistElement(NodeValue element, XQueryContext context) {
        this.element = element;
        this.context = context;
    }
   
    @Override
    public Iterable<Attribute> attributes() throws HttpClientException {
       
        return new Iterable<Attribute>() {
            @Override
            public Iterator<Attribute> iterator() {
                return new Iterator<Attribute>() {
                   
                    private final NamedNodeMap attrs = element.getNode().getAttributes();
                    private final int length = attrs.getLength();
                    private int position = 0;
                   
                    @Override
                    public boolean hasNext() {
                        return(position < length);
                    }

                    @Override
                    public Attribute next() {
                        if(position >= length){
                            throw new NoSuchElementException();
                        }
                       
                        return new EXistAttribute((Attr)attrs.item(position++));
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException("Not supported yet.");
                    }
                   
                };
           
        };
    }

    @Override
    public Iterable<Element> children() throws HttpClientException {
        final Node node = element.getNode();
        return new IterableElement(node);
    }

    @Override
    public String getAttribute(String local_name) throws HttpClientException {
        String attrValue = null;
        NamedNodeMap attrs = element.getNode().getAttributes();
        Node attr = attrs.getNamedItem(local_name);
        if(attr != null) {
            attrValue = ((Attr)attr).getValue();
        }

        return attrValue;
    }

    @Override
    public Sequence getContent() throws HttpClientException {
        org.exist.xquery.value.Sequence valueSequence = new ValueSequence();
       
        NodeList children = element.getNode().getChildNodes();
       
        try {
            for(int i = 0; i < children.getLength(); i++) {
                Node child = children.item(i);
                valueSequence.add((NodeValue)child);
            }
            return new EXistSequence(valueSequence, context);
        } catch(XPathException xpe) {
            throw new HttpClientException(xpe.getMessage(), xpe);
        }
    }

    @Override
    public String getDisplayName() throws HttpClientException {
        return element.getNode().getNodeName();
    }

    @Override
    public String getLocalName() throws HttpClientException {
        return element.getNode().getLocalName();
    }

    @Override
    public String getNamespaceUri() {
        return element.getNode().getNamespaceURI();
    }

    @Override
    public boolean hasNoNsChild() throws HttpClientException {
        NodeList children = element.getNode().getChildNodes();
        for(int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            if(child.getNamespaceURI() == null && child.getPrefix() == null || child.getNamespaceURI().equalsIgnoreCase("")) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Iterable<Element> httpNsChildren() throws HttpClientException {
      
        final Node node = element.getNode();
        return new IterableElement(node, HttpConstants.HTTP_CLIENT_NS_URI);
    }

    /**
     * Check the element {@code elem} does not have attributes other than {@code names}.
     *
     * {@code names} contains non-qualified names, for allowed attributes.  The
     * element can have other attributes in other namespace (not in the HTTP
     * Client namespace) but no attributes in no namespace.
     *
     * @param names The non-qualified names of allowed attributes (cannot be
     * null, but can be empty.)
     *
     * @throws HttpClientException If the element contains an attribute in the
     * HTTP Client namespace, or in no namespace and the name of which is not
     * in {@code names}.
     */
    @Override
    public void noOtherNCNameAttribute(String[] names) throws HttpClientException {
        NamedNodeMap attributes = element.getNode().getAttributes();
       
        for(int i = 0; i < attributes.getLength(); i++) {
            Node attribute = attributes.item(i);
            if(attribute.getNamespaceURI() != null) {
                if(attribute.getNamespaceURI().equals(HttpConstants.HTTP_CLIENT_NS_URI)) {
                    throw new HttpClientException("Element contains an attribute '" + attribute.getNodeName() + "' in the HTTP Client namespace");
                }
            } else {
                boolean matched = false;
                for(String name: names) {
                    if(attribute.getLocalName().equals(name)) {
                        matched = true;
                        break;
                    }
                }
                if(!matched) {
                    throw new HttpClientException("Element contains an attribute '" + attribute.getNodeName() + "' in no namespace but that attribute is not permitted");
                }
            }
        }
    }
   
    public class IterableElement implements Iterable<Element> {

        private final Node node;
        private String inNamespaceURI = null;

        public IterableElement(Node node) {
            this.node = node;
        }
       
        public IterableElement(Node node, String inNamespaceURI) {
            this.node = node;
            this.inNamespaceURI = inNamespaceURI;
        }
       
        @Override
        public Iterator<Element> iterator() {
            return new ElementIterator(node, inNamespaceURI);
        }
       
    }
   
    public class ElementIterator implements Iterator<Element> {
       
        private final Node parent;
        private final String inNamespaceURI;
       
        private List<org.w3c.dom.Element> elements = null;
        private int position = 0;
       
        public ElementIterator(Node parent, String inNamespaceURI) {
            this.parent = parent;
            this.inNamespaceURI = inNamespaceURI;
        }

        @Override
        public boolean hasNext() {
            return(position < getLength());
        }

        @Override
        public Element next() {
            if(position >= getLength()){
                throw new NoSuchElementException();
            }

            return new EXistElement((NodeValue)getElements().get(position++), context);
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        private int getLength() {
            return getElements().size();
        }
       
        /**
         * lazy initialised
         */
        private List<org.w3c.dom.Element> getElements() {

            if(elements == null) {
                elements = new ArrayList<org.w3c.dom.Element>();
                NodeList children = parent.getChildNodes();

                for(int i = 0; i < children.getLength(); i++) {
                    Node child = children.item(i);
                    if(child.getNodeType() == Node.ELEMENT_NODE) {
                        if(inNamespaceURI != null) {
                            if(inNamespaceURI.equals(child.getNamespaceURI())){
                                elements.add((org.w3c.dom.Element)child);
                            }
                        } else {
                            elements.add((org.w3c.dom.Element)child);
                        }
                    }
                }
            }
           
            return elements;
        }
    }
}
TOP

Related Classes of org.expath.httpclient.model.exist.EXistElement$ElementIterator

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.