All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avaje.ebeaninternal.server.lib.util.DnodeParser Maven / Gradle / Ivy

The newest version!
/**
 *  Copyright (C) 2006  Robin Bygrave
 *  
 *  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
package com.avaje.ebeaninternal.server.lib.util;

import java.util.Stack;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.avaje.ebeaninternal.server.lib.util.StringHelper;

/**
 * Parse an xml document into a Dnode tree.
 */
public class DnodeParser extends DefaultHandler {

    /**
     * The root of the DContent tree.
     */
    Dnode root;

    /**
     * The current node being parsed.
     */
    Dnode currentNode;

    /**
     * The nodeContent buffer.
     */
    StringBuilder buffer;

    /**
     * Used to stack the nodes.
     */
    Stack stack = new Stack();

    /**
     * The class used to construct new nodes. Should be Dnode or a subtype of
     * Dnode.
     */
    Class nodeClass = Dnode.class;

    int depth = 0;
    
    /**
     * Trim whitespace from the content.
     */
    boolean trimWhitespace = true;

    /**
     * The name of the tag that contains html content
     */
    String contentName;
    
    /**
     * The depth of the tag that contains the html content
     */
    int contentDepth;
    
    
    /**
     * If true then trim the whitespace from the content.
     */
    public boolean isTrimWhitespace() {
        return trimWhitespace;
    }

    /**
     * Set whether to trim whitespace from the content.
     */
    public void setTrimWhitespace(boolean trimWhitespace) {
        this.trimWhitespace = trimWhitespace;
    }

    /**
     * Return the root node of the DContent tree.
     */
    public Dnode getRoot() {
        return root;
    }

    /**
     * Set the type class of node to be created.
     */
    public void setNodeClass(Class nodeClass) {
        this.nodeClass = nodeClass;
    }

    /**
     * Create a new Dnode using the nodeClass.
     */
    private Dnode createNewNode() {
        try {
            return (Dnode) nodeClass.newInstance();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }


    /**
     * process a startElement.
     */
    public void startElement(String uri, String localName, String qName, Attributes attributes)
            throws SAXException {

        super.startElement(uri, localName, qName, attributes);
        depth++;
        
        boolean isContent = (contentName != null);
        
        if (isContent){
            // must be html content... add the begin tag as content
            buffer.append("<").append(localName);
            for (int i = 0; i < attributes.getLength(); i++) {
                String key = attributes.getLocalName(i);
                String val = attributes.getValue(i);
                buffer.append(" ").append(key).append("='").append(val).append("'");
            }
            buffer.append(">");
            return;
              
        } 
        
        buffer = new StringBuilder();
        Dnode node = createNewNode();
        node.setNodeName(localName);     
        for (int i = 0; i < attributes.getLength(); i++) {
            String key = attributes.getLocalName(i);
            String val = attributes.getValue(i);
            node.setAttribute(key, val);
            if ("type".equalsIgnoreCase(key) && "content".equalsIgnoreCase(val)) {
                // this tag contains html content
                // no more nodes until end tag is found
                contentName = localName;
                contentDepth = depth-1;
            }
            
        }
        if (root == null) {
            root = node;
        }
        if (currentNode != null) {
            currentNode.addChild(node);
        }
        stack.push(node);
        currentNode = node;
        
    }

    /**
     * append the node content.
     */
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        String s = new String(ch, start, length);
        int p = s.indexOf('\r');
        int p2 = s.indexOf('\n');
        if (p == -1 && p2 > -1) {
            // This is probably not an issue but tidys up content
            // in my text editor
            s = StringHelper.replaceString(s, "\n", "\r\n");
        }
        buffer.append(s);
    }

    /**
     * process the endElement.
     */
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        depth--;
        
        if (contentName != null){
            // is this the end of the content?
            if (contentName.equals(localName) && contentDepth == depth){
                contentName = null;
                
            } else {
                // the html content end tag
                buffer.append("");
            }
            return;
        }
        String content = buffer.toString();
        buffer.setLength(0);
        if (content.length() > 0) {
            if (trimWhitespace) {
            	content = content.trim();
            }
            if (content.length() > 0) {
                currentNode.setNodeContent(content);
            }
        }
        stack.pop();
        if (!stack.isEmpty()) {
            // get the new currentNode
            currentNode = (Dnode) stack.pop();
            stack.push(currentNode);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy