Thu, 31 Aug 2017 15:18:52 +0800
merge
1 /*
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.xml.internal.stream.buffer.sax;
28 import com.sun.xml.internal.stream.buffer.AbstractProcessor;
29 import com.sun.xml.internal.stream.buffer.AttributesHolder;
30 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
31 import org.xml.sax.ContentHandler;
32 import org.xml.sax.DTDHandler;
33 import org.xml.sax.EntityResolver;
34 import org.xml.sax.ErrorHandler;
35 import org.xml.sax.InputSource;
36 import org.xml.sax.SAXException;
37 import org.xml.sax.SAXNotRecognizedException;
38 import org.xml.sax.SAXNotSupportedException;
39 import org.xml.sax.SAXParseException;
40 import org.xml.sax.XMLReader;
41 import org.xml.sax.ext.LexicalHandler;
42 import org.xml.sax.helpers.LocatorImpl;
44 import javax.xml.XMLConstants;
45 import java.io.IOException;
46 import java.util.Collections;
47 import java.util.HashSet;
48 import java.util.Map;
49 import java.util.Set;
51 /**
52 * A processor of a {@link XMLStreamBuffer} that that reads the XML infoset as
53 * {@link XMLReader}.
54 */
55 public class SAXBufferProcessor extends AbstractProcessor implements XMLReader {
56 /**
57 * Reference to entity resolver.
58 */
59 protected EntityResolver _entityResolver = DEFAULT_LEXICAL_HANDLER;
61 /**
62 * Reference to dtd handler.
63 */
64 protected DTDHandler _dtdHandler = DEFAULT_LEXICAL_HANDLER;
66 /**
67 * Reference to content handler.
68 */
69 protected ContentHandler _contentHandler = DEFAULT_LEXICAL_HANDLER;
71 /**
72 * Reference to error handler.
73 */
74 protected ErrorHandler _errorHandler = DEFAULT_LEXICAL_HANDLER;
76 /**
77 * Reference to lexical handler.
78 */
79 protected LexicalHandler _lexicalHandler = DEFAULT_LEXICAL_HANDLER;
81 /**
82 * SAX Namespace attributes features
83 */
84 protected boolean _namespacePrefixesFeature = false;
86 protected AttributesHolder _attributes = new AttributesHolder();
88 protected String[] _namespacePrefixes = new String[16];
89 protected int _namespacePrefixesIndex;
91 protected int[] _namespaceAttributesStartingStack = new int[16];
92 protected int[] _namespaceAttributesStack = new int[16];
93 protected int _namespaceAttributesStackIndex;
95 public SAXBufferProcessor() {
96 }
98 /**
99 * @deprecated
100 * Use {@link #SAXBufferProcessor(XMLStreamBuffer, boolean)}
101 */
102 public SAXBufferProcessor(XMLStreamBuffer buffer) {
103 setXMLStreamBuffer(buffer);
104 }
106 /**
107 * @param produceFragmentEvent
108 * True to generate fragment SAX events without start/endDocument.
109 * False to generate a full document SAX events.
110 */
111 public SAXBufferProcessor(XMLStreamBuffer buffer, boolean produceFragmentEvent) {
112 setXMLStreamBuffer(buffer,produceFragmentEvent);
113 }
115 public boolean getFeature(String name)
116 throws SAXNotRecognizedException, SAXNotSupportedException {
117 if (name.equals(Features.NAMESPACES_FEATURE)) {
118 return true;
119 } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
120 return _namespacePrefixesFeature;
121 } else if (name.equals(Features.EXTERNAL_GENERAL_ENTITIES)) {
122 return true;
123 } else if (name.equals(Features.EXTERNAL_PARAMETER_ENTITIES)) {
124 return true;
125 } else if (name.equals(Features.STRING_INTERNING_FEATURE)) {
126 return _stringInterningFeature;
127 } else {
128 throw new SAXNotRecognizedException(
129 "Feature not supported: " + name);
130 }
131 }
133 public void setFeature(String name, boolean value)
134 throws SAXNotRecognizedException, SAXNotSupportedException {
135 if (name.equals(Features.NAMESPACES_FEATURE)) {
136 if (!value) {
137 throw new SAXNotSupportedException(name + ":" + value);
138 }
139 } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
140 _namespacePrefixesFeature = value;
141 } else if (name.equals(Features.EXTERNAL_GENERAL_ENTITIES)) {
142 // ignore
143 } else if (name.equals(Features.EXTERNAL_PARAMETER_ENTITIES)) {
144 // ignore
145 } else if (name.equals(Features.STRING_INTERNING_FEATURE)) {
146 if (value != _stringInterningFeature) {
147 throw new SAXNotSupportedException(name + ":" + value);
148 }
149 } else {
150 throw new SAXNotRecognizedException(
151 "Feature not supported: " + name);
152 }
153 }
155 public Object getProperty(String name)
156 throws SAXNotRecognizedException, SAXNotSupportedException {
157 if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
158 return getLexicalHandler();
159 } else {
160 throw new SAXNotRecognizedException("Property not recognized: " + name);
161 }
162 }
164 public void setProperty(String name, Object value)
165 throws SAXNotRecognizedException, SAXNotSupportedException {
166 if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
167 if (value instanceof LexicalHandler) {
168 setLexicalHandler((LexicalHandler)value);
169 } else {
170 throw new SAXNotSupportedException(Properties.LEXICAL_HANDLER_PROPERTY);
171 }
172 } else {
173 throw new SAXNotRecognizedException("Property not recognized: " + name);
174 }
175 }
177 public void setEntityResolver(EntityResolver resolver) {
178 _entityResolver = resolver;
179 }
181 public EntityResolver getEntityResolver() {
182 return _entityResolver;
183 }
185 public void setDTDHandler(DTDHandler handler) {
186 _dtdHandler = handler;
187 }
189 public DTDHandler getDTDHandler() {
190 return _dtdHandler;
191 }
193 public void setContentHandler(ContentHandler handler) {
194 _contentHandler = handler;
195 }
197 public ContentHandler getContentHandler() {
198 return _contentHandler;
199 }
201 public void setErrorHandler(ErrorHandler handler) {
202 _errorHandler = handler;
203 }
205 public ErrorHandler getErrorHandler() {
206 return _errorHandler;
207 }
209 public void setLexicalHandler(LexicalHandler handler) {
210 _lexicalHandler = handler;
211 }
213 public LexicalHandler getLexicalHandler() {
214 return _lexicalHandler;
215 }
217 public void parse(InputSource input) throws IOException, SAXException {
218 // InputSource is ignored
219 process();
220 }
222 public void parse(String systemId) throws IOException, SAXException {
223 // systemId is ignored
224 process();
225 }
227 /**
228 * Short-hand for {@link #setXMLStreamBuffer(XMLStreamBuffer)} then {@link #process()}.
229 *
230 * @deprecated
231 * Use {@link #process(XMLStreamBuffer, boolean)}
232 */
233 public final void process(XMLStreamBuffer buffer) throws SAXException {
234 setXMLStreamBuffer(buffer);
235 process();
236 }
238 /**
239 * Short-hand for {@link #setXMLStreamBuffer(XMLStreamBuffer,boolean)} then {@link #process()}.
240 *
241 * @param produceFragmentEvent
242 * True to generate fragment SAX events without start/endDocument.
243 * False to generate a full document SAX events.
244 */
245 public final void process(XMLStreamBuffer buffer, boolean produceFragmentEvent) throws SAXException {
246 setXMLStreamBuffer(buffer);
247 process();
248 }
250 /**
251 * Resets the parser to read from the beginning of the given {@link XMLStreamBuffer}.
252 *
253 * @deprecated
254 * Use {@link #setXMLStreamBuffer(XMLStreamBuffer, boolean)}.
255 */
256 public void setXMLStreamBuffer(XMLStreamBuffer buffer) {
257 setBuffer(buffer);
258 }
260 /**
261 * Resets the parser to read from the beginning of the given {@link XMLStreamBuffer}.
262 *
263 * @param produceFragmentEvent
264 * True to generate fragment SAX events without start/endDocument.
265 * False to generate a full document SAX events.
266 */
267 public void setXMLStreamBuffer(XMLStreamBuffer buffer, boolean produceFragmentEvent) {
268 if(!produceFragmentEvent && _treeCount>1)
269 throw new IllegalStateException("Can't write a forest to a full XML infoset");
270 setBuffer(buffer,produceFragmentEvent);
271 }
273 /**
274 * Parse the sub-tree (or a whole document) that {@link XMLStreamBuffer}
275 * points to, and sends events to handlers.
276 *
277 * <p>
278 * TODO:
279 * We probably need two modes for a sub-tree event generation. One for
280 * firing a sub-tree as if it's a whole document (in which case start/endDocument
281 * and appropriate additional namespace bindings are necessary), and the other
282 * mode for firing a subtree as a subtree, like it does today.
283 * A stream buffer SAX feature could be used to specify this.
284 *
285 * @throws SAXException
286 * Follow the same semantics as {@link XMLReader#parse(InputSource)}.
287 */
288 public final void process() throws SAXException {
289 if(!_fragmentMode) {
290 LocatorImpl nullLocator = new LocatorImpl();
291 nullLocator.setSystemId(_buffer.getSystemId());
292 nullLocator.setLineNumber(-1);
293 nullLocator.setColumnNumber(-1);
294 _contentHandler.setDocumentLocator(nullLocator);
296 _contentHandler.startDocument();
297 // TODO: if we are writing a fragment stream buffer as a full XML document,
298 // we need to declare in-scope namespaces as if they are on the root element.
299 }
301 while (_treeCount>0) {
302 final int item = readEiiState();
303 switch(item) {
304 case STATE_DOCUMENT:
305 processDocument();
306 _treeCount--;
307 break;
308 case STATE_END:
309 // Empty buffer
310 return;
311 case STATE_ELEMENT_U_LN_QN:
312 processElement(readStructureString(), readStructureString(), readStructureString(), isInscope());
313 _treeCount--;
314 break;
315 case STATE_ELEMENT_P_U_LN:
316 {
317 final String prefix = readStructureString();
318 final String uri = readStructureString();
319 final String localName = readStructureString();
320 processElement(uri, localName, getQName(prefix, localName),isInscope());
321 _treeCount--;
322 break;
323 }
324 case STATE_ELEMENT_U_LN: {
325 final String uri = readStructureString();
326 final String localName = readStructureString();
327 processElement(uri, localName, localName,isInscope());
328 _treeCount--;
329 break;
330 }
331 case STATE_ELEMENT_LN:
332 {
333 final String localName = readStructureString();
334 processElement("", localName, localName,isInscope());
335 _treeCount--;
336 break;
337 }
338 case STATE_COMMENT_AS_CHAR_ARRAY_SMALL:
339 processCommentAsCharArraySmall();
340 break;
341 case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM:
342 processCommentAsCharArrayMedium();
343 break;
344 case STATE_COMMENT_AS_CHAR_ARRAY_COPY:
345 processCommentAsCharArrayCopy();
346 break;
347 case STATE_COMMENT_AS_STRING:
348 processComment(readContentString());
349 break;
350 case STATE_PROCESSING_INSTRUCTION:
351 processProcessingInstruction(readStructureString(), readStructureString());
352 break;
353 default:
354 throw reportFatalError("Illegal state for DIIs: "+item);
355 }
356 }
358 if(!_fragmentMode)
359 _contentHandler.endDocument();
360 }
362 private void processCommentAsCharArraySmall() throws SAXException {
363 final int length = readStructure();
364 final int start = readContentCharactersBuffer(length);
365 processComment(_contentCharactersBuffer, start, length);
366 }
368 /**
369 * Report a fatal error and abort.
370 *
371 * This is necessary to follow the SAX semantics of error handling.
372 */
373 private SAXParseException reportFatalError(String msg) throws SAXException {
374 SAXParseException spe = new SAXParseException(msg, null);
375 if(_errorHandler!=null)
376 _errorHandler.fatalError(spe);
377 return spe;
378 }
380 private boolean isInscope() {
381 return _buffer.getInscopeNamespaces().size() > 0;
382 }
384 private void processDocument() throws SAXException {
385 while(true) {
386 int item = readEiiState();
387 switch(item) {
388 case STATE_ELEMENT_U_LN_QN:
389 processElement(readStructureString(), readStructureString(), readStructureString(),isInscope());
390 break;
391 case STATE_ELEMENT_P_U_LN:
392 {
393 final String prefix = readStructureString();
394 final String uri = readStructureString();
395 final String localName = readStructureString();
396 processElement(uri, localName, getQName(prefix, localName),isInscope());
397 break;
398 }
399 case STATE_ELEMENT_U_LN: {
400 final String uri = readStructureString();
401 final String localName = readStructureString();
402 processElement(uri, localName, localName,isInscope());
403 break;
404 }
405 case STATE_ELEMENT_LN:
406 {
407 final String localName = readStructureString();
408 processElement("", localName, localName,isInscope());
409 break;
410 }
411 case STATE_COMMENT_AS_CHAR_ARRAY_SMALL:
412 processCommentAsCharArraySmall();
413 break;
414 case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM:
415 processCommentAsCharArrayMedium();
416 break;
417 case STATE_COMMENT_AS_CHAR_ARRAY_COPY:
418 processCommentAsCharArrayCopy();
419 break;
420 case STATE_COMMENT_AS_STRING:
421 processComment(readContentString());
422 break;
423 case STATE_PROCESSING_INSTRUCTION:
424 processProcessingInstruction(readStructureString(), readStructureString());
425 break;
426 case STATE_END:
427 return;
428 default:
429 throw reportFatalError("Illegal state for child of DII: "+item);
430 }
431 }
432 }
434 protected void processElement(String uri, String localName, String qName, boolean inscope) throws SAXException {
435 boolean hasAttributes = false;
436 boolean hasNamespaceAttributes = false;
437 int item = peekStructure();
438 Set<String> prefixSet = inscope ? new HashSet<String>() : Collections.<String>emptySet();
439 if ((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE) {
440 cacheNamespacePrefixStartingIndex();
441 hasNamespaceAttributes = true;
442 item = processNamespaceAttributes(item, inscope, prefixSet);
443 }
444 if (inscope) {
445 readInscopeNamespaces(prefixSet);
446 }
448 if ((item & TYPE_MASK) == T_ATTRIBUTE) {
449 hasAttributes = true;
450 processAttributes(item);
451 }
453 _contentHandler.startElement(uri, localName, qName, _attributes);
455 if (hasAttributes) {
456 _attributes.clear();
457 }
459 do {
460 item = readEiiState();
461 switch(item) {
462 case STATE_ELEMENT_U_LN_QN:
463 processElement(readStructureString(), readStructureString(), readStructureString(), false);
464 break;
465 case STATE_ELEMENT_P_U_LN:
466 {
467 final String p = readStructureString();
468 final String u = readStructureString();
469 final String ln = readStructureString();
470 processElement(u, ln, getQName(p, ln),false);
471 break;
472 }
473 case STATE_ELEMENT_U_LN: {
474 final String u = readStructureString();
475 final String ln = readStructureString();
476 processElement(u, ln, ln,false);
477 break;
478 }
479 case STATE_ELEMENT_LN: {
480 final String ln = readStructureString();
481 processElement("", ln, ln,false);
482 break;
483 }
484 case STATE_TEXT_AS_CHAR_ARRAY_SMALL:
485 {
486 final int length = readStructure();
487 int start = readContentCharactersBuffer(length);
488 _contentHandler.characters(_contentCharactersBuffer, start, length);
489 break;
490 }
491 case STATE_TEXT_AS_CHAR_ARRAY_MEDIUM:
492 {
493 final int length = readStructure16();
494 int start = readContentCharactersBuffer(length);
495 _contentHandler.characters(_contentCharactersBuffer, start, length);
496 break;
497 }
498 case STATE_TEXT_AS_CHAR_ARRAY_COPY:
499 {
500 final char[] ch = readContentCharactersCopy();
502 _contentHandler.characters(ch, 0, ch.length);
503 break;
504 }
505 case STATE_TEXT_AS_STRING:
506 {
507 final String s = readContentString();
508 _contentHandler.characters(s.toCharArray(), 0, s.length());
509 break;
510 }
511 case STATE_TEXT_AS_OBJECT:
512 {
513 final CharSequence c = (CharSequence)readContentObject();
514 final String s = c.toString();
515 _contentHandler.characters(s.toCharArray(), 0, s.length());
516 break;
517 }
518 case STATE_COMMENT_AS_CHAR_ARRAY_SMALL:
519 processCommentAsCharArraySmall();
520 break;
521 case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM:
522 processCommentAsCharArrayMedium();
523 break;
524 case STATE_COMMENT_AS_CHAR_ARRAY_COPY:
525 processCommentAsCharArrayCopy();
526 break;
527 case T_COMMENT_AS_STRING:
528 processComment(readContentString());
529 break;
530 case STATE_PROCESSING_INSTRUCTION:
531 processProcessingInstruction(readStructureString(), readStructureString());
532 break;
533 case STATE_END:
534 break;
535 default:
536 throw reportFatalError("Illegal state for child of EII: "+item);
537 }
538 } while(item != STATE_END);
540 _contentHandler.endElement(uri, localName, qName);
542 if (hasNamespaceAttributes) {
543 processEndPrefixMapping();
544 }
545 }
547 private void readInscopeNamespaces(Set<String> prefixSet) throws SAXException {
548 for (Map.Entry<String, String> e : _buffer.getInscopeNamespaces().entrySet()) {
549 String key = fixNull(e.getKey());
550 // If the prefix is already written, do not write the prefix
551 if (!prefixSet.contains(key)) {
552 processNamespaceAttribute(key,e.getValue());
553 }
554 }
556 }
558 private static String fixNull(String s) {
559 if (s == null) return "";
560 else return s;
561 }
562 private void processCommentAsCharArrayCopy() throws SAXException {
563 final char[] ch = readContentCharactersCopy();
564 processComment(ch, 0, ch.length);
565 }
567 private void processCommentAsCharArrayMedium() throws SAXException {
568 final int length = readStructure16();
569 final int start = readContentCharactersBuffer(length);
570 processComment(_contentCharactersBuffer, start, length);
571 }
573 private void processEndPrefixMapping() throws SAXException {
574 final int end = _namespaceAttributesStack[--_namespaceAttributesStackIndex];
575 // final int start = (_namespaceAttributesStackIndex > 0) ? _namespaceAttributesStack[_namespaceAttributesStackIndex] : 0;
576 final int start = (_namespaceAttributesStackIndex >= 0) ? _namespaceAttributesStartingStack[_namespaceAttributesStackIndex] : 0;
578 for (int i = end - 1; i >= start; i--) {
579 _contentHandler.endPrefixMapping(_namespacePrefixes[i]);
580 }
581 _namespacePrefixesIndex = start;
582 }
584 private int processNamespaceAttributes(int item,boolean collectPrefixes, Set<String> prefixSet) throws SAXException {
585 do {
586 String prefix;
587 switch(getNIIState(item)) {
588 case STATE_NAMESPACE_ATTRIBUTE:
589 // Undeclaration of default namespace
590 processNamespaceAttribute("", "");
591 if(collectPrefixes) {
592 prefixSet.add("");
593 }
594 break;
595 case STATE_NAMESPACE_ATTRIBUTE_P:
596 // Undeclaration of namespace
597 prefix = readStructureString();
598 processNamespaceAttribute(prefix, "");
599 if(collectPrefixes) {
600 prefixSet.add(prefix);
601 }
602 break;
603 case STATE_NAMESPACE_ATTRIBUTE_P_U:
604 // Declaration with prefix
605 prefix = readStructureString();
606 processNamespaceAttribute(prefix, readStructureString());
607 if(collectPrefixes) {
608 prefixSet.add(prefix);
609 }
610 break;
611 case STATE_NAMESPACE_ATTRIBUTE_U:
612 // Default declaration
613 processNamespaceAttribute("", readStructureString());
614 if(collectPrefixes) {
615 prefixSet.add("");
616 }
617 break;
618 default:
619 throw reportFatalError("Illegal state: "+item);
620 }
621 readStructure();
623 item = peekStructure();
624 } while((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE);
627 cacheNamespacePrefixIndex();
629 return item;
630 }
632 private void processAttributes(int item) throws SAXException {
633 do {
634 switch(getAIIState(item)) {
635 case STATE_ATTRIBUTE_U_LN_QN:
636 _attributes.addAttributeWithQName(readStructureString(), readStructureString(), readStructureString(), readStructureString(), readContentString());
637 break;
638 case STATE_ATTRIBUTE_P_U_LN:
639 {
640 final String p = readStructureString();
641 final String u = readStructureString();
642 final String ln = readStructureString();
643 _attributes.addAttributeWithQName(u, ln, getQName(p, ln), readStructureString(), readContentString());
644 break;
645 }
646 case STATE_ATTRIBUTE_U_LN: {
647 final String u = readStructureString();
648 final String ln = readStructureString();
649 _attributes.addAttributeWithQName(u, ln, ln, readStructureString(), readContentString());
650 break;
651 }
652 case STATE_ATTRIBUTE_LN: {
653 final String ln = readStructureString();
654 _attributes.addAttributeWithQName("", ln, ln, readStructureString(), readContentString());
655 break;
656 }
657 default:
658 throw reportFatalError("Illegal state: "+item);
659 }
660 readStructure();
662 item = peekStructure();
663 } while((item & TYPE_MASK) == T_ATTRIBUTE);
664 }
666 private void processNamespaceAttribute(String prefix, String uri) throws SAXException {
667 _contentHandler.startPrefixMapping(prefix, uri);
669 if (_namespacePrefixesFeature) {
670 // Add the namespace delcaration as an attribute
671 if (prefix != "") {
672 _attributes.addAttributeWithQName(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, prefix,
673 getQName(XMLConstants.XMLNS_ATTRIBUTE, prefix),
674 "CDATA", uri);
675 } else {
676 _attributes.addAttributeWithQName(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE,
677 XMLConstants.XMLNS_ATTRIBUTE,
678 "CDATA", uri);
679 }
680 }
682 cacheNamespacePrefix(prefix);
683 }
685 private void cacheNamespacePrefix(String prefix) {
686 if (_namespacePrefixesIndex == _namespacePrefixes.length) {
687 final String[] namespaceAttributes = new String[_namespacePrefixesIndex * 3 / 2 + 1];
688 System.arraycopy(_namespacePrefixes, 0, namespaceAttributes, 0, _namespacePrefixesIndex);
689 _namespacePrefixes = namespaceAttributes;
690 }
692 _namespacePrefixes[_namespacePrefixesIndex++] = prefix;
693 }
695 private void cacheNamespacePrefixIndex() {
696 if (_namespaceAttributesStackIndex == _namespaceAttributesStack.length) {
697 final int[] namespaceAttributesStack = new int[_namespaceAttributesStackIndex * 3 /2 + 1];
698 System.arraycopy(_namespaceAttributesStack, 0, namespaceAttributesStack, 0, _namespaceAttributesStackIndex);
699 _namespaceAttributesStack = namespaceAttributesStack;
700 }
702 _namespaceAttributesStack[_namespaceAttributesStackIndex++] = _namespacePrefixesIndex;
703 }
705 private void cacheNamespacePrefixStartingIndex() {
706 if (_namespaceAttributesStackIndex == _namespaceAttributesStartingStack.length) {
707 final int[] namespaceAttributesStart = new int[_namespaceAttributesStackIndex * 3 /2 + 1];
708 System.arraycopy(_namespaceAttributesStartingStack, 0, namespaceAttributesStart, 0, _namespaceAttributesStackIndex);
709 _namespaceAttributesStartingStack = namespaceAttributesStart;
710 }
711 _namespaceAttributesStartingStack[_namespaceAttributesStackIndex] = _namespacePrefixesIndex;
712 }
714 private void processComment(String s) throws SAXException {
715 processComment(s.toCharArray(), 0, s.length());
716 }
718 private void processComment(char[] ch, int start, int length) throws SAXException {
719 _lexicalHandler.comment(ch, start, length);
720 }
722 private void processProcessingInstruction(String target, String data) throws SAXException {
723 _contentHandler.processingInstruction(target, data);
724 }
726 private static final DefaultWithLexicalHandler DEFAULT_LEXICAL_HANDLER = new DefaultWithLexicalHandler();
727 }