xref: /trunk/main/ooxml/source/framework/JavaOOXMLParser/src/org/apache/openoffice/ooxml/parser/Parser.java (revision 5226f0b8dea4ef117ddd2bc4948a8601d0ac403b)
1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements.  See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership.  The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License.  You may obtain a copy of the License at
10 *
11 *   http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied.  See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21 
22 package org.apache.openoffice.ooxml.parser;
23 
24 import java.io.InputStream;
25 
26 import javax.xml.stream.Location;
27 import javax.xml.stream.XMLInputFactory;
28 import javax.xml.stream.XMLStreamException;
29 import javax.xml.stream.XMLStreamReader;
30 
31 import org.apache.openoffice.ooxml.parser.action.ActionManager;
32 import org.apache.openoffice.ooxml.parser.attribute.AttributeProvider;
33 
34 /** This is the actual parser (where OOXMLParser is the front end that handles
35  *  parameters given to the main method).
36  */
37 public class Parser
38 {
Parser( final StateMachine aMachine, final InputStream aIn)39     public Parser (
40         final StateMachine aMachine,
41         final InputStream aIn)
42     {
43         maMachine = aMachine;
44         maReader = GetStreamReader(aIn, "input");
45         mnElementCount = 0;
46     }
47 
48 
49 
50 
Parse()51     public void Parse ()
52     {
53         Location aLocation = null;
54         try
55         {
56             final AttributeProvider aAttributeProvider = new AttributeProvider(maReader);
57             while (maReader.hasNext())
58             {
59                 aLocation = maReader.getLocation();
60                 final int nCode = maReader.next();
61                 switch(nCode)
62                 {
63                     case XMLStreamReader.START_ELEMENT:
64                         ++mnElementCount;
65                         if (maMachine.IsInSkipState())
66                         {
67                             if (Log.Dbg != null)
68                                 Log.Dbg.printf("is skip state -> starting to skip\n");
69                             Skip();
70                         }
71                         else if ( ! maMachine.ProcessStartElement(
72                             maReader.getNamespaceURI(),
73                             maReader.getLocalName(),
74                             aLocation,
75                             maReader.getLocation(),
76                             aAttributeProvider))
77                         {
78                             if (Log.Dbg != null)
79                                 Log.Dbg.printf("starting to skip to recover from error\n");
80                             Skip();
81                         }
82                         break;
83 
84                     case XMLStreamReader.END_ELEMENT:
85                         maMachine.ProcessEndElement(
86                             maReader.getNamespaceURI(),
87                             maReader.getLocalName(),
88                             aLocation,
89                             maReader.getLocation());
90                         break;
91 
92                     case XMLStreamReader.CHARACTERS:
93                         maMachine.ProcessCharacters(
94                             maReader.getText(),
95                             aLocation,
96                             maReader.getLocation());
97                         break;
98 
99                     case XMLStreamReader.END_DOCUMENT:
100                         break;
101 
102                     default:
103                         Log.Err.printf("can't handle XML event of type %d\n", nCode);
104                 }
105             }
106 
107             maReader.close();
108         }
109         catch (final XMLStreamException aException)
110         {
111             aException.printStackTrace();
112         }
113         catch (final Exception aException)
114         {
115             throw new ParseException(
116                 aException,
117                 aLocation);
118         }
119     }
120 
121 
122 
123 
124 
125 
GetElementCount()126     public int GetElementCount ()
127     {
128         return mnElementCount;
129     }
130 
131 
132 
133 
Skip()134     private void Skip ()
135     {
136         if (Log.Dbg != null)
137         {
138             Log.Dbg.printf("starting to skip on %s at L%dC%d\n",
139                 maReader.getLocalName(),
140                 maReader.getLocation().getLineNumber(),
141                 maReader.getLocation().getColumnNumber());
142             Log.Dbg.IncreaseIndentation();
143         }
144 
145         // We are called when processing a start element.  This means that we are
146         // already at relative depth 1.
147         int nRelativeDepth = 1;
148         try
149         {
150             while (maReader.hasNext())
151             {
152                 final int nCode = maReader.next();
153                 switch (nCode)
154                 {
155                     case XMLStreamReader.START_ELEMENT:
156                         ++nRelativeDepth;
157                         ++mnElementCount;
158                         if (Log.Dbg != null)
159                         {
160                             Log.Dbg.printf("skipping start element %s\n", maReader.getLocalName());
161                             Log.Dbg.IncreaseIndentation();
162                         }
163                         break;
164 
165                     case XMLStreamReader.END_ELEMENT:
166                         --nRelativeDepth;
167                         if (Log.Dbg != null)
168                             Log.Dbg.DecreaseIndentation();
169                         if (nRelativeDepth <= 0)
170                         {
171                             if (Log.Dbg != null)
172                                 Log.Dbg.printf("leaving skip mode on %s\n", maReader.getLocalName());
173                             return;
174                         }
175                         break;
176 
177                     case XMLStreamReader.END_DOCUMENT:
178                         throw new RuntimeException("saw end of document while skipping elements\n");
179 
180                     case XMLStreamReader.CHARACTERS:
181                         SkipText(maReader.getText());
182                         break;
183 
184                     default:
185                         if (Log.Dbg != null)
186                             Log.Dbg.printf("%s\n",  nCode);
187                         break;
188                 }
189             }
190         }
191         catch (final XMLStreamException aException)
192         {
193             aException.printStackTrace();
194         }
195     }
196 
197 
198 
199 
SkipText(final String sText)200     private void SkipText (final String sText)
201     {
202         if (Log.Dbg != null)
203             Log.Dbg.printf("skipping text [%s]\n", sText.replace("\n", "\\n"));
204     }
205 
206 
207 
208 
GetStreamReader( final InputStream aIn, final String sDescription)209     private XMLStreamReader GetStreamReader (
210         final InputStream aIn,
211         final String sDescription)
212     {
213         if (aIn == null)
214             return null;
215 
216         try
217         {
218             final XMLInputFactory aFactory = (XMLInputFactory)XMLInputFactory.newInstance();
219             aFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
220             aFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
221             aFactory.setProperty(XMLInputFactory.IS_COALESCING, false);
222 
223             return (XMLStreamReader)aFactory.createXMLStreamReader(
224                 sDescription,
225                 aIn);
226         }
227         catch (final Exception aException)
228         {
229             aException.printStackTrace();
230             return null;
231         }
232     }
233 
234 
235 
236 
GetActionManager()237     public ActionManager GetActionManager()
238     {
239         return maMachine.GetActionManager();
240     }
241 
242 
243 
244 
245     private final XMLStreamReader maReader;
246     private final StateMachine maMachine;
247     private int mnElementCount;
248 }
249