blob: ab4ee8122d00f7b51201d0abf73a8d31eb51bf87 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
package org.apache.openoffice.ooxml.parser;
import java.io.InputStream;
import java.util.Vector;
import javax.xml.stream.Location;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.openoffice.ooxml.parser.action.ActionManager;
import org.apache.openoffice.ooxml.parser.attribute.AttributeProvider;
/** This is the actual parser (where OOXMLParser is the front end that handles
* parameters given to the main method).
*/
public class Parser
{
public Parser (
final StateMachine aMachine,
final InputStream aIn)
{
maMachine = aMachine;
maReader = GetStreamReader(aIn, "input");
mnElementCount = 0;
}
public void Parse ()
{
Location aLocation = null;
try
{
final AttributeProvider aAttributeProvider = new AttributeProvider(maReader);
while (maReader.hasNext())
{
aLocation = maReader.getLocation();
final int nCode = maReader.next();
switch(nCode)
{
case XMLStreamReader.START_ELEMENT:
++mnElementCount;
if (maMachine.IsInSkipState())
{
if (Log.Dbg != null)
Log.Dbg.printf("is skip state -> starting to skip\n");
Skip();
}
else if ( ! maMachine.ProcessStartElement(
maReader.getNamespaceURI(),
maReader.getLocalName(),
aLocation,
maReader.getLocation(),
aAttributeProvider))
{
if (Log.Dbg != null)
Log.Dbg.printf("starting to skip to recover from error\n");
Skip();
}
break;
case XMLStreamReader.END_ELEMENT:
maMachine.ProcessEndElement(
maReader.getNamespaceURI(),
maReader.getLocalName(),
aLocation,
maReader.getLocation());
break;
case XMLStreamReader.CHARACTERS:
maMachine.ProcessCharacters(
maReader.getText(),
aLocation,
maReader.getLocation());
break;
case XMLStreamReader.END_DOCUMENT:
break;
default:
Log.Err.printf("can't handle XML event of type %d\n", nCode);
}
}
maReader.close();
}
catch (final XMLStreamException aException)
{
aException.printStackTrace();
}
catch (final Exception aException)
{
throw new ParseException(
aException,
aLocation);
}
}
public int GetElementCount ()
{
return mnElementCount;
}
private void Skip ()
{
if (Log.Dbg != null)
{
Log.Dbg.printf("starting to skip on %s at L%dC%d\n",
maReader.getLocalName(),
maReader.getLocation().getLineNumber(),
maReader.getLocation().getColumnNumber());
Log.Dbg.IncreaseIndentation();
}
// We are called when processing a start element. This means that we are
// already at relative depth 1.
int nRelativeDepth = 1;
try
{
while (maReader.hasNext())
{
final int nCode = maReader.next();
switch (nCode)
{
case XMLStreamReader.START_ELEMENT:
++nRelativeDepth;
++mnElementCount;
if (Log.Dbg != null)
{
Log.Dbg.printf("skipping start element %s\n", maReader.getLocalName());
Log.Dbg.IncreaseIndentation();
}
break;
case XMLStreamReader.END_ELEMENT:
--nRelativeDepth;
if (Log.Dbg != null)
Log.Dbg.DecreaseIndentation();
if (nRelativeDepth <= 0)
{
if (Log.Dbg != null)
Log.Dbg.printf("leaving skip mode on %s\n", maReader.getLocalName());
return;
}
break;
case XMLStreamReader.END_DOCUMENT:
throw new RuntimeException("saw end of document while skipping elements\n");
case XMLStreamReader.CHARACTERS:
SkipText(maReader.getText());
break;
default:
if (Log.Dbg != null)
Log.Dbg.printf("%s\n", nCode);
break;
}
}
}
catch (final XMLStreamException aException)
{
aException.printStackTrace();
}
}
private void SkipText (final String sText)
{
if (Log.Dbg != null)
Log.Dbg.printf("skipping text [%s]\n", sText.replace("\n", "\\n"));
}
private XMLStreamReader GetStreamReader (
final InputStream aIn,
final String sDescription)
{
if (aIn == null)
return null;
try
{
final XMLInputFactory aFactory = (XMLInputFactory)XMLInputFactory.newInstance();
aFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
aFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
aFactory.setProperty(XMLInputFactory.IS_COALESCING, false);
return (XMLStreamReader)aFactory.createXMLStreamReader(
sDescription,
aIn);
}
catch (final Exception aException)
{
aException.printStackTrace();
return null;
}
}
public ActionManager GetActionManager()
{
return maMachine.GetActionManager();
}
private final XMLStreamReader maReader;
private final StateMachine maMachine;
private int mnElementCount;
}