1 package com.fasterxml.jackson.dataformat.xml.ser;
2
3 import java.io.*;
4 import java.math.BigDecimal;
5 import java.math.BigInteger;
6 import java.util.*;
7
8 import javax.xml.namespace.QName;
9 import javax.xml.stream.XMLStreamException;
10 import javax.xml.stream.XMLStreamWriter;
11
12 import org.codehaus.stax2.XMLStreamWriter2;
13 import org.codehaus.stax2.ri.Stax2WriterAdapter;
14
15 import com.fasterxml.jackson.core.*;
16 import com.fasterxml.jackson.core.base.GeneratorBase;
17 import com.fasterxml.jackson.core.io.IOContext;
18 import com.fasterxml.jackson.core.json.JsonWriteContext;
19 import com.fasterxml.jackson.dataformat.xml.XmlPrettyPrinter;
20 import com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter;
21 import com.fasterxml.jackson.dataformat.xml.util.StaxUtil;
22
23
30 public final class ToXmlGenerator
31 extends GeneratorBase
32 {
33
37 protected final static String DEFAULT_UNKNOWN_ELEMENT = "unknown";
38
39
42 public enum Feature implements FormatFeature
43 {
44
48 WRITE_XML_DECLARATION(false),
49
50
59 WRITE_XML_1_1(false),
60
61
73 WRITE_NULLS_AS_XSI_NIL(false)
74 ;
75
76 final boolean _defaultState;
77 final int _mask;
78
79
83 public static int collectDefaults()
84 {
85 int flags = 0;
86 for (Feature f : values()) {
87 if (f.enabledByDefault()) {
88 flags |= f.getMask();
89 }
90 }
91 return flags;
92 }
93
94 private Feature(boolean defaultState) {
95 _defaultState = defaultState;
96 _mask = (1 << ordinal());
97 }
98
99 @Override public boolean enabledByDefault() { return _defaultState; }
100 @Override public int getMask() { return _mask; }
101 @Override public boolean enabledIn(int flags) { return (flags & getMask()) != 0; }
102 }
103
104
109
110 final protected XMLStreamWriter2 _xmlWriter;
111
112 final protected XMLStreamWriter _originalXmlWriter;
113
114
118 final protected boolean _stax2Emulation;
119
120 final protected IOContext _ioContext;
121
122
127 protected int _formatFeatures;
128
129
132 protected XmlPrettyPrinter _xmlPrettyPrinter;
133
134
139
140
145 protected boolean _initialized;
146
147
152 protected QName _nextName = null;
153
154
158 protected boolean _nextIsAttribute = false;
159
160
166 protected boolean _nextIsUnwrapped = false;
167
168
172 protected boolean _nextIsCData = false;
173
174
178 protected LinkedList<QName> _elementNameStack = new LinkedList<QName>();
179
180
185
186 public ToXmlGenerator(IOContext ctxt, int stdFeatures, int xmlFeatures,
187 ObjectCodec codec, XMLStreamWriter sw)
188 {
189 super(stdFeatures, codec);
190 _formatFeatures = xmlFeatures;
191 _ioContext = ctxt;
192 _originalXmlWriter = sw;
193 _xmlWriter = Stax2WriterAdapter.wrapIfNecessary(sw);
194 _stax2Emulation = (_xmlWriter != sw);
195 _xmlPrettyPrinter = (_cfgPrettyPrinter instanceof XmlPrettyPrinter) ?
196 (XmlPrettyPrinter) _cfgPrettyPrinter : null;
197 }
198
199
203 public void initGenerator() throws IOException
204 {
205 if (_initialized) {
206 return;
207 }
208 _initialized = true;
209 try {
210 if (Feature.WRITE_XML_1_1.enabledIn(_formatFeatures)) {
211 _xmlWriter.writeStartDocument("UTF-8", "1.1");
212 } else if (Feature.WRITE_XML_DECLARATION.enabledIn(_formatFeatures)) {
213 _xmlWriter.writeStartDocument("UTF-8", "1.0");
214 } else {
215 return;
216 }
217
218 if (_xmlPrettyPrinter != null) {
219
220 if (!_stax2Emulation) {
221 _xmlPrettyPrinter.writePrologLinefeed(_xmlWriter);
222 }
223 }
224 } catch (XMLStreamException e) {
225 StaxUtil.throwAsGenerationException(e, this);
226 }
227 }
228
229
234
235 @Override
236 protected PrettyPrinter _constructDefaultPrettyPrinter() {
237 return new DefaultXmlPrettyPrinter();
238 }
239
240 @Override
241 public JsonGenerator setPrettyPrinter(PrettyPrinter pp) {
242 _cfgPrettyPrinter = pp;
243 _xmlPrettyPrinter = (pp instanceof XmlPrettyPrinter) ?
244 (XmlPrettyPrinter) pp : null;
245 return this;
246 }
247
248 @Override
249 public Object getOutputTarget() {
250
251
252 return _originalXmlWriter;
253 }
254
255
259 @Override
260 public int getOutputBuffered() {
261 return -1;
262 }
263
264 @Override
265 public int getFormatFeatures() {
266 return _formatFeatures;
267 }
268
269 @Override
270 public JsonGenerator overrideFormatFeatures(int values, int mask)
271 {
272 int oldF = _formatFeatures;
273 int newF = (_formatFeatures & ~mask) | (values & mask);
274
275 if (oldF != newF) {
276 _formatFeatures = newF;
277 }
278 return this;
279 }
280
281
286
287 public ToXmlGenerator enable(Feature f) {
288 _formatFeatures |= f.getMask();
289 return this;
290 }
291
292 public ToXmlGenerator disable(Feature f) {
293 _formatFeatures &= ~f.getMask();
294 return this;
295 }
296
297 public final boolean isEnabled(Feature f) {
298 return (_formatFeatures & f.getMask()) != 0;
299 }
300
301 public ToXmlGenerator configure(Feature f, boolean state) {
302 if (state) {
303 enable(f);
304 } else {
305 disable(f);
306 }
307 return this;
308 }
309
310 @Override
311 public boolean canWriteFormattedNumbers() { return true; }
312
313
314 public boolean inRoot() {
315 return _writeContext.inRoot();
316 }
317
318
323
324
334 public XMLStreamWriter getStaxWriter() {
335 return _xmlWriter;
336 }
337
338
343
344 public void setNextIsAttribute(boolean isAttribute)
345 {
346 _nextIsAttribute = isAttribute;
347 }
348
349 public void setNextIsUnwrapped(boolean isUnwrapped)
350 {
351 _nextIsUnwrapped = isUnwrapped;
352 }
353
354 public void setNextIsCData(boolean isCData)
355 {
356 _nextIsCData = isCData;
357 }
358
359 public final void setNextName(QName name)
360 {
361 _nextName = name;
362 }
363
364
370 public final boolean setNextNameIfMissing(QName name)
371 {
372 if (_nextName == null) {
373 _nextName = name;
374 return true;
375 }
376 return false;
377 }
378
379
387 public void startWrappedValue(QName wrapperName, QName wrappedName) throws IOException
388 {
389 if (wrapperName != null) {
390 try {
391 if (_xmlPrettyPrinter != null) {
392 _xmlPrettyPrinter.writeStartElement(_xmlWriter,
393 wrapperName.getNamespaceURI(), wrapperName.getLocalPart());
394 } else {
395 _xmlWriter.writeStartElement(wrapperName.getNamespaceURI(), wrapperName.getLocalPart());
396 }
397 } catch (XMLStreamException e) {
398 StaxUtil.throwAsGenerationException(e, this);
399 }
400 }
401 this.setNextName(wrappedName);
402 }
403
404
407 public void finishWrappedValue(QName wrapperName, QName wrappedName) throws IOException
408 {
409
410 if (wrapperName != null) {
411 try {
412 if (_xmlPrettyPrinter != null) {
413 _xmlPrettyPrinter.writeEndElement(_xmlWriter, _writeContext.getEntryCount());
414 } else {
415 _xmlWriter.writeEndElement();
416 }
417 } catch (XMLStreamException e) {
418 StaxUtil.throwAsGenerationException(e, this);
419 }
420 }
421 }
422
423
428 public void writeRepeatedFieldName() throws IOException
429 {
430 if (_writeContext.writeFieldName(_nextName.getLocalPart()) == JsonWriteContext.STATUS_EXPECT_VALUE) {
431 _reportError("Can not write a field name, expecting a value");
432 }
433 }
434
435
440
441
444
445 @Override
446 public final void writeFieldName(String name) throws IOException
447 {
448 if (_writeContext.writeFieldName(name) == JsonWriteContext.STATUS_EXPECT_VALUE) {
449 _reportError("Can not write a field name, expecting a value");
450 }
451
452 String ns = (_nextName == null) ? "" : _nextName.getNamespaceURI();
453 setNextName(new QName(ns, name));
454 }
455
456 @Override
457 public final void writeStringField(String fieldName, String value) throws IOException
458 {
459 writeFieldName(fieldName);
460 writeString(value);
461 }
462
463
464
465
466
467
468
469
470
482
483
488
489 @Override
490 public final void writeStartArray() throws IOException
491 {
492 _verifyValueWrite("start an array");
493 _writeContext = _writeContext.createChildArrayContext();
494 if (_cfgPrettyPrinter != null) {
495 _cfgPrettyPrinter.writeStartArray(this);
496 } else {
497
498 }
499 }
500
501 @Override
502 public final void writeEndArray() throws IOException
503 {
504 if (!_writeContext.inArray()) {
505 _reportError("Current context not Array but "+_writeContext.typeDesc());
506 }
507 if (_cfgPrettyPrinter != null) {
508 _cfgPrettyPrinter.writeEndArray(this, _writeContext.getEntryCount());
509 } else {
510
511 }
512 _writeContext = _writeContext.getParent();
513 }
514
515 @Override
516 public final void writeStartObject() throws IOException
517 {
518 _verifyValueWrite("start an object");
519 _writeContext = _writeContext.createChildObjectContext();
520 if (_cfgPrettyPrinter != null) {
521 _cfgPrettyPrinter.writeStartObject(this);
522 } else {
523 _handleStartObject();
524 }
525 }
526
527 @Override
528 public final void writeEndObject() throws IOException
529 {
530 if (!_writeContext.inObject()) {
531 _reportError("Current context not Object but "+_writeContext.typeDesc());
532 }
533 _writeContext = _writeContext.getParent();
534 if (_cfgPrettyPrinter != null) {
535
536 int count = _nextIsAttribute ? 0 : _writeContext.getEntryCount();
537 _cfgPrettyPrinter.writeEndObject(this, count);
538 } else {
539 _handleEndObject();
540 }
541 }
542
543
544 public final void _handleStartObject() throws IOException
545 {
546 if (_nextName == null) {
547 handleMissingName();
548 }
549
550 _elementNameStack.addLast(_nextName);
551 try {
552 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
553 } catch (XMLStreamException e) {
554 StaxUtil.throwAsGenerationException(e, this);
555 }
556 }
557
558
559 public final void _handleEndObject() throws IOException
560 {
561
562 if (_elementNameStack.isEmpty()) {
563 throw new JsonGenerationException("Can not write END_ELEMENT without open START_ELEMENT", this);
564 }
565 _nextName = _elementNameStack.removeLast();
566 try {
567
568 _nextIsAttribute = false;
569 _xmlWriter.writeEndElement();
570
571 if (_elementNameStack.isEmpty() && (_xmlPrettyPrinter != null)) {
572
573 if (!_stax2Emulation) {
574 _xmlPrettyPrinter.writePrologLinefeed(_xmlWriter);
575 }
576 }
577 } catch (XMLStreamException e) {
578 StaxUtil.throwAsGenerationException(e, this);
579 }
580 }
581
582
587
588 @Override
589 public void writeFieldName(SerializableString name) throws IOException
590 {
591 writeFieldName(name.getValue());
592 }
593
594 @Override
595 public void writeString(String text) throws IOException
596 {
597 if (text == null) {
598 writeNull();
599 return;
600 }
601 _verifyValueWrite("write String value");
602 if (_nextName == null) {
603 handleMissingName();
604 }
605 try {
606 if (_nextIsAttribute) {
607 _xmlWriter.writeAttribute(_nextName.getNamespaceURI(), _nextName.getLocalPart(), text);
608 } else if (checkNextIsUnwrapped()) {
609
610
611
612 if(_nextIsCData) {
613 _xmlWriter.writeCData(text);
614 } else {
615 _xmlWriter.writeCharacters(text);
616 }
617 } else if (_xmlPrettyPrinter != null) {
618 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
619 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
620 text, _nextIsCData);
621 } else {
622 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
623 if(_nextIsCData) {
624 _xmlWriter.writeCData(text);
625 } else {
626 _xmlWriter.writeCharacters(text);
627 }
628 _xmlWriter.writeEndElement();
629 }
630 } catch (XMLStreamException e) {
631 StaxUtil.throwAsGenerationException(e, this);
632 }
633 }
634
635 @Override
636 public void writeString(char[] text, int offset, int len) throws IOException
637 {
638 _verifyValueWrite("write String value");
639 if (_nextName == null) {
640 handleMissingName();
641 }
642 try {
643 if (_nextIsAttribute) {
644 _xmlWriter.writeAttribute(_nextName.getNamespaceURI(), _nextName.getLocalPart(), new String(text, offset, len));
645 } else if (checkNextIsUnwrapped()) {
646
647 if(_nextIsCData) {
648 _xmlWriter.writeCData(text, offset, len);
649 } else {
650 _xmlWriter.writeCharacters(text, offset, len);
651 }
652 } else if (_xmlPrettyPrinter != null) {
653 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
654 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
655 text, offset, len, _nextIsCData);
656 } else {
657 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
658 if(_nextIsCData) {
659 _xmlWriter.writeCData(text, offset, len);
660 } else {
661 _xmlWriter.writeCharacters(text, offset, len);
662 }
663 _xmlWriter.writeEndElement();
664 }
665 } catch (XMLStreamException e) {
666 StaxUtil.throwAsGenerationException(e, this);
667 }
668 }
669
670 @Override
671 public void writeString(SerializableString text) throws IOException {
672 writeString(text.getValue());
673 }
674
675 @Override
676 public void writeRawUTF8String(byte[] text, int offset, int length) throws IOException
677 {
678
679 _reportUnsupportedOperation();
680 }
681
682 @Override
683 public void writeUTF8String(byte[] text, int offset, int length) throws IOException
684 {
685
686 _reportUnsupportedOperation();
687 }
688
689
694
695 @Override
696 public void writeRawValue(String text) throws IOException {
697
698 if (_stax2Emulation) {
699 _reportUnimplementedStax2("writeRawValue");
700 }
701 try {
702 _verifyValueWrite("write raw value");
703 if (_nextName == null) {
704 handleMissingName();
705 }
706
707 if (_nextIsAttribute) {
708 _xmlWriter.writeAttribute(_nextName.getNamespaceURI(), _nextName.getLocalPart(), text);
709 } else {
710 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
711 _xmlWriter.writeRaw(text);
712 _xmlWriter.writeEndElement();
713 }
714 } catch (XMLStreamException e) {
715 StaxUtil.throwAsGenerationException(e, this);
716 }
717 }
718
719 @Override
720 public void writeRawValue(String text, int offset, int len) throws IOException {
721
722 if (_stax2Emulation) {
723 _reportUnimplementedStax2("writeRawValue");
724 }
725 try {
726 _verifyValueWrite("write raw value");
727 if (_nextName == null) {
728 handleMissingName();
729 }
730
731 if (_nextIsAttribute) {
732 _xmlWriter.writeAttribute(_nextName.getNamespaceURI(), _nextName.getLocalPart(), text.substring(offset, offset + len));
733 } else {
734 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
735 _xmlWriter.writeRaw(text, offset, len);
736 _xmlWriter.writeEndElement();
737 }
738 } catch (XMLStreamException e) {
739 StaxUtil.throwAsGenerationException(e, this);
740 }
741 }
742
743 @Override
744 public void writeRawValue(char[] text, int offset, int len) throws IOException {
745
746 if (_stax2Emulation) {
747 _reportUnimplementedStax2("writeRawValue");
748 }
749 _verifyValueWrite("write raw value");
750 if (_nextName == null) {
751 handleMissingName();
752 }
753 try {
754 if (_nextIsAttribute) {
755 _xmlWriter.writeAttribute(_nextName.getNamespaceURI(), _nextName.getLocalPart(), new String(text, offset, len));
756 } else {
757 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
758 _xmlWriter.writeRaw(text, offset, len);
759 _xmlWriter.writeEndElement();
760 }
761 } catch (XMLStreamException e) {
762 StaxUtil.throwAsGenerationException(e, this);
763 }
764 }
765
766 @Override
767 public void writeRawValue(SerializableString text) throws IOException {
768 _reportUnsupportedOperation();
769 }
770
771 @Override
772 public void writeRaw(String text) throws IOException
773 {
774
775 if (_stax2Emulation) {
776 _reportUnimplementedStax2("writeRaw");
777 }
778 try {
779 _xmlWriter.writeRaw(text);
780 } catch (XMLStreamException e) {
781 StaxUtil.throwAsGenerationException(e, this);
782 }
783 }
784
785 @Override
786 public void writeRaw(String text, int offset, int len) throws IOException
787 {
788
789 if (_stax2Emulation) {
790 _reportUnimplementedStax2("writeRaw");
791 }
792 try {
793 _xmlWriter.writeRaw(text, offset, len);
794 } catch (XMLStreamException e) {
795 StaxUtil.throwAsGenerationException(e, this);
796 }
797 }
798
799 @Override
800 public void writeRaw(char[] text, int offset, int len) throws IOException
801 {
802
803 if (_stax2Emulation) {
804 _reportUnimplementedStax2("writeRaw");
805 }
806 try {
807 _xmlWriter.writeRaw(text, offset, len);
808 } catch (XMLStreamException e) {
809 StaxUtil.throwAsGenerationException(e, this);
810 }
811 }
812
813 @Override
814 public void writeRaw(char c) throws IOException
815 {
816 writeRaw(String.valueOf(c));
817 }
818
819
824
825 @Override
826 public void writeBinary(Base64Variant b64variant,
827 byte[] data, int offset, int len) throws IOException
828 {
829 if (data == null) {
830 writeNull();
831 return;
832 }
833 _verifyValueWrite("write Binary value");
834 if (_nextName == null) {
835 handleMissingName();
836 }
837 try {
838 if (_nextIsAttribute) {
839
840 byte[] fullBuffer = toFullBuffer(data, offset, len);
841 _xmlWriter.writeBinaryAttribute("", _nextName.getNamespaceURI(), _nextName.getLocalPart(), fullBuffer);
842 } else if (checkNextIsUnwrapped()) {
843
844 _xmlWriter.writeBinary(data, offset, len);
845 } else {
846 if (_xmlPrettyPrinter != null) {
847 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
848 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
849 data, offset, len);
850 } else {
851 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
852 _xmlWriter.writeBinary(data, offset, len);
853 _xmlWriter.writeEndElement();
854 }
855 }
856 } catch (XMLStreamException e) {
857 StaxUtil.throwAsGenerationException(e, this);
858 }
859 }
860
861 @Override
862 public int writeBinary(Base64Variant b64variant, InputStream data, int dataLength) throws IOException
863 {
864 if (data == null) {
865 writeNull();
866 return 0;
867 }
868 _verifyValueWrite("write Binary value");
869 if (_nextName == null) {
870 handleMissingName();
871 }
872 try {
873 if (_nextIsAttribute) {
874
875 byte[] fullBuffer = toFullBuffer(data, dataLength);
876 _xmlWriter.writeBinaryAttribute("", _nextName.getNamespaceURI(), _nextName.getLocalPart(), fullBuffer);
877 } else if (checkNextIsUnwrapped()) {
878
879 writeStreamAsBinary(data, dataLength);
880
881 } else {
882 if (_xmlPrettyPrinter != null) {
883 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
884 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
885 toFullBuffer(data, dataLength), 0, dataLength);
886 } else {
887 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
888 writeStreamAsBinary(data, dataLength);
889 _xmlWriter.writeEndElement();
890 }
891 }
892 } catch (XMLStreamException e) {
893 StaxUtil.throwAsGenerationException(e, this);
894 }
895
896 return dataLength;
897 }
898
899 private void writeStreamAsBinary(InputStream data, int len) throws IOException, XMLStreamException
900 {
901
902 byte[] tmp = new byte[3];
903 int offset = 0;
904 int read;
905 while((read = data.read(tmp, offset, Math.min(3 - offset, len))) != -1) {
906 offset += read;
907 len -= read;
908 if(offset == 3) {
909 offset = 0;
910 _xmlWriter.writeBinary(tmp, 0, 3);
911 }
912 if (len == 0) {
913 break;
914 }
915 }
916
917
918 if(offset > 0) {
919 _xmlWriter.writeBinary(tmp, 0, offset);
920 }
921 }
922
923
924 private byte[] toFullBuffer(byte[] data, int offset, int len)
925 {
926
927 if (offset == 0 && len == data.length) {
928 return data;
929 }
930 byte[] result = new byte[len];
931 if (len > 0) {
932 System.arraycopy(data, offset, result, 0, len);
933 }
934 return result;
935 }
936
937 private byte[] toFullBuffer(InputStream data, final int len) throws IOException
938 {
939 byte[] result = new byte[len];
940 int offset = 0;
941
942 for (; offset < len; ) {
943 int count = data.read(result, offset, len - offset);
944 if (count < 0) {
945 _reportError("Too few bytes available: missing "+(len - offset)+" bytes (out of "+len+")");
946 }
947 offset += count;
948 }
949 return result;
950 }
951
952
957
958 @Override
959 public void writeBoolean(boolean value) throws IOException
960 {
961 _verifyValueWrite("write boolean value");
962 if (_nextName == null) {
963 handleMissingName();
964 }
965 try {
966 if (_nextIsAttribute) {
967 _xmlWriter.writeBooleanAttribute(null, _nextName.getNamespaceURI(), _nextName.getLocalPart(), value);
968 } else if (checkNextIsUnwrapped()) {
969
970 _xmlWriter.writeBoolean(value);
971 } else {
972 if (_xmlPrettyPrinter != null) {
973 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
974 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
975 value);
976 } else {
977 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
978 _xmlWriter.writeBoolean(value);
979 _xmlWriter.writeEndElement();
980 }
981 }
982 } catch (XMLStreamException e) {
983 StaxUtil.throwAsGenerationException(e, this);
984 }
985 }
986
987 @Override
988 public void writeNull() throws IOException
989 {
990 _verifyValueWrite("write null value");
991 if (_nextName == null) {
992 handleMissingName();
993 }
994
995 try {
996 if (_nextIsAttribute) {
997
1000 } else if (checkNextIsUnwrapped()) {
1001
1002 } else {
1003 if (_xmlPrettyPrinter != null) {
1004 _xmlPrettyPrinter.writeLeafNullElement(_xmlWriter,
1005 _nextName.getNamespaceURI(), _nextName.getLocalPart());
1006 } else {
1007 _xmlWriter.writeEmptyElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
1008 }
1009 }
1010 } catch (XMLStreamException e) {
1011 StaxUtil.throwAsGenerationException(e, this);
1012 }
1013 }
1014
1015 @Override
1016 public void writeNumber(int i) throws IOException
1017 {
1018 _verifyValueWrite("write number");
1019 if (_nextName == null) {
1020 handleMissingName();
1021 }
1022 try {
1023 if (_nextIsAttribute) {
1024 _xmlWriter.writeIntAttribute(null, _nextName.getNamespaceURI(), _nextName.getLocalPart(), i);
1025 } else if (checkNextIsUnwrapped()) {
1026
1027 _xmlWriter.writeInt(i);
1028 } else {
1029 if (_xmlPrettyPrinter != null) {
1030 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
1031 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
1032 i);
1033 } else {
1034 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
1035 _xmlWriter.writeInt(i);
1036 _xmlWriter.writeEndElement();
1037 }
1038 }
1039 } catch (XMLStreamException e) {
1040 StaxUtil.throwAsGenerationException(e, this);
1041 }
1042 }
1043
1044 @Override
1045 public void writeNumber(long l) throws IOException
1046 {
1047 _verifyValueWrite("write number");
1048 if (_nextName == null) {
1049 handleMissingName();
1050 }
1051 try {
1052 if (_nextIsAttribute) {
1053 _xmlWriter.writeLongAttribute(null, _nextName.getNamespaceURI(), _nextName.getLocalPart(), l);
1054 } else if (checkNextIsUnwrapped()) {
1055 _xmlWriter.writeLong(l);
1056 } else {
1057 if (_xmlPrettyPrinter != null) {
1058 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
1059 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
1060 l);
1061 } else {
1062 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
1063 _xmlWriter.writeLong(l);
1064 _xmlWriter.writeEndElement();
1065 }
1066 }
1067 } catch (XMLStreamException e) {
1068 StaxUtil.throwAsGenerationException(e, this);
1069 }
1070 }
1071
1072 @Override
1073 public void writeNumber(double d) throws IOException
1074 {
1075 _verifyValueWrite("write number");
1076 if (_nextName == null) {
1077 handleMissingName();
1078 }
1079 try {
1080 if (_nextIsAttribute) {
1081 _xmlWriter.writeDoubleAttribute(null, _nextName.getNamespaceURI(), _nextName.getLocalPart(), d);
1082 } else if (checkNextIsUnwrapped()) {
1083 _xmlWriter.writeDouble(d);
1084 } else {
1085 if (_xmlPrettyPrinter != null) {
1086 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
1087 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
1088 d);
1089 } else {
1090 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
1091 _xmlWriter.writeDouble(d);
1092 _xmlWriter.writeEndElement();
1093 }
1094 }
1095 } catch (XMLStreamException e) {
1096 StaxUtil.throwAsGenerationException(e, this);
1097 }
1098 }
1099
1100 @Override
1101 public void writeNumber(float f) throws IOException
1102 {
1103 _verifyValueWrite("write number");
1104 if (_nextName == null) {
1105 handleMissingName();
1106 }
1107 try {
1108 if (_nextIsAttribute) {
1109 _xmlWriter.writeFloatAttribute(null, _nextName.getNamespaceURI(), _nextName.getLocalPart(), f);
1110 } else if (checkNextIsUnwrapped()) {
1111 _xmlWriter.writeFloat(f);
1112 } else {
1113 if (_xmlPrettyPrinter != null) {
1114 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
1115 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
1116 f);
1117 } else {
1118 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
1119 _xmlWriter.writeFloat(f);
1120 _xmlWriter.writeEndElement();
1121 }
1122 }
1123 } catch (XMLStreamException e) {
1124 StaxUtil.throwAsGenerationException(e, this);
1125 }
1126 }
1127
1128 @Override
1129 public void writeNumber(BigDecimal dec) throws IOException
1130 {
1131 if (dec == null) {
1132 writeNull();
1133 return;
1134 }
1135 _verifyValueWrite("write number");
1136 if (_nextName == null) {
1137 handleMissingName();
1138 }
1139 boolean usePlain = isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
1140 try {
1141 if (_nextIsAttribute) {
1142 if (usePlain) {
1143 _xmlWriter.writeAttribute("", _nextName.getNamespaceURI(), _nextName.getLocalPart(),
1144 dec.toPlainString());
1145 } else {
1146 _xmlWriter.writeDecimalAttribute("", _nextName.getNamespaceURI(), _nextName.getLocalPart(), dec);
1147 }
1148 } else if (checkNextIsUnwrapped()) {
1149 if (usePlain) {
1150 _xmlWriter.writeCharacters(dec.toPlainString());
1151 } else {
1152 _xmlWriter.writeDecimal(dec);
1153 }
1154 } else {
1155 if (_xmlPrettyPrinter != null) {
1156 if (usePlain) {
1157 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
1158 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
1159 dec.toPlainString(), false);
1160 } else {
1161 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
1162 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
1163 dec);
1164 }
1165 } else {
1166 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
1167 if (usePlain) {
1168 _xmlWriter.writeCharacters(dec.toPlainString());
1169 } else {
1170 _xmlWriter.writeDecimal(dec);
1171 }
1172 _xmlWriter.writeEndElement();
1173 }
1174 }
1175 } catch (XMLStreamException e) {
1176 StaxUtil.throwAsGenerationException(e, this);
1177 }
1178 }
1179
1180 @Override
1181 public void writeNumber(BigInteger value) throws IOException
1182 {
1183 if (value == null) {
1184 writeNull();
1185 return;
1186 }
1187 _verifyValueWrite("write number");
1188 if (_nextName == null) {
1189 handleMissingName();
1190 }
1191 try {
1192 if (_nextIsAttribute) {
1193 _xmlWriter.writeIntegerAttribute("",
1194 _nextName.getNamespaceURI(), _nextName.getLocalPart(), value);
1195 } else if (checkNextIsUnwrapped()) {
1196 _xmlWriter.writeInteger(value);
1197 } else {
1198 if (_xmlPrettyPrinter != null) {
1199 _xmlPrettyPrinter.writeLeafElement(_xmlWriter,
1200 _nextName.getNamespaceURI(), _nextName.getLocalPart(),
1201 value);
1202 } else {
1203 _xmlWriter.writeStartElement(_nextName.getNamespaceURI(), _nextName.getLocalPart());
1204 _xmlWriter.writeInteger(value);
1205 _xmlWriter.writeEndElement();
1206 }
1207 }
1208 } catch (XMLStreamException e) {
1209 StaxUtil.throwAsGenerationException(e, this);
1210 }
1211 }
1212
1213 @Override
1214 public void writeNumber(String encodedValue) throws IOException, UnsupportedOperationException
1215 {
1216 writeString(encodedValue);
1217 }
1218
1219
1224
1225 @Override
1226 protected final void _verifyValueWrite(String typeMsg) throws IOException
1227 {
1228 int status = _writeContext.writeValue();
1229 if (status == JsonWriteContext.STATUS_EXPECT_NAME) {
1230 _reportError("Can not "+typeMsg+", expecting field name");
1231 }
1232 }
1233
1234
1239
1240 @Override
1241 public void flush() throws IOException
1242 {
1243 if (isEnabled(JsonGenerator.Feature.FLUSH_PASSED_TO_STREAM)) {
1244 try {
1245 _xmlWriter.flush();
1246 } catch (XMLStreamException e) {
1247 StaxUtil.throwAsGenerationException(e, this);
1248 }
1249 }
1250 }
1251
1252 @Override
1253 public void close() throws IOException
1254 {
1255
1256 super.close();
1257
1258
1259 if (isEnabled(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT)) {
1260 try {
1261 while (true) {
1262
1266
1267 JsonStreamContext ctxt = _writeContext;
1268 if (ctxt.inArray()) {
1269 writeEndArray();
1270 } else if (ctxt.inObject()) {
1271 writeEndObject();
1272 } else {
1273 break;
1274 }
1275 }
1276 } catch (ArrayIndexOutOfBoundsException e) {
1277
1280 throw new JsonGenerationException(e, this);
1281 }
1282 }
1283 try {
1284 if (_ioContext.isResourceManaged() || isEnabled(JsonGenerator.Feature.AUTO_CLOSE_TARGET)) {
1285 _xmlWriter.closeCompletely();
1286 } else {
1287 _xmlWriter.close();
1288 }
1289 } catch (XMLStreamException e) {
1290 StaxUtil.throwAsGenerationException(e, this);
1291 }
1292 }
1293
1294 @Override
1295 protected void _releaseBuffers() {
1296
1297 }
1298
1299
1304
1305
1310 protected boolean checkNextIsUnwrapped()
1311 {
1312 if (_nextIsUnwrapped) {
1313 _nextIsUnwrapped = false;
1314 return true;
1315 }
1316 return false;
1317 }
1318
1319 protected void handleMissingName() {
1320 throw new IllegalStateException("No element/attribute name specified when trying to output element");
1321 }
1322
1323
1326 protected void _reportUnimplementedStax2(String missingMethod) throws IOException
1327 {
1328 throw new JsonGenerationException("Underlying Stax XMLStreamWriter (of type "
1329 +_originalXmlWriter.getClass().getName()
1330 +") does not implement Stax2 API natively and is missing method '"
1331 +missingMethod+"': this breaks functionality such as indentation that relies on it. "
1332 +"You need to upgrade to using compliant Stax implementation like Woodstox or Aalto",
1333 this);
1334 }
1335 }
1336