KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > xml > fastinfoset > dom > DOMDocumentParser


1 /*
2  * Fast Infoset ver. 0.1 software ("Software")
3  *
4  * Copyright, 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Software is licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License. You may
8  * obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations.
16  *
17  * Sun supports and benefits from the global community of open source
18  * developers, and thanks the community for its important contributions and
19  * open standards-based technology, which Sun has adopted into many of its
20  * products.
21  *
22  * Please note that portions of Software may be provided with notices and
23  * open source licenses from such communities and third parties that govern the
24  * use of those portions, and any licenses granted hereunder do not alter any
25  * rights and obligations you may have under such open source licenses,
26  * however, the disclaimer of warranty and limitation of liability provisions
27  * in this License will apply to all Software in this distribution.
28  *
29  * You acknowledge that the Software is not designed, licensed or intended
30  * for use in the design, construction, operation or maintenance of any nuclear
31  * facility.
32  *
33  * Apache License
34  * Version 2.0, January 2004
35  * http://www.apache.org/licenses/
36  *
37  */

38
39
40 package com.sun.xml.fastinfoset.dom;
41
42 import com.sun.xml.fastinfoset.Decoder;
43 import com.sun.xml.fastinfoset.DecoderStateTables;
44 import com.sun.xml.fastinfoset.EncodingConstants;
45 import com.sun.xml.fastinfoset.QualifiedName;
46 import com.sun.xml.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
47 import com.sun.xml.fastinfoset.util.CharArray;
48 import com.sun.xml.fastinfoset.util.CharArrayString;
49 import java.io.IOException JavaDoc;
50 import java.io.InputStream JavaDoc;
51 import org.jvnet.fastinfoset.EncodingAlgorithm;
52 import org.jvnet.fastinfoset.EncodingAlgorithmException;
53 import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
54 import org.jvnet.fastinfoset.FastInfosetException;
55 import org.w3c.dom.Attr JavaDoc;
56 import org.w3c.dom.Document JavaDoc;
57 import org.w3c.dom.Element JavaDoc;
58 import org.w3c.dom.Node JavaDoc;
59 import com.sun.xml.fastinfoset.CommonResourceBundle;
60
61
62 public class DOMDocumentParser extends Decoder {
63     protected Document JavaDoc _document;
64     
65     protected Node JavaDoc _currentNode;
66     
67     protected Element JavaDoc _currentElement;
68
69     protected Attr JavaDoc[] _namespaceAttributes = new Attr JavaDoc[16];
70
71     protected int _namespaceAttributesIndex;
72     
73     protected int[] _namespacePrefixes = new int[16];
74     
75     protected int _namespacePrefixesIndex;
76
77     public void parse(Document JavaDoc d, InputStream JavaDoc s) throws FastInfosetException, IOException JavaDoc {
78         _currentNode = _document = d;
79         _namespaceAttributesIndex = 0;
80                     
81         parse(s);
82     }
83     
84     protected final void parse(InputStream JavaDoc s) throws FastInfosetException, IOException JavaDoc {
85         setInputStream(s);
86         parse();
87     }
88     
89     protected void resetOnError() {
90         _namespacePrefixesIndex = 0;
91         
92         if (_v == null) {
93             _prefixTable.clearCompletely();
94         }
95     }
96     
97     protected final void parse() throws FastInfosetException, IOException JavaDoc {
98         try {
99             reset();
100             decodeHeader();
101             processDII();
102         } catch (RuntimeException JavaDoc e) {
103             resetOnError();
104             // Wrap runtime exception
105
throw new FastInfosetException(e);
106         } catch (FastInfosetException e) {
107             resetOnError();
108             throw e;
109         } catch (IOException JavaDoc e) {
110             resetOnError();
111             throw e;
112         }
113     }
114     
115     protected final void processDII() throws FastInfosetException, IOException JavaDoc {
116         _b = read();
117         if (_b > 0) {
118             processDIIOptionalProperties();
119         }
120         
121         // Decode one Document Type II, Comment IIs, PI IIs and one EII
122
boolean firstElementHasOccured = false;
123         boolean documentTypeDeclarationOccured = false;
124         while(!_terminate || !firstElementHasOccured) {
125             _b = read();
126             switch(DecoderStateTables.DII[_b]) {
127                 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
128                     processEII(_elementNameTable._array[_b], false);
129                     firstElementHasOccured = true;
130                     break;
131                 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
132                     processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true);
133                     firstElementHasOccured = true;
134                     break;
135                 case DecoderStateTables.EII_INDEX_MEDIUM:
136                     processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
137                     firstElementHasOccured = true;
138                     break;
139                 case DecoderStateTables.EII_INDEX_LARGE:
140                     processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
141                     firstElementHasOccured = true;
142                     break;
143                 case DecoderStateTables.EII_LITERAL:
144                 {
145                     final QualifiedName qn = processLiteralQualifiedName(
146                                 _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
147                     _elementNameTable.add(qn);
148                     processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
149                     firstElementHasOccured = true;
150                     break;
151                 }
152                 case DecoderStateTables.EII_NAMESPACES:
153                     processEIIWithNamespaces();
154                     firstElementHasOccured = true;
155                     break;
156                 case DecoderStateTables.DOCUMENT_TYPE_DECLARATION_II:
157                 {
158                     if (documentTypeDeclarationOccured) {
159                         throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.secondOccurenceOfDTDII"));
160                     }
161                     documentTypeDeclarationOccured = true;
162
163                     String JavaDoc system_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_SYSTEM_IDENTIFIER_FLAG) > 0)
164                         ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
165                     String JavaDoc public_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_PUBLIC_IDENTIFIER_FLAG) > 0)
166                         ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
167                     
168                     _b = read();
169                     while (_b == EncodingConstants.PROCESSING_INSTRUCTION) {
170                         switch(decodeNonIdentifyingStringOnFirstBit()) {
171                             case NISTRING_STRING:
172                                 final String JavaDoc data = new String JavaDoc(_charBuffer, 0, _charBufferLength);
173                                 if (_addToTable) {
174                                     _v.otherString.add(new CharArray(_charBuffer, 0, _charBufferLength, true));
175                                 }
176                                 break;
177                             case NISTRING_ENCODING_ALGORITHM:
178                                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm"));
179                             case NISTRING_INDEX:
180                                 break;
181                             case NISTRING_EMPTY_STRING:
182                                 break;
183                         }
184                         _b = read();
185                     }
186                     if ((_b & EncodingConstants.TERMINATOR) != EncodingConstants.TERMINATOR) {
187                         throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingInstructionIIsNotTerminatedCorrectly"));
188                     }
189                     if (_b == EncodingConstants.DOUBLE_TERMINATOR) {
190                         _terminate = true;
191                     }
192                     
193                     _notations.clear();
194                     _unparsedEntities.clear();
195                     /*
196                      * TODO
197                      * Report All events associated with DTD, PIs, notations etc
198                      */

199                     break;
200                 }
201                 case DecoderStateTables.COMMENT_II:
202                     processCommentII();
203                     break;
204                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
205                     processProcessingII();
206                     break;
207                 case DecoderStateTables.TERMINATOR_DOUBLE:
208                     _doubleTerminate = true;
209                 case DecoderStateTables.TERMINATOR_SINGLE:
210                     _terminate = true;
211                     break;
212                 default:
213                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII"));
214             }
215         }
216
217         // Decode any remaining Comment IIs, PI IIs
218
while(!_terminate) {
219             _b = read();
220             switch(DecoderStateTables.DII[_b]) {
221                 case DecoderStateTables.COMMENT_II:
222                     processCommentII();
223                     break;
224                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
225                     processProcessingII();
226                     break;
227                 case DecoderStateTables.TERMINATOR_DOUBLE:
228                     _doubleTerminate = true;
229                 case DecoderStateTables.TERMINATOR_SINGLE:
230                     _terminate = true;
231                     break;
232                 default:
233                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII"));
234             }
235         }
236
237     }
238
239     protected final void processDIIOptionalProperties() throws FastInfosetException, IOException JavaDoc {
240         // Optimize for the most common case
241
if (_b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) {
242             decodeInitialVocabulary();
243             return;
244         }
245         
246         if ((_b & EncodingConstants.DOCUMENT_ADDITIONAL_DATA_FLAG) > 0) {
247             decodeAdditionalData();
248             /*
249              * TODO
250              * how to report the additional data?
251              */

252         }
253         
254         if ((_b & EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) > 0) {
255             decodeInitialVocabulary();
256         }
257
258         if ((_b & EncodingConstants.DOCUMENT_NOTATIONS_FLAG) > 0) {
259             decodeNotations();
260             // TODO Report notations
261
}
262
263         if ((_b & EncodingConstants.DOCUMENT_UNPARSED_ENTITIES_FLAG) > 0) {
264             decodeUnparsedEntities();
265             // TODO Report unparsed entities
266
}
267
268         if ((_b & EncodingConstants.DOCUMENT_CHARACTER_ENCODING_SCHEME) > 0) {
269             String JavaDoc version = decodeCharacterEncodingScheme();
270             /*
271              * TODO
272              * how to report the character encoding scheme?
273              */

274         }
275         
276         if ((_b & EncodingConstants.DOCUMENT_STANDALONE_FLAG) > 0) {
277             boolean standalone = (read() > 0) ? true : false ;
278             /*
279              * TODO
280              * how to report the standalone flag?
281              */

282         }
283
284         if ((_b & EncodingConstants.DOCUMENT_VERSION_FLAG) > 0) {
285             String JavaDoc version = decodeVersion();
286             /*
287              * TODO
288              * how to report the document version?
289              */

290         }
291     }
292
293     protected final void processEII(QualifiedName name, boolean hasAttributes) throws FastInfosetException, IOException JavaDoc {
294         if (_prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
295             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qnameOfEIINotInScope"));
296         }
297         
298         final Node JavaDoc parentCurrentNode = _currentNode;
299         
300         _currentNode = _currentElement = createElement(name.namespaceName, name.qName, name.localName);
301         
302         if (_namespaceAttributesIndex > 0) {
303             for (int i = 0; i < _namespaceAttributesIndex; i++) {
304                 _currentElement.setAttributeNode(_namespaceAttributes[i]);
305                 _namespaceAttributes[i] = null;
306             }
307             _namespaceAttributesIndex = 0;
308         }
309         
310         if (hasAttributes) {
311             processAIIs();
312         }
313         
314         parentCurrentNode.appendChild(_currentElement);
315
316         while(!_terminate) {
317             _b = read();
318             switch(DecoderStateTables.EII[_b]) {
319                 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
320                     processEII(_elementNameTable._array[_b], false);
321                     break;
322                 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
323                     processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true);
324                     break;
325                 case DecoderStateTables.EII_INDEX_MEDIUM:
326                     processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
327                     break;
328                 case DecoderStateTables.EII_INDEX_LARGE:
329                     processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
330                     break;
331                 case DecoderStateTables.EII_LITERAL:
332                 {
333                     final QualifiedName qn = processLiteralQualifiedName(
334                                 _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
335                     _elementNameTable.add(qn);
336                     processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
337                     break;
338                 }
339                 case DecoderStateTables.EII_NAMESPACES:
340                     processEIIWithNamespaces();
341                     break;
342                 case DecoderStateTables.CII_UTF8_SMALL_LENGTH:
343                 {
344                     _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
345                         + 1;
346                     String JavaDoc v = decodeUtf8StringAsString();
347                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
348                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
349                     }
350                     
351                     _currentNode.appendChild(_document.createTextNode(v));
352                     break;
353                 }
354                 case DecoderStateTables.CII_UTF8_MEDIUM_LENGTH:
355                 {
356                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
357                     String JavaDoc v = decodeUtf8StringAsString();
358                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
359                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
360                     }
361                     
362                     _currentNode.appendChild(_document.createTextNode(v));
363                     break;
364                 }
365                 case DecoderStateTables.CII_UTF8_LARGE_LENGTH:
366                 {
367                     _octetBufferLength = (read() << 24) |
368                         (read() << 16) |
369                         (read() << 8) |
370                         read();
371                     _octetBufferLength += EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
372                     String JavaDoc v = decodeUtf8StringAsString();
373                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
374                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
375                     }
376                     
377                     _currentNode.appendChild(_document.createTextNode(v));
378                     break;
379                 }
380                 case DecoderStateTables.CII_UTF16_SMALL_LENGTH:
381                 {
382                     _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
383                         + 1;
384                     String JavaDoc v = decodeUtf16StringAsString();
385                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
386                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
387                     }
388                     
389                     _currentNode.appendChild(_document.createTextNode(v));
390                     break;
391                 }
392                 case DecoderStateTables.CII_UTF16_MEDIUM_LENGTH:
393                 {
394                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
395                     String JavaDoc v = decodeUtf16StringAsString();
396                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
397                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
398                     }
399                     
400                     _currentNode.appendChild(_document.createTextNode(v));
401                     break;
402                 }
403                 case DecoderStateTables.CII_UTF16_LARGE_LENGTH:
404                 {
405                     _octetBufferLength = (read() << 24) |
406                         (read() << 16) |
407                         (read() << 8) |
408                         read();
409                     _octetBufferLength += EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
410                     String JavaDoc v = decodeUtf16StringAsString();
411                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
412                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
413                     }
414                     
415                     _currentNode.appendChild(_document.createTextNode(v));
416                     break;
417                 }
418                 case DecoderStateTables.CII_RA:
419                 {
420                     final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0;
421                     
422                     // Decode resitricted alphabet integer
423
_identifier = (_b & 0x02) << 6;
424                     _b = read();
425                     _identifier |= (_b & 0xFC) >> 2;
426
427                     decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
428                     
429                     String JavaDoc v = decodeRestrictedAlphabetAsString();
430                     if (addToTable) {
431                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
432                     }
433                     
434                     _currentNode.appendChild(_document.createTextNode(v));
435                     break;
436                 }
437                 case DecoderStateTables.CII_EA:
438                 {
439                     if ((_b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
440                         throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.addToTableNotSupported"));
441                     }
442
443                     // Decode encoding algorithm integer
444
_identifier = (_b & 0x02) << 6;
445                     _b = read();
446                     _identifier |= (_b & 0xFC) >> 2;
447                     
448                     decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
449                     final String JavaDoc s = convertEncodingAlgorithmDataToCharacters(false);
450                     _currentNode.appendChild(_document.createTextNode(s));
451                     break;
452                 }
453                 case DecoderStateTables.CII_INDEX_SMALL:
454                 {
455                     final CharArray ca = _characterContentChunkTable.get(_b & EncodingConstants.INTEGER_4TH_BIT_SMALL_MASK);
456                     
457                     _currentNode.appendChild(_document.createTextNode(ca.toString()));
458                     break;
459                 }
460                 case DecoderStateTables.CII_INDEX_MEDIUM:
461                 {
462                     final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_MEDIUM_MASK) << 8) | read())
463                         + EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT;
464                     final String JavaDoc s = _characterContentChunkTable.get(index).toString();
465                     
466                     _currentNode.appendChild(_document.createTextNode(s));
467                     break;
468                 }
469                 case DecoderStateTables.CII_INDEX_LARGE:
470                 {
471                     int index = ((_b & EncodingConstants.INTEGER_4TH_BIT_LARGE_MASK) << 16) |
472                         (read() << 8) |
473                         read();
474                     index += EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT;
475                     final String JavaDoc s = _characterContentChunkTable.get(index).toString();
476                     
477                     _currentNode.appendChild(_document.createTextNode(s));
478                     break;
479                 }
480                 case DecoderStateTables.CII_INDEX_LARGE_LARGE:
481                 {
482                     int index = (read() << 16) |
483                         (read() << 8) |
484                         read();
485                     index += EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT;
486                     final String JavaDoc s = _characterContentChunkTable.get(index).toString();
487                     
488                     _currentNode.appendChild(_document.createTextNode(s));
489                     break;
490                 }
491                 case DecoderStateTables.COMMENT_II:
492                     processCommentII();
493                     break;
494                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
495                     processProcessingII();
496                     break;
497                 case DecoderStateTables.UNEXPANDED_ENTITY_REFERENCE_II:
498                 {
499                     String JavaDoc entity_reference_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
500                     
501                     String JavaDoc system_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_SYSTEM_IDENTIFIER_FLAG) > 0)
502                         ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
503                     String JavaDoc public_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_PUBLIC_IDENTIFIER_FLAG) > 0)
504                         ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
505
506                     // TODO create Node
507
break;
508                 }
509                 case DecoderStateTables.TERMINATOR_DOUBLE:
510                     _doubleTerminate = true;
511                 case DecoderStateTables.TERMINATOR_SINGLE:
512                     _terminate = true;
513                     break;
514                 default:
515                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEII"));
516             }
517         }
518
519         _terminate = _doubleTerminate;
520         _doubleTerminate = false;
521         
522         _currentNode = parentCurrentNode;
523     }
524
525     protected final void processEIIWithNamespaces() throws FastInfosetException, IOException JavaDoc {
526         final boolean hasAttributes = (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0;
527
528         if (++_prefixTable._declarationId == Integer.MAX_VALUE) {
529             _prefixTable.clearDeclarationIds();
530         }
531
532         String JavaDoc prefix;
533         Attr JavaDoc a = null;
534         final int start = _namespacePrefixesIndex;
535         int b = read();
536         while ((b & EncodingConstants.NAMESPACE_ATTRIBUTE_MASK) == EncodingConstants.NAMESPACE_ATTRIBUTE) {
537             if (_namespaceAttributesIndex == _namespaceAttributes.length) {
538                 final Attr JavaDoc[] newNamespaceAttributes = new Attr JavaDoc[_namespaceAttributesIndex * 3 / 2 + 1];
539                 System.arraycopy(_namespaceAttributes, 0, newNamespaceAttributes, 0, _namespaceAttributesIndex);
540                 _namespaceAttributes = newNamespaceAttributes;
541             }
542
543             if (_namespacePrefixesIndex == _namespacePrefixes.length) {
544                 final int[] namespaceAIIs = new int[_namespacePrefixesIndex * 3 / 2 + 1];
545                 System.arraycopy(_namespacePrefixes, 0, namespaceAIIs, 0, _namespacePrefixesIndex);
546                 _namespacePrefixes = namespaceAIIs;
547             }
548
549             
550             switch (b & EncodingConstants.NAMESPACE_ATTRIBUTE_PREFIX_NAME_MASK) {
551                 // no prefix, no namespace
552
// Undeclaration of default namespace
553
case 0:
554                     a = createAttribute(
555                             EncodingConstants.XMLNS_NAMESPACE_NAME,
556                             EncodingConstants.XMLNS_NAMESPACE_PREFIX,
557                             EncodingConstants.XMLNS_NAMESPACE_PREFIX);
558                     a.setValue ("");
559                     
560                     _prefixIndex = _namespaceNameIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
561                     break;
562                 // no prefix, namespace
563
// Declaration of default namespace
564
case 1:
565                     a = createAttribute(
566                             EncodingConstants.XMLNS_NAMESPACE_NAME,
567                             EncodingConstants.XMLNS_NAMESPACE_PREFIX,
568                             EncodingConstants.XMLNS_NAMESPACE_PREFIX);
569                     a.setValue (decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(false));
570                            
571                     _prefixIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
572                     break;
573                 // prefix, no namespace
574
// Undeclaration of namespace
575
case 2:
576                     prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(false);
577                     a = createAttribute(
578                             EncodingConstants.XMLNS_NAMESPACE_NAME,
579                             createQualifiedNameString(EncodingConstants.XMLNS_NAMESPACE_PREFIX_CHARS, prefix),
580                             prefix);
581                     a.setValue ("");
582                     
583                     _namespaceNameIndex = -1;
584                     _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
585                     break;
586                 // prefix, namespace
587
// Declaration of prefixed namespace
588
case 3:
589                     prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(true);
590                     a = createAttribute(
591                             EncodingConstants.XMLNS_NAMESPACE_NAME,
592                             createQualifiedNameString(EncodingConstants.XMLNS_NAMESPACE_PREFIX_CHARS, prefix),
593                             prefix);
594                     a.setValue (decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(true));
595                     
596                     _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
597                     break;
598             }
599                         
600             _prefixTable.pushScope(_prefixIndex, _namespaceNameIndex);
601             
602             _namespaceAttributes[_namespaceAttributesIndex++] = a;
603             
604             b = read();
605         }
606         if (b != EncodingConstants.TERMINATOR) {
607             throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.EIInamespaceNameNotTerminatedCorrectly"));
608         }
609         final int end = _namespacePrefixesIndex;
610
611         _b = read();
612         switch(DecoderStateTables.EII[_b]) {
613             case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
614                 processEII(_elementNameTable._array[_b], hasAttributes);
615                 break;
616             case DecoderStateTables.EII_INDEX_MEDIUM:
617                 processEII(decodeEIIIndexMedium(), hasAttributes);
618                 break;
619             case DecoderStateTables.EII_INDEX_LARGE:
620                 processEII(decodeEIIIndexLarge(), hasAttributes);
621                 break;
622             case DecoderStateTables.EII_LITERAL:
623             {
624                 final QualifiedName qn = processLiteralQualifiedName(
625                             _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
626                 _elementNameTable.add(qn);
627                 processEII(qn, hasAttributes);
628                 break;
629             }
630             default:
631                 throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEIIAfterAIIs"));
632         }
633         
634         for (int i = start; i < end; i++) {
635             _prefixTable.popScope(_namespacePrefixes[i]);
636         }
637         _namespacePrefixesIndex = start;
638         
639     }
640
641     protected final QualifiedName processLiteralQualifiedName(int state) throws FastInfosetException, IOException JavaDoc {
642         switch (state) {
643             // no prefix, no namespace
644
case 0:
645                 return new QualifiedName(
646                         null,
647                         null,
648                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
649                         -1,
650                         -1,
651                         _identifier,
652                         null);
653             // no prefix, namespace
654
case 1:
655                 return new QualifiedName(
656                         null,
657                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(false),
658                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
659                         -1,
660                         _namespaceNameIndex,
661                         _identifier,
662                         null);
663             // prefix, no namespace
664
case 2:
665                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameMissingNamespaceName"));
666             // prefix, namespace
667
case 3:
668                 return new QualifiedName(
669                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(true),
670                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(true),
671                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
672                         _prefixIndex,
673                         _namespaceNameIndex,
674                         _identifier,
675                         _charBuffer);
676             default:
677                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingEII"));
678         }
679     }
680
681     protected final void processAIIs() throws FastInfosetException, IOException JavaDoc {
682         QualifiedName name;
683         int b;
684         String JavaDoc value;
685
686         if (++_duplicateAttributeVerifier._currentIteration == Integer.MAX_VALUE) {
687             _duplicateAttributeVerifier.clear();
688         }
689         
690         do {
691             // AII qualified name
692
b = read();
693             switch (DecoderStateTables.AII[b]) {
694                 case DecoderStateTables.AII_INDEX_SMALL:
695                     name = _attributeNameTable._array[b];
696                     break;
697                 case DecoderStateTables.AII_INDEX_MEDIUM:
698                 {
699                     final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
700                         + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
701                     name = _attributeNameTable._array[i];
702                     break;
703                 }
704                 case DecoderStateTables.AII_INDEX_LARGE:
705                 {
706                     final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
707                         + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
708                     name = _attributeNameTable._array[i];
709                     break;
710                 }
711                 case DecoderStateTables.AII_LITERAL:
712                     name = processLiteralQualifiedName(
713                             b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
714                     name.createAttributeValues(_duplicateAttributeVerifier.MAP_SIZE);
715                     _attributeNameTable.add(name);
716                     break;
717                 case DecoderStateTables.AII_TERMINATOR_DOUBLE:
718                     _doubleTerminate = true;
719                 case DecoderStateTables.AII_TERMINATOR_SINGLE:
720                     _terminate = true;
721                     // AIIs have finished break out of loop
722
continue;
723                 default:
724                     throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.decodingAIIs"));
725             }
726
727             if (name.prefixIndex > 0 && _prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
728                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.AIIqNameNotInScope"));
729             }
730
731             _duplicateAttributeVerifier.checkForDuplicateAttribute(name.attributeHash, name.attributeId);
732
733             Attr JavaDoc a = createAttribute(
734                         name.namespaceName,
735                         name.qName,
736                         name.localName);
737                         
738             // [normalized value] of AII
739

740             b = read();
741             switch(DecoderStateTables.NISTRING[b]) {
742                 case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
743                 {
744                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
745                     _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
746                     value = decodeUtf8StringAsString();
747                     if (addToTable) {
748                         _attributeValueTable.add(value);
749                     }
750                     
751                     a.setValue(value);
752                     _currentElement.setAttributeNode(a);
753                     break;
754                 }
755                 case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
756                 {
757                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
758                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
759                     value = decodeUtf8StringAsString();
760                     if (addToTable) {
761                         _attributeValueTable.add(value);
762                     }
763                     
764                     a.setValue(value);
765                     _currentElement.setAttributeNode(a);
766                     break;
767                 }
768                 case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
769                 {
770                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
771                     final int length = (read() << 24) |
772                         (read() << 16) |
773                         (read() << 8) |
774                         read();
775                     _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
776                     value = decodeUtf8StringAsString();
777                     if (addToTable) {
778                         _attributeValueTable.add(value);
779                     }
780
781                     a.setValue(value);
782                     _currentElement.setAttributeNode(a);
783                     break;
784                 }
785                 case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH:
786                 {
787                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
788                     _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
789                     value = decodeUtf16StringAsString();
790                     if (addToTable) {
791                         _attributeValueTable.add(value);
792                     }
793                     
794                     a.setValue(value);
795                     _currentElement.setAttributeNode(a);
796                     break;
797                 }
798                 case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH:
799                 {
800                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
801                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
802                     value = decodeUtf16StringAsString();
803                     if (addToTable) {
804                         _attributeValueTable.add(value);
805                     }
806                     
807                     a.setValue(value);
808                     _currentElement.setAttributeNode(a);
809                     break;
810                 }
811                 case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH:
812                 {
813                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
814                     final int length = (read() << 24) |
815                         (read() << 16) |
816                         (read() << 8) |
817                         read();
818                     _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
819                     value = decodeUtf16StringAsString();
820                     if (addToTable) {
821                         _attributeValueTable.add(value);
822                     }
823
824                     a.setValue(value);
825                     _currentElement.setAttributeNode(a);
826                     break;
827                 }
828                 case DecoderStateTables.NISTRING_RA:
829                 {
830                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
831                     // Decode resitricted alphabet integer
832
_identifier = (b & 0x0F) << 4;
833                     b = read();
834                     _identifier |= (b & 0xF0) >> 4;
835                     
836                     decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
837                     
838                     value = decodeRestrictedAlphabetAsString();
839                     if (addToTable) {
840                         _attributeValueTable.add(value);
841                     }
842
843                     a.setValue(value);
844                     _currentElement.setAttributeNode(a);
845                     break;
846                 }
847                 case DecoderStateTables.NISTRING_EA:
848                 {
849                     if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
850                         throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.addToTableNotSupported"));
851                     }
852
853                     _identifier = (b & 0x0F) << 4;
854                     b = read();
855                     _identifier |= (b & 0xF0) >> 4;
856
857                     decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
858                     value = convertEncodingAlgorithmDataToCharacters(true);
859                     a.setValue(value);
860                     _currentElement.setAttributeNode(a);
861                     break;
862                 }
863                 case DecoderStateTables.NISTRING_INDEX_SMALL:
864                     value = _attributeValueTable._array[b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK];
865
866                     a.setValue(value);
867                     _currentElement.setAttributeNode(a);
868                     break;
869                 case DecoderStateTables.NISTRING_INDEX_MEDIUM:
870                 {
871                     final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
872                         + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
873                     value = _attributeValueTable._array[index];
874
875                     a.setValue(value);
876                     _currentElement.setAttributeNode(a);
877                     break;
878                 }
879                 case DecoderStateTables.NISTRING_INDEX_LARGE:
880                 {
881                     final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
882                         + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
883                     value = _attributeValueTable._array[index];
884
885                     a.setValue(value);
886                     _currentElement.setAttributeNode(a);
887                     break;
888                 }
889                 case DecoderStateTables.NISTRING_EMPTY:
890                     a.setValue("");
891                     _currentElement.setAttributeNode(a);
892                     break;
893                 default:
894                     throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.decodingAIIValue"));
895             }
896             
897         } while (!_terminate);
898  
899         // Reset duplication attribute verfifier
900
_duplicateAttributeVerifier._poolCurrent = _duplicateAttributeVerifier._poolHead;
901         
902         _terminate = _doubleTerminate;
903         _doubleTerminate = false;
904     }
905         
906     protected final void processCommentII() throws FastInfosetException, IOException JavaDoc {
907         switch(decodeNonIdentifyingStringOnFirstBit()) {
908             case NISTRING_STRING:
909             {
910                 final String JavaDoc s = new String JavaDoc(_charBuffer, 0, _charBufferLength);
911                 if (_addToTable) {
912                     _v.otherString.add(new CharArrayString(s, false));
913                 }
914                 
915                 _currentNode.appendChild(_document.createComment(s));
916                 break;
917             }
918             case NISTRING_ENCODING_ALGORITHM:
919                 throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.commentIIAlgorithmNotSupported"));
920             case NISTRING_INDEX:
921             {
922                 final String JavaDoc s = _v.otherString.get(_integer).toString();
923
924                 _currentNode.appendChild(_document.createComment(s));
925                 break;
926             }
927             case NISTRING_EMPTY_STRING:
928                 _currentNode.appendChild(_document.createComment(""));
929                 break;
930         }
931     }
932
933     protected final void processProcessingII() throws FastInfosetException, IOException JavaDoc {
934         final String JavaDoc target = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
935
936         switch(decodeNonIdentifyingStringOnFirstBit()) {
937             case NISTRING_STRING:
938             {
939                 final String JavaDoc data = new String JavaDoc(_charBuffer, 0, _charBufferLength);
940                 if (_addToTable) {
941                     _v.otherString.add(new CharArrayString(data, false));
942                 }
943
944                 _currentNode.appendChild (_document.createProcessingInstruction (target, data));
945                 break;
946             }
947             case NISTRING_ENCODING_ALGORITHM:
948                 throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm"));
949             case NISTRING_INDEX:
950             {
951                 final String JavaDoc data = _v.otherString.get(_integer).toString();
952                 
953                 _currentNode.appendChild (_document.createProcessingInstruction (target, data));
954                 break;
955             }
956             case NISTRING_EMPTY_STRING:
957                 _currentNode.appendChild (_document.createProcessingInstruction (target, ""));
958                 break;
959         }
960     }
961     
962     protected Element JavaDoc createElement(String JavaDoc namespaceName, String JavaDoc qName, String JavaDoc localName) {
963         return _document.createElementNS(namespaceName, qName);
964     }
965     
966     protected Attr JavaDoc createAttribute(String JavaDoc namespaceName, String JavaDoc qName, String JavaDoc localName) {
967         return _document.createAttributeNS(namespaceName, qName);
968     }
969
970     protected String JavaDoc convertEncodingAlgorithmDataToCharacters(boolean isAttributeValue) throws FastInfosetException, IOException JavaDoc {
971         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
972         if (_identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
973             Object JavaDoc array = BuiltInEncodingAlgorithmFactory.table[_identifier].
974                 decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
975             BuiltInEncodingAlgorithmFactory.table[_identifier].convertToCharacters(array, buffer);
976         } else if (_identifier == EncodingAlgorithmIndexes.CDATA) {
977             if (!isAttributeValue) {
978                 // Set back buffer position to start of encoded string
979
_octetBufferOffset -= _octetBufferLength;
980                 return decodeUtf8StringAsString();
981             }
982             throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.CDATAAlgorithmNotSupported"));
983         } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
984             final String JavaDoc URI = _v.encodingAlgorithm.get(_identifier - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START);
985             final EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
986             if (ea != null) {
987                 final Object JavaDoc data = ea.decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
988                 ea.convertToCharacters(data, buffer);
989             } else {
990                 throw new EncodingAlgorithmException(
991                         CommonResourceBundle.getInstance().getString("message.algorithmDataCannotBeReported"));
992             }
993         }
994         return buffer.toString();
995     }
996     
997 }
998
Popular Tags