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 import java.util.Vector;
26 
27 import javax.xml.stream.Location;
28 import javax.xml.stream.XMLInputFactory;
29 import javax.xml.stream.XMLStreamException;
30 import javax.xml.stream.XMLStreamReader;
31 
32 import org.apache.openoffice.ooxml.parser.action.ActionManager;
33 import org.apache.openoffice.ooxml.parser.attribute.AttributeProvider;
34 
35 /** This is the actual parser (where OOXMLParser is the front end that handles
36  *  parameters given to the main method).
37  */
38 public class Parser
39 {
Parser( final StateMachine aMachine, final InputStream aIn)40     public Parser (
41         final StateMachine aMachine,
42         final InputStream aIn)
43     {
44         maMachine = aMachine;
45         maReader = GetStreamReader(aIn, "input");
46         mnElementCount = 0;
47     }
48 
49 
50 
51 
Parse()52     public void Parse ()
53     {
54         Location aLocation = null;
55         try
56         {
57             final AttributeProvider aAttributeProvider = new AttributeProvider(maReader);
58             while (maReader.hasNext())
59             {
60                 aLocation = maReader.getLocation();
61                 final int nCode = maReader.next();
62                 switch(nCode)
63                 {
64                     case XMLStreamReader.START_ELEMENT:
65                         ++mnElementCount;
66                         if (maMachine.IsInSkipState())
67                         {
68                             if (Log.Dbg != null)
69                                 Log.Dbg.printf("is skip state -> starting to skip\n");
70                             Skip();
71                         }
72                         else if ( ! maMachine.ProcessStartElement(
73                             maReader.getNamespaceURI(),
74                             maReader.getLocalName(),
75                             aLocation,
76                             maReader.getLocation(),
77                             aAttributeProvider))
78                         {
79                             if (Log.Dbg != null)
80                                 Log.Dbg.printf("starting to skip to recover from error\n");
81                             Skip();
82                         }
83                         break;
84 
85                     case XMLStreamReader.END_ELEMENT:
86                         maMachine.ProcessEndElement(
87                             maReader.getNamespaceURI(),
88                             maReader.getLocalName(),
89                             aLocation,
90                             maReader.getLocation());
91                         break;
92 
93                     case XMLStreamReader.CHARACTERS:
94                         maMachine.ProcessCharacters(
95                             maReader.getText(),
96                             aLocation,
97                             maReader.getLocation());
98                         break;
99 
100                     case XMLStreamReader.END_DOCUMENT:
101                         break;
102 
103                     default:
104                         Log.Err.printf("can't handle XML event of type %d\n", nCode);
105                 }
106             }
107 
108             maReader.close();
109         }
110         catch (final XMLStreamException aException)
111         {
112             aException.printStackTrace();
113         }
114         catch (final Exception aException)
115         {
116             throw new ParseException(
117                 aException,
118                 aLocation);
119         }
120     }
121 
122 
123 
124 
125 
126 
GetElementCount()127     public int GetElementCount ()
128     {
129         return mnElementCount;
130     }
131 
132 
133 
134 
Skip()135     private void Skip ()
136     {
137         if (Log.Dbg != null)
138         {
139             Log.Dbg.printf("starting to skip on %s at L%dC%d\n",
140                 maReader.getLocalName(),
141                 maReader.getLocation().getLineNumber(),
142                 maReader.getLocation().getColumnNumber());
143             Log.Dbg.IncreaseIndentation();
144         }
145 
146         // We are called when processing a start element.  This means that we are
147         // already at relative depth 1.
148         int nRelativeDepth = 1;
149         try
150         {
151             while (maReader.hasNext())
152             {
153                 final int nCode = maReader.next();
154                 switch (nCode)
155                 {
156                     case XMLStreamReader.START_ELEMENT:
157                         ++nRelativeDepth;
158                         ++mnElementCount;
159                         if (Log.Dbg != null)
160                         {
161                             Log.Dbg.printf("skipping start element %s\n", maReader.getLocalName());
162                             Log.Dbg.IncreaseIndentation();
163                         }
164                         break;
165 
166                     case XMLStreamReader.END_ELEMENT:
167                         --nRelativeDepth;
168                         if (Log.Dbg != null)
169                             Log.Dbg.DecreaseIndentation();
170                         if (nRelativeDepth <= 0)
171                         {
172                             if (Log.Dbg != null)
173                                 Log.Dbg.printf("leaving skip mode on %s\n", maReader.getLocalName());
174                             return;
175                         }
176                         break;
177 
178                     case XMLStreamReader.END_DOCUMENT:
179                         throw new RuntimeException("saw end of document while skipping elements\n");
180 
181                     case XMLStreamReader.CHARACTERS:
182                         SkipText(maReader.getText());
183                         break;
184 
185                     default:
186                         if (Log.Dbg != null)
187                             Log.Dbg.printf("%s\n",  nCode);
188                         break;
189                 }
190             }
191         }
192         catch (final XMLStreamException aException)
193         {
194             aException.printStackTrace();
195         }
196     }
197 
198 
199 
200 
SkipText(final String sText)201     private void SkipText (final String sText)
202     {
203         if (Log.Dbg != null)
204             Log.Dbg.printf("skipping text [%s]\n", sText.replace("\n", "\\n"));
205     }
206 
207 
208 
209 
GetStreamReader( final InputStream aIn, final String sDescription)210     private XMLStreamReader GetStreamReader (
211         final InputStream aIn,
212         final String sDescription)
213     {
214         if (aIn == null)
215             return null;
216 
217         try
218         {
219             final XMLInputFactory aFactory = (XMLInputFactory)XMLInputFactory.newInstance();
220             aFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
221             aFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
222             aFactory.setProperty(XMLInputFactory.IS_COALESCING, false);
223 
224             return (XMLStreamReader)aFactory.createXMLStreamReader(
225                 sDescription,
226                 aIn);
227         }
228         catch (final Exception aException)
229         {
230             aException.printStackTrace();
231             return null;
232         }
233     }
234 
235 
236 
237 
GetActionManager()238     public ActionManager GetActionManager()
239     {
240         return maMachine.GetActionManager();
241     }
242 
243 
244 
245 
246     private final XMLStreamReader maReader;
247     private final StateMachine maMachine;
248     private int mnElementCount;
249 }
250