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

de.mrapp.parser.feed.common.parser.DocumentTreeParser Maven / Gradle / Ivy

The newest version!
/*
 * JavaFeedParserCommon Copyright 2013-2014 Michael Rapp
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see . 
 */
package de.mrapp.parser.feed.common.parser;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;

import de.mrapp.parser.feed.common.builder.AbstractLoggingParserBuilder;
import de.mrapp.parser.feed.common.datastructure.AttributeNode;
import de.mrapp.parser.feed.common.datastructure.DocumentTree;
import de.mrapp.parser.feed.common.datastructure.ElementNode;
import de.mrapp.parser.feed.common.datastructure.Namespace;

/**
 * A parser, which allows to parse a XML structure and returns a tree, which
 * contains the elements and attributes, which correspond to the XML structure.
 * 
 * @author Michael Rapp
 * 
 * @since 1.0.0
 */
public class DocumentTreeParser
		extends
		AbstractLoggingParser> {

	/**
	 * Parses an element of the XML structure.
	 * 
	 * @param element
	 *            The element, which should be parsed, as an instance of the
	 *            type {@link Element}. The element may not be null
	 * @return An instance of the class {@link ElementNode}, which corresponds
	 *         to the parsed element. The instance may not be null
	 * @throws ParserException
	 *             The exception, which is thrown, if an error occurs, while
	 *             parsing the element
	 */
	private ElementNode parseElement(final Element element)
			throws ParserException {
		ElementNode elementNode = new ElementNode(parseElementName(element));
		elementNode.setValue(parseElementValue(element));
		elementNode.setNamespace(parseNamespace(element.getNamespace()));
		elementNode.addAllChildren(parseChildren(element));
		elementNode.addAllAttributes(parseAttributes(element));
		return elementNode;
	}

	/**
	 * Parses the name of an element of the XML structure.
	 * 
	 * @param element
	 *            The element, whose name should be parsed, as an instance of
	 *            the type {@link Element}. The element may not be null
	 * @return The name of the parsed element as a {@link String}. The name may
	 *         neither be null, nor empty
	 * @throws ParserException
	 *             The exception, which is thrown, if an error occurs, while
	 *             parsing the name
	 */
	private String parseElementName(final Element element)
			throws ParserException {
		String name = element.getName();

		if (name == null) {
			String message = "Parser encountered an element name which is null.";
			logError(message);
			throw new MalformedDocumentException(message);
		} else if (name.isEmpty()) {
			String message = "Parser encountered an empty element name.";
			logError(message);
			throw new MalformedDocumentException(message);
		}

		return name;
	}

	/**
	 * Parses the value of an element of the XML structure.
	 * 
	 * @param element
	 *            The element, whose value should be parsed, as an instance of
	 *            the type {@link Element}. The element may not be null
	 * @return The value of the parsed element as a {@link String}. The value
	 *         may not be null
	 */
	private String parseElementValue(final Element element) {
		String value = element.getValue();

		if (value == null) {
			return "";
		}

		return value;
	}

	/**
	 * Parses an XML namespace declaration.
	 * 
	 * @param namespace
	 *            The namespace, which should be parsed, as an instance of the
	 *            class {@link org.jdom2.Namespace}.
	 * @return The namespace as an instance of the class {@link Namespace}. The
	 *         namespace may not be null
	 */
	private Namespace parseNamespace(final org.jdom2.Namespace namespace) {
		Namespace result = new Namespace();

		if (namespace != null) {
			if (namespace.getPrefix() != null) {
				result.setPrefix(namespace.getPrefix());
			}

			if (namespace.getURI() != null) {
				result.setUri(namespace.getURI());
			}
		}

		return result;
	}

	/**
	 * Parses the children of an element of the XML structure.
	 * 
	 * @param element
	 *            The element, whose children should be parsed, as an instance
	 *            of the type {@link Element}. The element may not be null
	 * @return A collection, which contains the children of the parsed element,
	 *         as an instance of the type {@link Collection}, or an empty
	 *         collection, when the element has no children
	 * @throws ParserException
	 *             The exception, which is thrown, if an error occurs, while
	 *             parsing the children
	 */
	private Collection parseChildren(final Element element)
			throws ParserException {
		Collection elementNodes = new LinkedList();
		List elements = element.getChildren();

		for (int i = 0; i < elements.size(); i++) {
			Element child = (Element) elements.get(i);
			elementNodes.add(parseElement(child));
		}

		return elementNodes;
	}

	/**
	 * Parses the attributes of an element of the XML structure.
	 * 
	 * @param element
	 *            The element, which should be parsed, as an instance of the
	 *            type {@link Element}. The element may not be null
	 * @return A collection, which contains the attributes of the parsed
	 *         element, as an instance of the type {@link Collection}, or an
	 *         empty collection, when the element has no attributes
	 * @throws ParserException
	 *             The exception, which is thrown, if an error occurs, while
	 *             parsing the attributes
	 */
	private Collection parseAttributes(final Element element)
			throws ParserException {
		Collection attributeNodes = new LinkedList();
		List attributes = element.getAttributes();

		for (int i = 0; i < attributes.size(); i++) {
			Attribute attribute = (Attribute) attributes.get(i);
			attributeNodes.add(parseAttribute(attribute));
		}

		return attributeNodes;
	}

	/**
	 * Parses an attribute of the XML structure.
	 * 
	 * @param attribute
	 *            The attribute, which should be parsed, as an instance of the
	 *            type {@link Attribute}. The attribute may not be null
	 * @return An instance of the class {@link AttributeNode}, which corresponds
	 *         to the parsed attribute. The instance may not be null
	 * @throws ParserException
	 *             The exception, which is thrown, if an error occurs, while
	 *             parsing the attribute
	 */
	private AttributeNode parseAttribute(final Attribute attribute)
			throws ParserException {
		AttributeNode attributeNode = new AttributeNode(
				parseAttributeName(attribute));
		attributeNode.setValue(parseAttributeValue(attribute));
		attributeNode.setNamespace(parseNamespace(attribute.getNamespace()));
		return attributeNode;
	}

	/**
	 * Parses the name of an attribute of the XML structure.
	 * 
	 * @param attribute
	 *            The attribute, whose name should be parsed, as an instance of
	 *            the class {@link Attribute}. The attribute may not be null
	 * @return The name of the parsed attribute as a {@link String}. The name
	 *         may neither be null, nor empty
	 * @throws ParserException
	 *             The exception, which is thrown, if an error occurs, while
	 *             parsing the name
	 */
	private String parseAttributeName(final Attribute attribute)
			throws ParserException {
		String name = attribute.getName();

		if (name == null) {
			String message = "Parser encountered an attribute name which is null.";
			logError(message);
			throw new MalformedDocumentException(message);
		} else if (name.isEmpty()) {
			String message = "Parser encountered an empty attribute name.";
			logError(message);
			throw new MalformedDocumentException(message);
		}

		return name;
	}

	/**
	 * Parses the value of an attribute of the XML structure.
	 * 
	 * @param attribute
	 *            The attribute, whose value should be parsed, as an instance of
	 *            the class {@link Attribute}. The attribute may not be null
	 * @return The value of the parsed attribute as a {@link String}. The value
	 *         may not be null
	 */
	private String parseAttributeValue(final Attribute attribute) {
		String value = attribute.getValue();

		if (value == null) {
			return "";
		}

		return value;
	}

	/**
	 * Creates a new parser, which allows to parse a XML structure and returns a
	 * tree, which contains the elements and attributes, which correspond to the
	 * XML structure.
	 * 
	 * @param document
	 *            The document, which contains the XML structure, which should
	 *            be parsed, as an instance of the class {@link Document}. The
	 *            document may not be null
	 * @param builder
	 *            The builder, which should be used to initialize the parser, as
	 *            an instance of the class {@link AbstractLoggingParserBuilder}.
	 *            The builder may not be null
	 */
	public DocumentTreeParser(final Document document,
			final AbstractLoggingParserBuilder builder) {
		super(document, builder);
	}

	@Override
	public final DocumentTree parse() throws ParserException {
		Element rootElement = getInput().getRootElement();

		if (rootElement == null) {
			String message = "XML structure contains no root element.";
			logError(message);
			throw new MalformedDocumentException(message);
		}

		DocumentTree documentTree = new DocumentTree(parseElement(rootElement));
		logDebug("Successfully parsed document tree \"{}\".", documentTree);
		return documentTree;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy