com.unicodecollective.oxml.OxmlParserTests.java Source code

Java tutorial

Introduction

Here is the source code for com.unicodecollective.oxml.OxmlParserTests.java

Source

/*
 * Copyright (c) 2012 Unicode Collective London > Oxml contributors
 * This program is made available under the terms of the MIT License:
 * http://www.opensource.org/licenses/MIT
 */
package com.unicodecollective.oxml;

import static java.lang.String.format;
import static java.util.Arrays.asList;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;

import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;

import org.apache.commons.io.IOUtils;
import org.junit.Test;

import com.unicodecollective.oxml.AbstractElementParser;
import com.unicodecollective.oxml.OxmlParser;

public class OxmlParserTests {

    private static final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();

    @Test
    public void singleEmptyElement() throws XMLStreamException {
        assertEquals(new TopLevel(null), parse("<top-level/>"));
    }

    @Test
    public void singleEmptyElementWithAttribute() throws XMLStreamException {
        assertEquals(new TopLevel("myattr"), parse("<top-level attr=\"myattr\"/>"));
    }

    @Test
    public void singleEmptyElementWithWrongElementNameReturnsNull() throws XMLStreamException {
        assertNull(parse("<dont-know-about-this></dont-know-about-this>"));
        assertNull(parse("<nor-this/>"));
    }

    @Test
    public void singleElementWithCloseTag() throws XMLStreamException {
        assertEquals(new TopLevel("myattr"), parse("<top-level attr=\"myattr\"></top-level>"));
    }

    @Test
    public void singleElementWithContent() throws XMLStreamException {
        assertEquals(new TopLevel("myattr", "Content Here!"),
                parse("<top-level attr=\"myattr\">Content Here!</top-level>"));
    }

    @Test
    public void elementWithChild() throws XMLStreamException {
        assertEquals(new TopLevel("myattr", asList(new SecondLevel("Content!"))),
                parse("<top-level attr=\"myattr\"><second-level>Content!</second-level></top-level>"));
    }

    @Test
    public void elementWithMultipleChildren() throws XMLStreamException {
        assertEquals(new TopLevel("myattr", asList(new SecondLevel("One"), new SecondLevel("Two"))), parse(
                "<top-level attr=\"myattr\"><second-level>One</second-level><second-level>Two</second-level></top-level>"));
    }

    @Test
    public void unknownSecondLevelChildrenAreIgnored() throws XMLStreamException {
        assertEquals(new TopLevel("myattr", asList(new SecondLevel("One"))), parse(
                "<top-level attr=\"myattr\"><second-level>One</second-level><dont-know-this-one><nor-this><nope>Lost!</nope></nor-this></dont-know-this-one></top-level>"));
    }

    @Test
    public void unknownThirdLevelChildrenAreIgnored() throws XMLStreamException {
        assertEquals(new TopLevel("myattr", asList(new SecondLevel())), parse(
                "<top-level attr=\"myattr\"><second-level><dont-know-about-this>Nope!</dont-know-about-this></second-level></top-level>"));
    }

    @Test
    public void whiteSpaceIsIgnored() throws XMLStreamException {
        assertEquals(new TopLevel("myattr", asList(new SecondLevel())), parse(
                "  <top-level attr=\"myattr\">\t\n <second-level  >\n <dont-know-about-this>Nope!</dont-know-about-this></second-level>\t  </top-level>  "));
    }

    /**
     * Note that any whitespace before the XML declaration will cause an error. It's not legal and the Stax parser say no. 
     */
    @Test
    public void xmlDeclarationIsIgnored() throws XMLStreamException {
        assertEquals(new TopLevel("myattr"),
                parse("<?xml version = \"1.0\" ?><top-level attr=\"myattr\"></top-level>"));
    }

    @Test
    public void dtdIsIgnored() throws XMLStreamException {
        assertEquals(new TopLevel("myattr"),
                parse("<!DOCTYPE top-level SYSTEM \"MY.DTD\"><top-level attr=\"myattr\"></top-level>"));
    }

    /* --- Private Helpers --- */

    private TopLevel parse(String xml) throws XMLStreamException {
        return new OxmlParser().parse(stringReader(xml), new TopLevelParser());
    }

    private XMLEventReader stringReader(String xml) throws XMLStreamException {
        return xmlInputFactory.createXMLEventReader(IOUtils.toInputStream(xml));
    }

    private static final class TopLevelParser extends AbstractElementParser<TopLevel> {

        private SecondLevelParser secondLevelParser = new SecondLevelParser();
        private List<SecondLevel> children;

        public TopLevelParser() {
            super("top-level");
        }

        @Override
        protected TopLevel buildObject() {
            return children != null ? new TopLevel(attributes.get("attr"), content, children)
                    : new TopLevel(attributes.get("attr"), content);
        }

        @Override
        protected void processChild(XMLEventReader reader) throws XMLStreamException {
            if (children == null)
                children = new ArrayList<SecondLevel>();
            SecondLevel child = secondLevelParser.parse(reader);
            if (child != null)
                children.add(child);
        }

    }

    private static final class SecondLevelParser extends AbstractElementParser<SecondLevel> {

        public SecondLevelParser() {
            super("second-level");
        }

        @Override
        protected SecondLevel buildObject() {
            return new SecondLevel(content);
        }

    }

    private static final class TopLevel {

        private String attr;
        private String content;
        private List<SecondLevel> secondLevels;

        public TopLevel(String attr, String content, List<SecondLevel> secondLevels) {
            this.attr = attr;
            this.content = content;
            this.secondLevels = secondLevels;
        }

        public TopLevel(String attr, List<SecondLevel> secondLevels) {
            this.attr = attr;
            this.secondLevels = secondLevels;
        }

        public TopLevel(String attr, String content) {
            this.attr = attr;
            this.content = content;
        }

        public TopLevel(String attr) {
            this.attr = attr;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == this)
                return true;
            if (!(obj instanceof TopLevel))
                return false;
            TopLevel that = (TopLevel) obj;
            return (this.content != null ? this.content.equals(that.content) : that.content == null)
                    && (this.attr != null ? this.attr.equals(that.attr) : that.attr == null)
                    && (this.secondLevels != null ? this.secondLevels.equals(that.secondLevels)
                            : that.secondLevels == null);
        }

        @Override
        public int hashCode() {
            int result = 17;
            result = 31 * result + (content != null ? content.hashCode() : 0);
            result = 31 * result + (attr != null ? attr.hashCode() : 0);
            result = 31 * result + (secondLevels != null ? secondLevels.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return format("<%s: {attr: %s, content: %s, secondLevel: %s}>", TopLevel.class.getSimpleName(), attr,
                    content, secondLevels);
        }

    }

    private static final class SecondLevel {

        private String content;

        public SecondLevel() {
        }

        public SecondLevel(String content) {
            this.content = content;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == this)
                return true;
            if (!(obj instanceof SecondLevel))
                return false;
            SecondLevel that = (SecondLevel) obj;
            return (this.content != null ? this.content.equals(that.content) : that.content == null);
        }

        @Override
        public int hashCode() {
            int result = 17;
            result = 31 * result + (content != null ? content.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return format("<%s: {content: %s}>", SecondLevel.class.getSimpleName(), content);
        }

    }

}