Package org.formulacompiler.spreadsheet.internal.excel.xlsx.loader

Source Code of org.formulacompiler.spreadsheet.internal.excel.xlsx.loader.XmlParser

/*
* Copyright (c) 2006-2009 by Abacus Research AG, Switzerland.
* All rights reserved.
*
* This file is part of the Abacus Formula Compiler (AFC).
*
* For commercial licensing, please contact sales(at)formulacompiler.com.
*
* AFC 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.
*
* AFC 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 AFC.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.formulacompiler.spreadsheet.internal.excel.xlsx.loader;

import java.io.InputStream;
import java.util.Stack;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.formulacompiler.spreadsheet.internal.excel.xlsx.xml.XmlNode;


/**
* @author Igor Didyuk
*/
public abstract class XmlParser
{
  private final XMLEventReader xmlEventReader;
  private final Stack<QName> cursor;

  protected XmlParser( final InputStream _input ) throws XMLStreamException
  {
    this.xmlEventReader = XMLInputFactory.newInstance().createXMLEventReader( _input );
    this.cursor = new Stack<QName>();
  }

  protected final StartElement find( final QName[] _path, final int _context ) throws XMLStreamException
  {
    int matchPosition = _context;
    for (int i = _context; i != this.cursor.size(); i++) {
      if (i - _context >= _path.length || !this.cursor.get( i ).equals( _path[ i - _context ] ))
        break;
      matchPosition++;
    }

    if (matchPosition != this.cursor.size()) {
      while (this.xmlEventReader.hasNext()) {
        final XMLEvent event = this.xmlEventReader.nextEvent();
        if (event.isStartElement()) {
          final StartElement startElement = event.asStartElement();
          final QName name = startElement.getName();
          this.cursor.push( name );
        }
        else if (event.isEndElement()) {
          this.cursor.pop();
          if (this.cursor.size() == matchPosition)
            break;
        }
      }
    }

    while (this.xmlEventReader.hasNext()) {
      final XMLEvent event = this.xmlEventReader.nextEvent();
      if (event.isStartElement()) {
        final StartElement startElement = event.asStartElement();
        final QName name = startElement.getName();
        final int pathIndex = this.cursor.size() - _context;
        if (pathIndex < _path.length && name.equals( _path[ pathIndex ] )) {
          this.cursor.push( name );
          if (this.cursor.size() == _context + _path.length)
            return startElement;
        }
        else {
          skipElement();
        }
      }
      else if (event.isEndElement()) {
        this.cursor.pop();
        if (this.cursor.size() < _context)
          return null;
      }
    }
    return null;
  }

  private void skipElement() throws XMLStreamException
  {
    int level = 0;
    while (this.xmlEventReader.hasNext()) {
      final XMLEvent event = this.xmlEventReader.nextEvent();
      if (event.isStartElement()) level++;
      else if (event.isEndElement() && level-- == 0) return;
    }
  }

  protected final XmlNode readEvents( StartElement _se ) throws XMLStreamException
  {
    final XmlNode node = new XmlNode( _se );

    while (this.xmlEventReader.hasNext()) {
      final XMLEvent event = this.xmlEventReader.nextEvent();
      if (event.isEndElement()) {
        this.cursor.pop();
        return node;
      }
      if (event.isStartElement()) {
        StartElement se = event.asStartElement();
        this.cursor.push( se.getName() );
        node.addChild( new XmlNode( se ) );
      }
    }
    throw new XMLStreamException( "Element end not found." );
  }

  protected final StartElement findAny( final int _context ) throws XMLStreamException
  {
    while (this.xmlEventReader.hasNext()) {
      final XMLEvent event = this.xmlEventReader.nextEvent();
      if (event.isStartElement()) {
        final StartElement startElement = event.asStartElement();
        final QName name = startElement.getName();
        this.cursor.push( name );
        if (this.cursor.size() == _context + 1)
          return startElement;
      }
      else if (event.isEndElement()) {
        this.cursor.pop();
        if (this.cursor.size() < _context)
          return null;
      }
    }
    return null;
  }

  protected final StartElement find( final QName[] _path ) throws XMLStreamException
  {
    return find( _path, 0 );
  }

  protected final StartElement find( final QName _path, final int _context ) throws XMLStreamException
  {
    return find( new QName[]{ _path }, _context );
  }

  protected final int getContext()
  {
    return this.cursor.size();
  }

  protected final String getText() throws XMLStreamException
  {
    StringBuilder sb = null;
    XMLEvent event;
    while ((event = this.xmlEventReader.nextEvent()).isCharacters()) {
      if (sb == null)
        sb = new StringBuilder();
      sb.append( event.asCharacters().getData() );
    }
    if (event.isEndElement())
      this.cursor.pop();
    else
      throw new XMLStreamException( "Unexpected event type: " + event.getEventType() );
    return sb == null ? null : sb.toString();
  }

  public final void close() throws XMLStreamException
  {
    this.cursor.clear();
    this.xmlEventReader.close();
  }
}
TOP

Related Classes of org.formulacompiler.spreadsheet.internal.excel.xlsx.loader.XmlParser

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.