Package org.dbwiki.data.io

Source Code of org.dbwiki.data.io.InputCallbackHandler

/*
    BEGIN LICENSE BLOCK
    Copyright 2010-2011, Heiko Mueller, Sam Lindley, James Cheney and
    University of Edinburgh

    This file is part of Database Wiki.

    Database Wiki 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.

    Database Wiki 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 Database Wiki.  If not, see <http://www.gnu.org/licenses/>.
    END LICENSE BLOCK
*/
package org.dbwiki.data.io;

import java.util.Stack;

import org.dbwiki.data.document.DocumentAttributeNode;
import org.dbwiki.data.document.DocumentGroupNode;
import org.dbwiki.data.document.DocumentNode;

import org.dbwiki.data.schema.AttributeSchemaNode;
import org.dbwiki.data.schema.DatabaseSchema;
import org.dbwiki.data.schema.SchemaNode;
import org.dbwiki.data.schema.GroupSchemaNode;

import org.dbwiki.exception.WikiFatalException;
import org.dbwiki.exception.data.WikiDataException;

/** Callbacks for parsing an XML file that meets our special case of XML
* FIXME #xmlparsing: This is only used in DocumentInputHandler and so can probably be merged with it (at least as a private inner class)
* TODO #xmlparsing: Add error handling so that we don't just fail if the XML document uses features we don't handle.
* @author jcheney
*
*/
public class InputCallbackHandler {
  /*
   * Private Methods
   */
 
 
  private Stack<DocumentNode> _elementStack;
  private int _ignoreSubtreeDepth = -1;
  private DocumentNode _root;
  private SchemaNode _rootSchemaNode;
  private NodeValueReader _valueReader;
 
 
  /*
   * Constructors
   */
 
  public InputCallbackHandler(SchemaNode rootSchemaNode) {
    _rootSchemaNode = rootSchemaNode;
    _valueReader = null;
  }
 
  public InputCallbackHandler(DatabaseSchema schema) {
    _rootSchemaNode = schema.root();
    _valueReader = null;
  }
  /*
   * Public Methods
   */
 
  public void endDocument() throws org.dbwiki.exception.WikiException {
    if (!_elementStack.isEmpty()) {
      throw new WikiDataException(WikiDataException.UnexcpectedEOD, "Open elements on input stack");
    }
    if (_valueReader != null) {
      throw new WikiDataException(WikiDataException.UnexcpectedEOD, "Open elements on input stack");
    }
  }
 
  public void endElement() throws org.dbwiki.exception.WikiException {
    if (_ignoreSubtreeDepth > 0) {
      _ignoreSubtreeDepth--;
    } else if (_valueReader != null) {
      if (_valueReader.hasOpenElements()) {
        _valueReader.endElement();
      } else if (!_elementStack.isEmpty()) {
        DocumentNode currentElement = _elementStack.peek();
        if (currentElement.isAttribute()) {
          DocumentAttributeNode attribute = (DocumentAttributeNode)currentElement;
          if (!attribute.hasValue()) {
            attribute.setValue(_valueReader.value());
            _valueReader = null;
            _elementStack.pop();
          } else {
            throw new WikiDataException(WikiDataException.InvaldInputData, "Duplicate text value for attribute " + attribute.label());
          }
        } else {
          throw new WikiDataException(WikiDataException.InvaldInputData, "Unexpected text value under element " + currentElement.label());
        }
      } else {
        throw new WikiDataException(WikiDataException.InvaldInputData, "Trying to close non-existing element past end of document");
      }
    } else if (!_elementStack.isEmpty()) {
      _elementStack.pop();
    } else {
      throw new WikiDataException(WikiDataException.InvaldInputData, "Trying to close non-existing element past end of document");
    }
  }
 
  public DocumentNode getRootNode() {
    return _root;
  }
 
  public void startDocument() {
    _elementStack = new Stack<DocumentNode>();
    _ignoreSubtreeDepth = 0;
    _root = null;
  }
 
  public void startElement(String label) throws org.dbwiki.exception.WikiException {
    if (_ignoreSubtreeDepth > 0) {
      _ignoreSubtreeDepth++;
    } else if (_valueReader != null) {
      _valueReader.startElement(label);
    } else if (_root == null) {
      if (_rootSchemaNode.label().equals(label)) {
        if (_rootSchemaNode.isAttribute()) {
          _root = new DocumentAttributeNode((AttributeSchemaNode)_rootSchemaNode);
          _valueReader = new NodeValueReader();
        } else {
          _root = new DocumentGroupNode((GroupSchemaNode)_rootSchemaNode);
        }
        _elementStack.push(_root);
      } else {
        throw new WikiDataException(WikiDataException.InvaldInputData, "Expected root label " + _rootSchemaNode.label() + " instead of " + label);
      }
    } else if (!_elementStack.isEmpty()) {
      DocumentNode element = _elementStack.peek();
      if (element.isGroup()) {
        DocumentGroupNode group = (DocumentGroupNode)element;
        SchemaNode childSchemaNode = ((GroupSchemaNode)group.schema()).children().get(label);
        if (childSchemaNode != null && childSchemaNode.getTimestamp().isCurrent()) {
          DocumentNode child = null;
          if (childSchemaNode.isAttribute()) {
            child = new DocumentAttributeNode((AttributeSchemaNode)childSchemaNode);
            _valueReader = new NodeValueReader();
          } else {
            child = new DocumentGroupNode((GroupSchemaNode)childSchemaNode);
          }
          group.children().add(child);
          _elementStack.push(child);
        } else {
          _ignoreSubtreeDepth = 1;
        }
      } else {
        throw new WikiFatalException("Missing node value reader for attribute node " + element.label());
      }
    } else {
      throw new WikiDataException(WikiDataException.InvaldInputData, "Multiple root nodes detected");
    }
  }
 
  public void text(String value) throws org.dbwiki.exception.WikiException {
    if (_ignoreSubtreeDepth <= 0) {
      if (_valueReader != null) {
        _valueReader.text(value);
      } else if (!value.trim().equals("")) {
        throw new WikiDataException(WikiDataException.InvaldInputData, "Unexpected text node " + value);
      }
    }
  }
}
TOP

Related Classes of org.dbwiki.data.io.InputCallbackHandler

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.