Skip to content
Browse files

Changed: Switched from org.json to org.codehaus.jackson for JSON pars…

…ing: Speedup factor 3 (so far). Unfortunately had to patch some of the sources.

git-svn-id: http://android-xbmcremote.googlecode.com/svn/trunk/XBMC Remote@585 677bec2c-7919-11de-bdc7-1f637afd43b1
  • Loading branch information...
1 parent 63cf8a8 commit 10444d55ebdcd1e01bc2ae78c781eb59b43ea82b @freezy committed
Showing with 9,731 additions and 1 deletion.
  1. +1 −0 .classpath
  2. +1 −1 AndroidManifest.xml
  3. +339 −0 lib-src/org/codehaus/jackson/Base64Variant.java
  4. +90 −0 lib-src/org/codehaus/jackson/Base64Variants.java
  5. +48 −0 lib-src/org/codehaus/jackson/JsonEncoding.java
  6. +581 −0 lib-src/org/codehaus/jackson/JsonFactory.java
  7. +27 −0 lib-src/org/codehaus/jackson/JsonGenerationException.java
  8. +875 −0 lib-src/org/codehaus/jackson/JsonGenerator.java
  9. +141 −0 lib-src/org/codehaus/jackson/JsonLocation.java
  10. +417 −0 lib-src/org/codehaus/jackson/JsonNode.java
  11. +22 −0 lib-src/org/codehaus/jackson/JsonParseException.java
  12. +945 −0 lib-src/org/codehaus/jackson/JsonParser.java
  13. +80 −0 lib-src/org/codehaus/jackson/JsonProcessingException.java
  14. +112 −0 lib-src/org/codehaus/jackson/JsonStreamContext.java
  15. +160 −0 lib-src/org/codehaus/jackson/JsonToken.java
  16. +141 −0 lib-src/org/codehaus/jackson/ObjectCodec.java
  17. +166 −0 lib-src/org/codehaus/jackson/PrettyPrinter.java
  18. +20 −0 lib-src/org/codehaus/jackson/annotate/JacksonAnnotation.java
  19. +24 −0 lib-src/org/codehaus/jackson/annotate/JsonAnySetter.java
  20. +148 −0 lib-src/org/codehaus/jackson/annotate/JsonAutoDetect.java
  21. +41 −0 lib-src/org/codehaus/jackson/annotate/JsonClass.java
  22. +42 −0 lib-src/org/codehaus/jackson/annotate/JsonContentClass.java
  23. +19 −0 lib-src/org/codehaus/jackson/annotate/JsonCreator.java
  24. +34 −0 lib-src/org/codehaus/jackson/annotate/JsonGetter.java
  25. +50 −0 lib-src/org/codehaus/jackson/annotate/JsonIgnore.java
  26. +48 −0 lib-src/org/codehaus/jackson/annotate/JsonIgnoreProperties.java
  27. +44 −0 lib-src/org/codehaus/jackson/annotate/JsonKeyClass.java
  28. +90 −0 lib-src/org/codehaus/jackson/annotate/JsonMethod.java
  29. +38 −0 lib-src/org/codehaus/jackson/annotate/JsonProperty.java
  30. +46 −0 lib-src/org/codehaus/jackson/annotate/JsonPropertyOrder.java
  31. +29 −0 lib-src/org/codehaus/jackson/annotate/JsonSetter.java
  32. +45 −0 lib-src/org/codehaus/jackson/annotate/JsonSubTypes.java
  33. +174 −0 lib-src/org/codehaus/jackson/annotate/JsonTypeInfo.java
  34. +28 −0 lib-src/org/codehaus/jackson/annotate/JsonTypeName.java
  35. +46 −0 lib-src/org/codehaus/jackson/annotate/JsonValue.java
  36. +29 −0 lib-src/org/codehaus/jackson/annotate/JsonWriteNullProperties.java
  37. +16 −0 lib-src/org/codehaus/jackson/annotate/package-info.java
  38. +351 −0 lib-src/org/codehaus/jackson/impl/ByteSourceBootstrapper.java
  39. +264 −0 lib-src/org/codehaus/jackson/impl/DefaultPrettyPrinter.java
  40. +23 −0 lib-src/org/codehaus/jackson/impl/Indenter.java
  41. +476 −0 lib-src/org/codehaus/jackson/impl/JsonGeneratorBase.java
  42. +590 −0 lib-src/org/codehaus/jackson/impl/JsonNumericParserBase.java
  43. +666 −0 lib-src/org/codehaus/jackson/impl/JsonParserBase.java
  44. +176 −0 lib-src/org/codehaus/jackson/impl/JsonReadContext.java
  45. +228 −0 lib-src/org/codehaus/jackson/impl/JsonWriteContext.java
  46. +302 −0 lib-src/org/codehaus/jackson/impl/ReaderBasedNumericParser.java
  47. +1,040 −0 lib-src/org/codehaus/jackson/impl/ReaderBasedParser.java
  48. +134 −0 lib-src/org/codehaus/jackson/impl/ReaderBasedParserBase.java
  49. +134 −0 lib-src/org/codehaus/jackson/impl/StreamBasedParserBase.java
  50. +190 −0 lib-src/org/codehaus/jackson/impl/Utf8NumericParser.java
Sorry, we could not display the entire diff because it was too big.
View
1 .classpath
@@ -2,6 +2,7 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
+ <classpathentry kind="src" path="lib-src"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="lib" path="lib/jmdns.jar"/>
<classpathentry kind="output" path="bin"/>
View
2 AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.xbmc.android.remote"
- android:versionName="0.6.7+" android:versionCode="584">
+ android:versionName="0.6.7+" android:versionCode="585">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false" >
<activity android:name=".presentation.activity.HomeActivity"
android:label="@string/app_name"
View
339 lib-src/org/codehaus/jackson/Base64Variant.java
@@ -0,0 +1,339 @@
+/* Jackson JSON-processor.
+ *
+ * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi
+ *
+ * Licensed under the License specified in file LICENSE, included with
+ * the source code and binary code bundles.
+ * You may not use this file except in compliance with the License.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codehaus.jackson;
+
+import java.util.Arrays;
+
+/**
+ * Abstract base class used to define specific details of which
+ * variant of Base64 encoding/decoding is to be used. Although there is
+ * somewhat standard basic version (so-called "MIME Base64"), other variants
+ * exists, see <a href="http://en.wikipedia.org/wiki/Base64">Base64 Wikipedia entry</a> for details.
+ *
+ * @author Tatu Saloranta
+ *
+ * @since 0.9.3
+ */
+public final class Base64Variant
+{
+ /**
+ * Placeholder used by "no padding" variant, to be used when a character
+ * value is needed.
+ */
+ final static char PADDING_CHAR_NONE = '\0';
+
+ /**
+ * Marker used to denote ascii characters that do not correspond
+ * to a 6-bit value (in this variant), and is not used as a padding
+ * character.
+ */
+ public final static int BASE64_VALUE_INVALID = -1;
+
+ /**
+ * Marker used to denote ascii character (in decoding table) that
+ * is the padding character using this variant (if any).
+ */
+ public final static int BASE64_VALUE_PADDING = -2;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Encoding/decoding tables
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Decoding table used for base 64 decoding.
+ */
+ private final int[] _asciiToBase64 = new int[128];
+
+ /**
+ * Encoding table used for base 64 decoding when output is done
+ * as characters.
+ */
+ private final char[] _base64ToAsciiC = new char[64];
+
+ /**
+ * Alternative encoding table used for base 64 decoding when output is done
+ * as ascii bytes.
+ */
+ private final byte[] _base64ToAsciiB = new byte[64];
+
+ /*
+ ////////////////////////////////////////////////////
+ // Other configuration
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Symbolic name of variant; used for diagnostics/debugging.
+ */
+ final String _name;
+
+ /**
+ * Whether this variant uses padding or not.
+ */
+ final boolean _usesPadding;
+
+ /**
+ * Characted used for padding, if any ({@link #PADDING_CHAR_NONE} if not).
+ */
+ final char _paddingChar;
+
+ /**
+ * Maximum number of encoded base64 characters to output during encoding
+ * before adding a linefeed, if line length is to be limited
+ * ({@link java.lang.Integer#MAX_VALUE} if not limited).
+ *<p>
+ * Note: for some output modes (when writing attributes) linefeeds may
+ * need to be avoided, and this value ignored.
+ */
+ final int _maxLineLength;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Life-cycle
+ ////////////////////////////////////////////////////
+ */
+
+ public Base64Variant(String name, String base64Alphabet, boolean usesPadding, char paddingChar, int maxLineLength)
+ {
+ _name = name;
+ _usesPadding = usesPadding;
+ _paddingChar = paddingChar;
+ _maxLineLength = maxLineLength;
+
+ // Ok and then we need to create codec tables.
+
+ // First the main encoding table:
+ int alphaLen = base64Alphabet.length();
+ if (alphaLen != 64) {
+ throw new IllegalArgumentException("Base64Alphabet length must be exactly 64 (was "+alphaLen+")");
+ }
+
+ // And then secondary encoding table and decoding table:
+ base64Alphabet.getChars(0, alphaLen, _base64ToAsciiC, 0);
+ Arrays.fill(_asciiToBase64, BASE64_VALUE_INVALID);
+ for (int i = 0; i < alphaLen; ++i) {
+ char alpha = _base64ToAsciiC[i];
+ _base64ToAsciiB[i] = (byte) alpha;
+ _asciiToBase64[alpha] = i;
+ }
+
+ // Plus if we use padding, add that in too
+ if (usesPadding) {
+ _asciiToBase64[(int) paddingChar] = BASE64_VALUE_PADDING;
+ }
+ }
+
+ /**
+ * "Copy constructor" that can be used when the base alphabet is identical
+ * to one used by another variant except for the maximum line length
+ * (and obviously, name).
+ */
+ public Base64Variant(Base64Variant base, String name, int maxLineLength)
+ {
+ this(base, name, base._usesPadding, base._paddingChar, maxLineLength);
+ }
+
+ /**
+ * "Copy constructor" that can be used when the base alphabet is identical
+ * to one used by another variant, but other details (padding, maximum
+ * line length) differ
+ */
+ public Base64Variant(Base64Variant base, String name, boolean usesPadding, char paddingChar, int maxLineLength)
+ {
+ _name = name;
+ byte[] srcB = base._base64ToAsciiB;
+ System.arraycopy(srcB, 0, this._base64ToAsciiB, 0, srcB.length);
+ char[] srcC = base._base64ToAsciiC;
+ System.arraycopy(srcC, 0, this._base64ToAsciiC, 0, srcC.length);
+ int[] srcV = base._asciiToBase64;
+ System.arraycopy(srcV, 0, this._asciiToBase64, 0, srcV.length);
+
+ _usesPadding = usesPadding;
+ _paddingChar = paddingChar;
+ _maxLineLength = maxLineLength;
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public accessors
+ ////////////////////////////////////////////////////
+ */
+
+ public String getName() { return _name; }
+
+ public boolean usesPadding() { return _usesPadding; }
+ public boolean usesPaddingChar(char c) { return c == _paddingChar; }
+ public boolean usesPaddingChar(int ch) { return ch == (int) _paddingChar; }
+ public char getPaddingChar() { return _paddingChar; }
+ public byte getPaddingByte() { return (byte)_paddingChar; }
+
+ public int getMaxLineLength() { return _maxLineLength; }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Decoding support
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * @return 6-bit decoded value, if valid character;
+ */
+ public int decodeBase64Char(char c)
+ {
+ int ch = (int) c;
+ return (ch <= 127) ? _asciiToBase64[ch] : BASE64_VALUE_INVALID;
+ }
+
+ public int decodeBase64Char(int ch)
+ {
+ return (ch <= 127) ? _asciiToBase64[ch] : BASE64_VALUE_INVALID;
+ }
+
+ public int decodeBase64Byte(byte b)
+ {
+ int ch = (int) b;
+ return (ch <= 127) ? _asciiToBase64[ch] : BASE64_VALUE_INVALID;
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Encoding support
+ ////////////////////////////////////////////////////
+ */
+
+ public char encodeBase64BitsAsChar(int value)
+ {
+ /* Let's assume caller has done necessary checks; this
+ * method must be fast and inlinable
+ */
+ return _base64ToAsciiC[value];
+ }
+
+ /**
+ * Method that encodes given right-aligned (LSB) 24-bit value
+ * into 4 base64 characters, stored in given result buffer.
+ */
+ public int encodeBase64Chunk(int b24, char[] buffer, int ptr)
+ {
+ buffer[ptr++] = _base64ToAsciiC[(b24 >> 18) & 0x3F];
+ buffer[ptr++] = _base64ToAsciiC[(b24 >> 12) & 0x3F];
+ buffer[ptr++] = _base64ToAsciiC[(b24 >> 6) & 0x3F];
+ buffer[ptr++] = _base64ToAsciiC[b24 & 0x3F];
+ return ptr;
+ }
+
+ public void encodeBase64Chunk(StringBuilder sb, int b24)
+ {
+ sb.append(_base64ToAsciiC[(b24 >> 18) & 0x3F]);
+ sb.append(_base64ToAsciiC[(b24 >> 12) & 0x3F]);
+ sb.append(_base64ToAsciiC[(b24 >> 6) & 0x3F]);
+ sb.append(_base64ToAsciiC[b24 & 0x3F]);
+ }
+
+ /**
+ * Method that outputs partial chunk (which only encodes one
+ * or two bytes of data). Data given is still aligned same as if
+ * it as full data; that is, missing data is at the "right end"
+ * (LSB) of int.
+ *
+ * @param outputBytes Number of encoded bytes included (either 1 or 2)
+ */
+ public int encodeBase64Partial(int bits, int outputBytes, char[] buffer, int outPtr)
+ {
+ buffer[outPtr++] = _base64ToAsciiC[(bits >> 18) & 0x3F];
+ buffer[outPtr++] = _base64ToAsciiC[(bits >> 12) & 0x3F];
+ if (_usesPadding) {
+ buffer[outPtr++] = (outputBytes == 2) ?
+ _base64ToAsciiC[(bits >> 6) & 0x3F] : _paddingChar;
+ buffer[outPtr++] = _paddingChar;
+ } else {
+ if (outputBytes == 2) {
+ buffer[outPtr++] = _base64ToAsciiC[(bits >> 6) & 0x3F];
+ }
+ }
+ return outPtr;
+ }
+
+ public void encodeBase64Partial(StringBuilder sb, int bits, int outputBytes)
+ {
+ sb.append(_base64ToAsciiC[(bits >> 18) & 0x3F]);
+ sb.append(_base64ToAsciiC[(bits >> 12) & 0x3F]);
+ if (_usesPadding) {
+ sb.append((outputBytes == 2) ?
+ _base64ToAsciiC[(bits >> 6) & 0x3F] : _paddingChar);
+ sb.append(_paddingChar);
+ } else {
+ if (outputBytes == 2) {
+ sb.append(_base64ToAsciiC[(bits >> 6) & 0x3F]);
+ }
+ }
+ }
+
+ public byte encodeBase64BitsAsByte(int value)
+ {
+ // As with above, assuming it is 6-bit value
+ return _base64ToAsciiB[value];
+ }
+
+ /**
+ * Method that encodes given right-aligned (LSB) 24-bit value
+ * into 4 base64 bytes (ascii), stored in given result buffer.
+ */
+ public int encodeBase64Chunk(int b24, byte[] buffer, int ptr)
+ {
+ buffer[ptr++] = _base64ToAsciiB[(b24 >> 18) & 0x3F];
+ buffer[ptr++] = _base64ToAsciiB[(b24 >> 12) & 0x3F];
+ buffer[ptr++] = _base64ToAsciiB[(b24 >> 6) & 0x3F];
+ buffer[ptr++] = _base64ToAsciiB[b24 & 0x3F];
+ return ptr;
+ }
+
+ /**
+ * Method that outputs partial chunk (which only encodes one
+ * or two bytes of data). Data given is still aligned same as if
+ * it as full data; that is, missing data is at the "right end"
+ * (LSB) of int.
+ *
+ * @param outputBytes Number of encoded bytes included (either 1 or 2)
+ */
+ public int encodeBase64Partial(int bits, int outputBytes, byte[] buffer, int outPtr)
+ {
+ buffer[outPtr++] = _base64ToAsciiB[(bits >> 18) & 0x3F];
+ buffer[outPtr++] = _base64ToAsciiB[(bits >> 12) & 0x3F];
+ if (_usesPadding) {
+ byte pb = (byte) _paddingChar;
+ buffer[outPtr++] = (outputBytes == 2) ?
+ _base64ToAsciiB[(bits >> 6) & 0x3F] : pb;
+ buffer[outPtr++] = pb;
+ } else {
+ if (outputBytes == 2) {
+ buffer[outPtr++] = _base64ToAsciiB[(bits >> 6) & 0x3F];
+ }
+ }
+ return outPtr;
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // other methods
+ ////////////////////////////////////////////////////
+ */
+
+ // @Override
+ public String toString() { return _name; }
+}
+
View
90 lib-src/org/codehaus/jackson/Base64Variants.java
@@ -0,0 +1,90 @@
+/* Jackson JSON-processor.
+ *
+ * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi
+ *
+ * Licensed under the License specified in file LICENSE, included with
+ * the source code and binary code bundles.
+ * You may not use this file except in compliance with the License.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codehaus.jackson;
+
+/**
+ * Container for commonly used Base64 variants.
+ *
+ * @author Tatu Saloranta
+ */
+public final class Base64Variants
+{
+ final static String STD_BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ /**
+ * This variant is what most people would think of "the standard"
+ * Base64 encoding.
+ *<p>
+ * See <a href="">wikipedia Base64 entry</a> for details.
+ *<p>
+ * Note that although this can be thought of as the standard variant,
+ * it is <b>not</b> the default for Jackson: no-linefeeds alternative
+ * is because of JSON requirement of escaping all linefeeds.
+ */
+ public final static Base64Variant MIME;
+ static {
+ MIME = new Base64Variant("MIME", STD_BASE64_ALPHABET, true, '=', 76);
+ }
+
+ /**
+ * Slightly non-standard modification of {@link #MIME} which does not
+ * use linefeeds (max line length set to infinite). Useful when linefeeds
+ * wouldn't work well (possibly in attributes), or for minor space savings
+ * (save 1 linefeed per 76 data chars, ie. ~1.4% savings).
+ */
+ public final static Base64Variant MIME_NO_LINEFEEDS;
+ static {
+ MIME_NO_LINEFEEDS = new Base64Variant(MIME, "MIME-NO-LINEFEEDS", Integer.MAX_VALUE);
+ }
+
+ /**
+ * This variant is the one that predates {@link #MIME}: it is otherwise
+ * identical, except that it mandates shorter line length.
+ */
+ public final static Base64Variant PEM = new Base64Variant(MIME, "PEM", true, '=', 64);
+
+ /**
+ * This non-standard variant is usually used when encoded data needs to be
+ * passed via URLs (such as part of GET request). It differs from the
+ * base {@link #MIME} variant in multiple ways.
+ * First, no padding is used: this also means that it generally can not
+ * be written in multiple separate but adjacent chunks (which would not
+ * be the usual use case in any case). Also, no linefeeds are used (max
+ * line length set to infinite). And finally, two characters (plus and
+ * slash) that would need quoting in URLs are replaced with more
+ * optimal alternatives (hyphen and underscore, respectively).
+ */
+ public final static Base64Variant MODIFIED_FOR_URL;
+ static {
+ StringBuffer sb = new StringBuffer(STD_BASE64_ALPHABET);
+ // Replace plus with hyphen, slash with underscore (and no padding)
+ sb.setCharAt(sb.indexOf("+"), '-');
+ sb.setCharAt(sb.indexOf("/"), '_');
+ /* And finally, let's not split lines either, wouldn't work too
+ * well with URLs
+ */
+ MODIFIED_FOR_URL = new Base64Variant("MODIFIED-FOR-URL", sb.toString(), false, Base64Variant.PADDING_CHAR_NONE, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Method used to get the default variant ("MIME_NO_LINEFEEDS") for cases
+ * where caller does not explicitly specify the variant.
+ * We will prefer no-linefeed version because linefeeds in JSON values
+ * must be escaped, making linefeed-containing variants sub-optimal.
+ */
+ public static Base64Variant getDefaultVariant() {
+ return MIME_NO_LINEFEEDS;
+ }
+}
View
48 lib-src/org/codehaus/jackson/JsonEncoding.java
@@ -0,0 +1,48 @@
+package org.codehaus.jackson;
+
+/**
+ * Enumeration that defines legal encodings that can be used
+ * for JSON content, based on list of allowed encodings from
+ * <a href="http://www.ietf.org/rfc/rfc4627.txt">JSON specification</a>.
+ *<p>
+ * Note: if application want to explicitly disregard Encoding
+ * limitations (to read in JSON encoded using an encoding not
+ * listed as allowed), they can use {@link java.io.Reader} /
+ * {@link java.io.Writer} instances as input
+ * source (or output target).
+ */
+public enum JsonEncoding {
+ UTF8("UTF-8", false), // N/A for big-endian, really
+ UTF16_BE("UTF-16BE", true),
+ UTF16_LE("UTF-16LE", false),
+ UTF32_BE("UTF-32BE", true),
+ UTF32_LE("UTF-32LE", false)
+ ;
+
+ final String mJavaName;
+
+ final boolean mBigEndian;
+
+ JsonEncoding(String javaName, boolean bigEndian)
+ {
+ mJavaName = javaName;
+ mBigEndian = bigEndian;
+ }
+
+ /**
+ * Method for accessing encoding name that JDK will support.
+ *
+ * @return Matching encoding name that JDK will support.
+ */
+ public String getJavaName() { return mJavaName; }
+
+ /**
+ * Whether encoding is big-endian (if encoding supports such
+ * notion). If no such distinction is made (as is the case for
+ * {@link #UTF8}), return value is undefined.
+ *
+ * @return True for big-endian encodings; false for little-endian
+ * (or if not applicable)
+ */
+ public boolean isBigEndian() { return mBigEndian; }
+}
View
581 lib-src/org/codehaus/jackson/JsonFactory.java
@@ -0,0 +1,581 @@
+/* Jackson JSON-processor.
+ *
+ * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi
+ *
+ * Licensed under the License specified in file LICENSE, included with
+ * the source code and binary code bundles.
+ * You may not use this file except in compliance with the License.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codehaus.jackson;
+
+import java.io.*;
+import java.lang.ref.SoftReference;
+import java.net.URL;
+
+import org.codehaus.jackson.io.*;
+import org.codehaus.jackson.impl.ByteSourceBootstrapper;
+import org.codehaus.jackson.impl.ReaderBasedParser;
+import org.codehaus.jackson.impl.WriterBasedGenerator;
+import org.codehaus.jackson.sym.BytesToNameCanonicalizer;
+import org.codehaus.jackson.sym.CharsToNameCanonicalizer;
+import org.codehaus.jackson.util.BufferRecycler;
+
+/**
+ * The main factory class of Jackson package, used to configure and
+ * construct reader (aka parser, {@link JsonParser})
+ * and writer (aka generator, {@link JsonGenerator})
+ * instances.
+ *<p>
+ * Factory instances are thread-safe and reusable after configuration
+ * (if any). Typically applications and services use only a single
+ * globally shared factory instance, unless they need differently
+ * configured factories. Factory reuse is important if efficiency matters;
+ * most recycling of expensive construct is done on per-factory basis.
+ *<p>
+ * Creation of a factory instance is a light-weight operation,
+ * and since there is no need for pluggable alternative implementations
+ * (as there is no "standard" json processor API to implement),
+ * the default constructor is used for constructing factory
+ * instances.
+ *
+ * @author Tatu Saloranta
+ */
+public class JsonFactory
+{
+ /**
+ * Bitfield (set of flags) of all parser features that are enabled
+ * by default.
+ */
+ final static int DEFAULT_PARSER_FEATURE_FLAGS = JsonParser.Feature.collectDefaults();
+
+ /**
+ * Bitfield (set of flags) of all generator features that are enabled
+ * by default.
+ */
+ final static int DEFAULT_GENERATOR_FEATURE_FLAGS = JsonGenerator.Feature.collectDefaults();
+
+ /*
+ /******************************************************
+ /* Buffer, symbol table management
+ /******************************************************
+ */
+
+ /**
+ * This <code>ThreadLocal</code> contains a {@link SoftRerefence}
+ * to a {@link BufferRecycler} used to provide a low-cost
+ * buffer recycling between reader and writer instances.
+ */
+ final static ThreadLocal<SoftReference<BufferRecycler>> _recyclerRef = new ThreadLocal<SoftReference<BufferRecycler>>();
+
+ /**
+ * Each factory comes equipped with a shared root symbol table.
+ * It should not be linked back to the original blueprint, to
+ * avoid contents from leaking between factories.
+ */
+ protected CharsToNameCanonicalizer _rootCharSymbols = CharsToNameCanonicalizer.createRoot();
+
+ /**
+ * Alternative to the basic symbol table, some stream-based
+ * parsers use different name canonicalization method.
+ *<p>
+ * TODO: should clean up this; looks messy having 2 alternatives
+ * with not very clear differences.
+ */
+ protected BytesToNameCanonicalizer _rootByteSymbols = BytesToNameCanonicalizer.createRoot();
+
+ /*
+ /******************************************************
+ /* Configuration
+ /******************************************************
+ */
+
+ /**
+ * Object that implements conversion functionality between
+ * Java objects and Json content. For base JsonFactory implementation
+ * usually not set by default, but can be explicitly set.
+ * Sub-classes (like @link org.codehaus.jackson.map.MappingJsonFactory}
+ * usually provide an implementation.
+ */
+ protected ObjectCodec _objectCodec;
+
+ protected int _parserFeatures = DEFAULT_PARSER_FEATURE_FLAGS;
+
+ protected int _generatorFeatures = DEFAULT_GENERATOR_FEATURE_FLAGS;
+
+ /**
+ * Default constructor used to create factory instances.
+ * Creation of a factory instance is a light-weight operation,
+ * but it is still a good idea to reuse limited number of
+ * factory instances (and quite often just a single instance):
+ * factories are used as context for storing some reused
+ * processing objects (such as symbol tables parsers use)
+ * and this reuse only works within context of a single
+ * factory instance.
+ */
+ public JsonFactory() { this(null); }
+
+ public JsonFactory(ObjectCodec oc) { _objectCodec = oc; }
+
+ /*
+ /******************************************************
+ /* Configuration, parser settings
+ /******************************************************
+ */
+
+ /**
+ * Method for enabling or disabling specified parser feature
+ * (check {@link JsonParser.Feature} for list of features)
+ *
+ * @since 1.2
+ */
+ public final JsonFactory configure(JsonParser.Feature f, boolean state)
+ {
+ if (state) {
+ enable(f);
+ } else {
+ disable(f);
+ }
+ return this;
+ }
+
+ /**
+ * Method for enabling specified parser feature
+ * (check {@link JsonParser.Feature} for list of features)
+ *
+ * @since 1.2
+ */
+ public JsonFactory enable(JsonParser.Feature f) {
+ _parserFeatures |= f.getMask();
+ return this;
+ }
+
+ /**
+ * Method for disabling specified parser features
+ * (check {@link JsonParser.Feature} for list of features)
+ *
+ * @since 1.2
+ */
+ public JsonFactory disable(JsonParser.Feature f) {
+ _parserFeatures &= ~f.getMask();
+ return this;
+ }
+
+ /**
+ * Checked whether specified parser feature is enabled.
+ *
+ * @since 1.2
+ */
+ public final boolean isEnabled(JsonParser.Feature f) {
+ return (_parserFeatures & f.getMask()) != 0;
+ }
+
+ // // // Older deprecated (as of 1.2) methods
+
+ /**
+ * @deprecated Use {@link #enable(JsonParser.Feature)} instead
+ */
+ public final void enableParserFeature(JsonParser.Feature f) {
+ enable(f);
+ }
+
+ /**
+ * @deprecated Use {@link #disable(JsonParser.Feature)} instead
+ */
+ public final void disableParserFeature(JsonParser.Feature f) {
+ disable(f);
+ }
+
+ /**
+ * @deprecated Use {@link #configure(JsonParser.Feature, boolean)} instead
+ */
+ public final void setParserFeature(JsonParser.Feature f, boolean state) {
+ configure(f, state);
+ }
+
+ /**
+ * @deprecated Use {@link #isEnabled(JsonParser.Feature)} instead
+ */
+ public final boolean isParserFeatureEnabled(JsonParser.Feature f) {
+ return (_parserFeatures & f.getMask()) != 0;
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // Configuration, generator settings
+ //////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for enabling or disabling specified generator feature
+ * (check {@link JsonGenerator.Feature} for list of features)
+ *
+ * @since 1.2
+ */
+ public final JsonFactory configure(JsonGenerator.Feature f, boolean state) {
+ if (state) {
+ enable(f);
+ } else {
+ disable(f);
+ }
+ return this;
+ }
+
+
+ /**
+ * Method for enabling specified generator features
+ * (check {@link JsonGenerator.Feature} for list of features)
+ *
+ * @since 1.2
+ */
+ public JsonFactory enable(JsonGenerator.Feature f) {
+ _generatorFeatures |= f.getMask();
+ return this;
+ }
+
+ /**
+ * Method for disabling specified generator feature
+ * (check {@link JsonGenerator.Feature} for list of features)
+ *
+ * @since 1.2
+ */
+ public JsonFactory disable(JsonGenerator.Feature f) {
+ _generatorFeatures &= ~f.getMask();
+ return this;
+ }
+
+ /**
+ * Checked whether specified generator feature is enabled.
+ *
+ * @since 1.2
+ */
+ public final boolean isEnabled(JsonGenerator.Feature f) {
+ return (_generatorFeatures & f.getMask()) != 0;
+ }
+
+ // // // Older deprecated (as of 1.2) methods
+
+ /**
+ * @deprecated Use {@link #enable(JsonGenerator.Feature)} instead
+ */
+ public final void enableGeneratorFeature(JsonGenerator.Feature f) {
+ enable(f);
+ }
+
+ /**
+ * @deprecated Use {@link #disable(JsonGenerator.Feature)} instead
+ */
+ public final void disableGeneratorFeature(JsonGenerator.Feature f) {
+ disable(f);
+ }
+
+ /**
+ * @deprecated Use {@link #configure(JsonGenerator.Feature, boolean)} instead
+ */
+ public final void setGeneratorFeature(JsonGenerator.Feature f, boolean state) {
+ configure(f, state);
+ }
+
+ /**
+ * @deprecated Use {@link #isEnabled(JsonGenerator.Feature)} instead
+ */
+ public final boolean isGeneratorFeatureEnabled(JsonGenerator.Feature f) {
+ return isEnabled(f);
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // Configuration, other
+ //////////////////////////////////////////////////////
+ */
+
+ public JsonFactory setCodec(ObjectCodec oc) {
+ _objectCodec = oc;
+ return this;
+ }
+
+ public ObjectCodec getCodec() { return _objectCodec; }
+
+ /*
+ //////////////////////////////////////////////////////
+ // Reader factories
+ //////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for constructing json parser instance to parse
+ * contents of specified file. Encoding is auto-detected
+ * from contents according to json specification recommended
+ * mechanism.
+ *<p>
+ * Underlying input stream (needed for reading contents)
+ * will be <b>owned</b> (and managed, i.e. closed as need be) by
+ * the parser, since caller has no access to it.
+ *
+ * @param f File that contains JSON content to parse
+ */
+ public JsonParser createJsonParser(File f)
+ throws IOException, JsonParseException
+ {
+ return _createJsonParser(new FileInputStream(f), _createContext(f, true));
+ }
+
+ /**
+ * Method for constructing json parser instance to parse
+ * contents of resource reference by given URL.
+ * Encoding is auto-detected
+ * from contents according to json specification recommended
+ * mechanism.
+ *<p>
+ * Underlying input stream (needed for reading contents)
+ * will be <b>owned</b> (and managed, i.e. closed as need be) by
+ * the parser, since caller has no access to it.
+ *
+ * @param url URL pointing to resource that contains JSON content to parse
+ */
+ public JsonParser createJsonParser(URL url)
+ throws IOException, JsonParseException
+ {
+ return _createJsonParser(_optimizedStreamFromURL(url), _createContext(url, true));
+ }
+
+ /**
+ * Method for constructing json parser instance to parse
+ * the contents accessed via specified input stream.
+ *<p>
+ * The input stream will <b>not be owned</b> by
+ * the parser, it will still be managed (i.e. closed if
+ * end-of-stream is reacher, or parser close method called)
+ * if (and only if) {@link org.codehaus.jackson.JsonParser.Feature#AUTO_CLOSE_SOURCE}
+ * is enabled.
+ *<p>
+ * Note: no encoding argument is taken since it can always be
+ * auto-detected as suggested by Json RFC.
+ *
+ * @param in InputStream to use for reading JSON content to parse
+ */
+ public JsonParser createJsonParser(InputStream in)
+ throws IOException, JsonParseException
+ {
+ return _createJsonParser(in, _createContext(in, false));
+ }
+
+ /**
+ * Method for constructing json parser instance to parse
+ * the contents accessed via specified Reader.
+ <p>
+ * The read stream will <b>not be owned</b> by
+ * the parser, it will still be managed (i.e. closed if
+ * end-of-stream is reacher, or parser close method called)
+ * if (and only if) {@link org.codehaus.jackson.JsonParser.Feature#AUTO_CLOSE_SOURCE}
+ * is enabled.
+ *<p>
+ *
+ * @param r Reader to use for reading JSON content to parse
+ */
+ public JsonParser createJsonParser(Reader r)
+ throws IOException, JsonParseException
+ {
+ return _createJsonParser(r, _createContext(r, false));
+ }
+
+ public JsonParser createJsonParser(byte[] data)
+ throws IOException, JsonParseException
+ {
+ return _createJsonParser(data, 0, data.length, _createContext(data, true));
+ }
+
+ public JsonParser createJsonParser(byte[] data, int offset, int len)
+ throws IOException, JsonParseException
+ {
+ return _createJsonParser(data, offset, len, _createContext(data, true));
+ }
+
+ public JsonParser createJsonParser(String content)
+ throws IOException, JsonParseException
+ {
+ // true -> we own the Reader (and must close); not a big deal
+ Reader r = new StringReader(content);
+ return _createJsonParser(r, _createContext(r, true));
+ }
+
+ /*
+ //////////////////////////////////////////////////////
+ // Generator factories
+ //////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for constructing json generator for writing json content
+ * using specified output stream.
+ * Encoding to use must be specified, and needs to be one of available
+ * types (as per JSON specification).
+ *<p>
+ * Underlying stream <b>is NOT owned</b> by the generator constructed,
+ * so that generator will NOT close the output stream when
+ * {@link JsonGenerator#close} is called (unless auto-closing
+ * feature,
+ * {@link org.codehaus.jackson.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
+ * is enabled).
+ * Using application needs to close it explicitly if this is the case.
+ *
+ * @param out OutputStream to use for writing json content
+ * @param enc Character encoding to use
+ */
+ public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc)
+ throws IOException
+ {
+ // false -> we won't manage the stream unless explicitly directed to
+ IOContext ctxt = _createContext(out, false);
+ ctxt.setEncoding(enc);
+ return _createJsonGenerator(_createWriter(out, enc, ctxt), ctxt);
+ }
+
+ /**
+ * Method for constructing json generator for writing json content
+ * using specified Writer.
+ *<p>
+ * Underlying stream <b>is NOT owned</b> by the generator constructed,
+ * so that generator will NOT close the Reader when
+ * {@link JsonGenerator#close} is called (unless auto-closing
+ * feature,
+ * {@link org.codehaus.jackson.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
+ * Using application needs to close it explicitly.
+ *
+ * @param out Writer to use for writing json content
+ */
+ public JsonGenerator createJsonGenerator(Writer out)
+ throws IOException
+ {
+ IOContext ctxt = _createContext(out, false);
+ return _createJsonGenerator(out, ctxt);
+ }
+
+ /**
+ * Method for constructing json generator for writing json content
+ * to specified file, overwriting contents it might have (or creating
+ * it if such file does not yet exist).
+ * Encoding to use must be specified, and needs to be one of available
+ * types (as per JSON specification).
+ *<p>
+ * Underlying stream <b>is owned</b> by the generator constructed,
+ * i.e. generator will handle closing of file when
+ * {@link JsonGenerator#close} is called.
+ *
+ * @param f File to write contents to
+ * @param enc Character encoding to use
+ */
+ public JsonGenerator createJsonGenerator(File f, JsonEncoding enc)
+ throws IOException
+ {
+ OutputStream out = new FileOutputStream(f);
+ // true -> yes, we have to manage the stream since we created it
+ IOContext ctxt = _createContext(out, true);
+ ctxt.setEncoding(enc);
+ return _createJsonGenerator(_createWriter(out, enc, ctxt), ctxt);
+ }
+
+ /*
+ ///////////////////////////////////////////////////////////
+ // Internal methods
+ ///////////////////////////////////////////////////////////
+ */
+
+ /**
+ * Overridable construction method that actually instantiates desired generator.
+ */
+ protected IOContext _createContext(Object srcRef, boolean resourceManaged)
+ {
+ return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
+ }
+
+ /**
+ * Overridable construction method that actually instantiates desired parser.
+ */
+ protected JsonParser _createJsonParser(InputStream in, IOContext ctxt)
+ throws IOException, JsonParseException
+ {
+ return new ByteSourceBootstrapper(ctxt, in).constructParser(_parserFeatures, _objectCodec, _rootByteSymbols, _rootCharSymbols);
+ }
+
+ protected JsonParser _createJsonParser(Reader r, IOContext ctxt)
+ throws IOException, JsonParseException
+ {
+ return new ReaderBasedParser(ctxt, _parserFeatures, r, _objectCodec,
+ _rootCharSymbols.makeChild(isEnabled(JsonParser.Feature.CANONICALIZE_FIELD_NAMES),
+ isEnabled(JsonParser.Feature.INTERN_FIELD_NAMES)));
+ }
+
+ protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt)
+ throws IOException, JsonParseException
+ {
+ // true -> managed (doesn't really matter; we have no stream!)
+ return new ByteSourceBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures, _objectCodec, _rootByteSymbols, _rootCharSymbols);
+ }
+
+ /**
+ * Overridable construction method that actually instantiates desired generator
+ */
+ protected JsonGenerator _createJsonGenerator(Writer out, IOContext ctxt)
+ throws IOException
+ {
+ return new WriterBasedGenerator(ctxt, _generatorFeatures, _objectCodec, out);
+ }
+
+ /**
+ * Method used by factory to create buffer recycler instances
+ * for parsers and generators.
+ *<p>
+ * Note: only public to give access for <code>ObjectMapper</code>
+ */
+ public BufferRecycler _getBufferRecycler()
+ {
+ SoftReference<BufferRecycler> ref = _recyclerRef.get();
+ BufferRecycler br = (ref == null) ? null : ref.get();
+
+ if (br == null) {
+ br = new BufferRecycler();
+ if (ref == null) {
+ _recyclerRef.set(new SoftReference<BufferRecycler>(br));
+ }
+ }
+ return br;
+ }
+
+ /**
+ * Helper methods used for constructing an optimal stream for
+ * parsers to use, when input is to be read from an URL.
+ * This helps when reading file content via URL.
+ */
+ protected InputStream _optimizedStreamFromURL(URL url)
+ throws IOException
+ {
+ if ("file".equals(url.getProtocol())) {
+ /* Can not do this if the path refers
+ * to a network drive on windows. This fixes the problem;
+ * might not be needed on all platforms (NFS?), but should not
+ * matter a lot: performance penalty of extra wrapping is more
+ * relevant when accessing local file system.
+ */
+ String host = url.getHost();
+ if (host == null || host.length() == 0) {
+ return new FileInputStream(url.getPath());
+ }
+ }
+ return url.openStream();
+ }
+
+ protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
+ {
+ if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8
+ return new UTF8Writer(ctxt, out);
+ }
+ // not optimal, but should do unless we really care about UTF-16/32 encoding speed
+ return new OutputStreamWriter(out, enc.getJavaName());
+ }
+}
View
27 lib-src/org/codehaus/jackson/JsonGenerationException.java
@@ -0,0 +1,27 @@
+package org.codehaus.jackson;
+
+/**
+ * Exception type for exceptions during JSON writing, such as trying
+ * to output content in wrong context (non-matching end-array or end-object,
+ * for example).
+ */
+public class JsonGenerationException
+ extends JsonProcessingException
+{
+ final static long serialVersionUID = 123; // Stupid eclipse...
+
+ public JsonGenerationException(Throwable rootCause)
+ {
+ super(rootCause);
+ }
+
+ public JsonGenerationException(String msg)
+ {
+ super(msg, (JsonLocation)null);
+ }
+
+ public JsonGenerationException(String msg, Throwable rootCause)
+ {
+ super(msg, (JsonLocation)null, rootCause);
+ }
+}
View
875 lib-src/org/codehaus/jackson/JsonGenerator.java
@@ -0,0 +1,875 @@
+/* Jackson JSON-processor.
+ *
+ * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi
+ *
+ * Licensed under the License specified in file LICENSE, included with
+ * the source code and binary code bundles.
+ * You may not use this file except in compliance with the License.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codehaus.jackson;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * Base class that defines public API for writing Json content.
+ * Instances are created using factory methods of
+ * a {@link JsonFactory} instance.
+ *
+ * @author Tatu Saloranta
+ */
+public abstract class JsonGenerator
+ implements Closeable
+{
+ /**
+ * Enumeration that defines all togglable features for generators.
+ */
+ public enum Feature {
+ /**
+ * Feature that determines whether generator will automatically
+ * close underlying output target that is NOT owned by the
+ * generator.
+ * If disabled, calling application has to separately
+ * close the underlying {@link OutputStream} and {@link Writer}
+ * instances used to create the generator. If enabled, generator
+ * will handle closing, as long as generator itself gets closed:
+ * this happens when end-of-input is encountered, or generator
+ * is closed by a call to {@link JsonGenerator#close}.
+ *<p>
+ * Feature is enabled by default.
+ */
+ AUTO_CLOSE_TARGET(true)
+
+ /**
+ * Feature that determines what happens when the generator is
+ * closed while there are still unmatched
+ * {@link JsonToken#START_ARRAY} or {@link JsonToken#START_OBJECT}
+ * entries in output content. If enabled, such Array(s) and/or
+ * Object(s) are automatically closed; if disabled, nothing
+ * specific is done.
+ *<p>
+ * Feature is enabled by default.
+ */
+ ,AUTO_CLOSE_JSON_CONTENT(true)
+
+ /**
+ * Feature that determines whether Json Object field names are
+ * quoted using double-quotes, as specified by Json specification
+ * or not. Ability to disable quoting was added to support use
+ * cases where they are not usually expected, which most commonly
+ * occurs when used straight from javascript.
+ */
+ ,QUOTE_FIELD_NAMES(true)
+
+ /**
+ * Feature that determines whether "exceptional" (not real number)
+ * float/double values are outputted as quoted strings.
+ * The values checked are Double.Nan,
+ * Double.POSITIVE_INFINITY and Double.NEGATIVE_INIFINTY (and
+ * associated Float values).
+ * If feature is disabled, these numbers are still output using
+ * associated literal values, resulting in non-conformant
+ * output
+ *<p>
+ * Feature is enabled by default.
+ */
+ ,QUOTE_NON_NUMERIC_NUMBERS(true)
+
+ /**
+ * Feature that forces all Java numbers to be written as JSON strings.
+ * Default state is 'false', meaning that Java numbers are to
+ * be serialized using basic numeric serialization (as JSON
+ * numbers, integral or floating point). If enabled, all such
+ * numeric values are instead written out as JSON Strings.
+ *<p>
+ * One use case is to avoid problems with Javascript limitations:
+ * since Javascript standard specifies that all number handling
+ * should be done using 64-bit IEEE 754 floating point values,
+ * result being that some 64-bit integer values can not be
+ * accurately represent (as mantissa is only 51 bit wide).
+ *
+ * @since 1.3
+ */
+ ,WRITE_NUMBERS_AS_STRINGS(false)
+
+ ;
+
+ final boolean _defaultState;
+
+ final int _mask;
+
+ /**
+ * Method that calculates bit set (flags) of all features that
+ * are enabled by default.
+ */
+ public static int collectDefaults()
+ {
+ int flags = 0;
+ for (Feature f : values()) {
+ if (f.enabledByDefault()) {
+ flags |= f.getMask();
+ }
+ }
+ return flags;
+ }
+
+ private Feature(boolean defaultState) {
+ _defaultState = defaultState;
+ _mask = (1 << ordinal());
+ }
+
+ public boolean enabledByDefault() { return _defaultState; }
+
+ public int getMask() { return _mask; }
+ };
+
+ // // // Configuration:
+
+ /**
+ * Object that handles pretty-printing (usually additional
+ * white space to make results more human-readable) during
+ * output. If null, no pretty-printing is done.
+ */
+ protected PrettyPrinter _cfgPrettyPrinter;
+
+ protected JsonGenerator() {
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, configuration
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for enabling specified parser features:
+ * check {@link Feature} for list of available features.
+ *
+ * @return Generator itself (this), to allow chaining
+ *
+ * @since 1.2
+ */
+ public abstract JsonGenerator enable(Feature f);
+
+ /**
+ * Method for disabling specified features
+ * (check {@link Feature} for list of features)
+ *
+ * @return Generator itself (this), to allow chaining
+ *
+ * @since 1.2
+ */
+ public abstract JsonGenerator disable(Feature f);
+
+ /**
+ * Method for enabling or disabling specified feature:
+ * check {@link Feature} for list of available features.
+ *
+ * @return Generator itself (this), to allow chaining
+ *
+ * @since 1.2
+ */
+ public JsonGenerator configure(Feature f, boolean state)
+ {
+ if (state) {
+ enable(f);
+ } else {
+ disable(f);
+ }
+ return this;
+ }
+
+ /**
+ * Method for checking whether given feature is enabled.
+ * Check {@link Feature} for list of available features.
+ *
+ * @since 1.2
+ */
+ public abstract boolean isEnabled(Feature f);
+
+ /**
+ * Method that can be called to set or reset the object to
+ * use for writing Java objects as JsonContent
+ * (using method {@link #writeObject}).
+ *
+ * @return Generator itself (this), to allow chaining
+ */
+ public abstract JsonGenerator setCodec(ObjectCodec oc);
+
+ /**
+ * Method for accessing the object used for writing Java
+ * object as Json content
+ * (using method {@link #writeObject}).
+ */
+ public abstract ObjectCodec getCodec();
+
+ // // // Older deprecated versions
+
+ /** @deprecated Use {@link #enable} instead
+ */
+ public void enableFeature(Feature f) { enable(f); }
+
+ /** @deprecated Use {@link #disable} instead
+ */
+ public void disableFeature(Feature f) { disable(f); }
+
+ /** @deprecated Use {@link #configure} instead
+ */
+ public void setFeature(Feature f, boolean state) { configure(f, state); }
+
+ /** @deprecated Use {@link #isEnabled} instead
+ */
+ public boolean isFeatureEnabled(Feature f) { return isEnabled(f); }
+
+
+ /*
+ ////////////////////////////////////////////////////
+ // Configuring generator
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for setting a custom pretty printer, which is usually
+ * used to add indentation for improved human readability.
+ * By default, generator does not do pretty printing.
+ *<p>
+ * To use the default pretty printer that comes with core
+ * Jackson distribution, call {@link #useDefaultPrettyPrinter}
+ * instead.
+ *
+ * @return Generator itself (this), to allow chaining
+ */
+ public JsonGenerator setPrettyPrinter(PrettyPrinter pp) {
+ _cfgPrettyPrinter = pp;
+ return this;
+ }
+
+ /**
+ * Convenience method for enabling pretty-printing using
+ * the default pretty printer
+ * ({@link org.codehaus.jackson.impl.DefaultPrettyPrinter}).
+ *
+ * @return Generator itself (this), to allow chaining
+ */
+ public abstract JsonGenerator useDefaultPrettyPrinter();
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, write methods, structural
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for writing starting marker of a Json Array value
+ * (character '['; plus possible white space decoration
+ * if pretty-printing is enabled).
+ *<p>
+ * Array values can be written in any context where values
+ * are allowed: meaning everywhere except for when
+ * a field name is expected.
+ */
+ public abstract void writeStartArray()
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for writing closing marker of a Json Array value
+ * (character ']'; plus possible white space decoration
+ * if pretty-printing is enabled).
+ *<p>
+ * Marker can be written if the innermost structured type
+ * is Array.
+ */
+ public abstract void writeEndArray()
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for writing starting marker of a Json Object value
+ * (character '{'; plus possible white space decoration
+ * if pretty-printing is enabled).
+ *<p>
+ * Object values can be written in any context where values
+ * are allowed: meaning everywhere except for when
+ * a field name is expected.
+ */
+ public abstract void writeStartObject()
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for writing closing marker of a Json Object value
+ * (character '}'; plus possible white space decoration
+ * if pretty-printing is enabled).
+ *<p>
+ * Marker can be written if the innermost structured type
+ * is Object, and the last written event was either a
+ * complete value, or START-OBJECT marker (see Json specification
+ * for more details).
+ */
+ public abstract void writeEndObject()
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for writing a field name (json String surrounded by
+ * double quotes: syntactically identical to a json String value),
+ * possibly decorated by white space if pretty-printing is enabled.
+ *<p>
+ * Field names can only be written in Object context (check out
+ * Json specification for details), when field name is expected
+ * (field names alternate with values).
+ */
+ public abstract void writeFieldName(String name)
+ throws IOException, JsonGenerationException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, write methods, textual/binary
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for outputting a String value. Depending on context
+ * this means either array element, (object) field value or
+ * a stand alone String; but in all cases, String will be
+ * surrounded in double quotes, and contents will be properly
+ * escaped as required by Json specification.
+ */
+ public abstract void writeString(String text)
+ throws IOException, JsonGenerationException;
+
+ public abstract void writeString(char[] text, int offset, int len)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Fallback method which can be used to make generator copy
+ * input text verbatim with <b>no</b> modifications (including
+ * that no quoting is done and no separators are added even
+ * if context [array, object] would otherwise require such).
+ * If such separators are desired, use
+ * {@link #writeRawValue(String)} instead.
+ */
+ public abstract void writeRaw(String text)
+ throws IOException, JsonGenerationException;
+
+ public abstract void writeRaw(String text, int offset, int len)
+ throws IOException, JsonGenerationException;
+
+ public abstract void writeRaw(char[] text, int offset, int len)
+ throws IOException, JsonGenerationException;
+
+ public abstract void writeRaw(char c)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Fallback method which can be used to make generator copy
+ * input text verbatim without any modifications, but assuming
+ * it must constitute a single legal Json value (number, string,
+ * boolean, null, Array or List). Assuming this, proper separators
+ * are added if and as needed (comma or colon), and generator
+ * state updated to reflect this.
+ */
+ public abstract void writeRawValue(String text)
+ throws IOException, JsonGenerationException;
+
+ public abstract void writeRawValue(String text, int offset, int len)
+ throws IOException, JsonGenerationException;
+
+ public abstract void writeRawValue(char[] text, int offset, int len)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method that will output given chunk of binary data as base64
+ * encoded, as a complete String value (surrounded by double quotes).
+ * This method defaults
+ *<p>
+ * Note: because Json Strings can not contain unescaped linefeeds,
+ * if linefeeds are included (as per last argument), they must be
+ * escaped. This adds overhead for decoding without improving
+ * readability.
+ * Alternatively if linefeeds are not included,
+ * resulting String value may violate the requirement of base64
+ * RFC which mandates line-length of 76 characters and use of
+ * linefeeds. However, all {@link JsonParser} implementations
+ * are required to accept such "long line base64"; as do
+ * typical production-level base64 decoders.
+ *
+ * @param b64variant Base64 variant to use: defines details such as
+ * whether padding is used (and if so, using which character);
+ * what is the maximum line length before adding linefeed,
+ * and also the underlying alphabet to use.
+ */
+ public abstract void writeBinary(Base64Variant b64variant,
+ byte[] data, int offset, int len)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
+ * but default to using the Jackson default Base64 variant
+ * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}).
+ */
+ public void writeBinary(byte[] data, int offset, int len)
+ throws IOException, JsonGenerationException
+ {
+ writeBinary(Base64Variants.getDefaultVariant(), data, offset, len);
+ }
+
+ /**
+ * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
+ * but assumes default to using the Jackson default Base64 variant
+ * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}). Also
+ * assumes that whole byte array is to be output.
+ */
+ public void writeBinary(byte[] data)
+ throws IOException, JsonGenerationException
+ {
+ writeBinary(Base64Variants.getDefaultVariant(), data, 0, data.length);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, write methods, other value types
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for outputting given value as Json number.
+ * Can be called in any context where a value is expected
+ * (Array value, Object field value, root-level value).
+ * Additional white space may be added around the value
+ * if pretty-printing is enabled.
+ */
+ public abstract void writeNumber(int v)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for outputting given value as Json number.
+ * Can be called in any context where a value is expected
+ * (Array value, Object field value, root-level value).
+ * Additional white space may be added around the value
+ * if pretty-printing is enabled.
+ */
+ public abstract void writeNumber(long v)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for outputting given value as Json number.
+ * Can be called in any context where a value is expected
+ * (Array value, Object field value, root-level value).
+ * Additional white space may be added around the value
+ * if pretty-printing is enabled.
+ */
+ public abstract void writeNumber(BigInteger v)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for outputting indicate Json numeric value.
+ * Can be called in any context where a value is expected
+ * (Array value, Object field value, root-level value).
+ * Additional white space may be added around the value
+ * if pretty-printing is enabled.
+ */
+ public abstract void writeNumber(double d)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for outputting indicate Json numeric value.
+ * Can be called in any context where a value is expected
+ * (Array value, Object field value, root-level value).
+ * Additional white space may be added around the value
+ * if pretty-printing is enabled.
+ */
+ public abstract void writeNumber(float f)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for outputting indicate Json numeric value.
+ * Can be called in any context where a value is expected
+ * (Array value, Object field value, root-level value).
+ * Additional white space may be added around the value
+ * if pretty-printing is enabled.
+ */
+ public abstract void writeNumber(BigDecimal dec)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Write method that can be used for custom numeric types that can
+ * not be (easily?) converted to "standard" Java number types.
+ * Because numbers are not surrounded by double quotes, regular
+ * {@link #writeString} method can not be used; nor
+ * {@link #writeRaw} because that does not properly handle
+ * value separators needed in Array or Object contexts.
+ *<p>
+ * Note: because of lack of type safety, some generator
+ * implementations may not be able to implement this
+ * method. For example, if a binary json format is used,
+ * it may require type information for encoding; similarly
+ * for generator-wrappers around Java objects or Json nodes.
+ * If implementation does not implement this method,
+ * it needs to throw {@link UnsupportedOperationException}.
+ */
+ public abstract void writeNumber(String encodedValue)
+ throws IOException, JsonGenerationException,
+ UnsupportedOperationException;
+
+ /**
+ * Method for outputting literal Json boolean value (one of
+ * Strings 'true' and 'false').
+ * Can be called in any context where a value is expected
+ * (Array value, Object field value, root-level value).
+ * Additional white space may be added around the value
+ * if pretty-printing is enabled.
+ */
+ public abstract void writeBoolean(boolean state)
+ throws IOException, JsonGenerationException;
+
+ /**
+ * Method for outputting literal Json null value.
+ * Can be called in any context where a value is expected
+ * (Array value, Object field value, root-level value).
+ * Additional white space may be added around the value
+ * if pretty-printing is enabled.
+ */
+ public abstract void writeNull()
+ throws IOException, JsonGenerationException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, write methods, serializing Java objects
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for writing given Java object (POJO) as Json.
+ * Exactly how the object gets written depends on object
+ * in question (ad on codec, its configuration); for most
+ * beans it will result in Json object, but for others Json
+ * array, or String or numeric value (and for nulls, Json
+ * null literal.
+ * <b>NOTE</b>: generator must have its <b>object codec</b>
+ * set to non-null value; for generators created by a mapping
+ * factory this is the case, for others not.
+ */
+ public abstract void writeObject(Object pojo)
+ throws IOException, JsonProcessingException;
+
+ /**
+ * Method for writing given Json tree (expressed as a tree
+ * where given JsonNode is the root) using this generator.
+ * This will generally just call
+ * {@link #writeObject} with given node, but is added
+ * for convenience and to make code more explicit in cases
+ * where it deals specifically with trees.
+ */
+ public abstract void writeTree(JsonNode rootNode)
+ throws IOException, JsonProcessingException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, convenience field write methods
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that has a String value. Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeString(value);
+ *</pre>
+ */
+ public final void writeStringField(String fieldName, String value)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeString(value);
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that has a boolean value. Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeBoolean(value);
+ *</pre>
+ */
+ public final void writeBooleanField(String fieldName, boolean value)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeBoolean(value);
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that has Json literal value null. Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeNull();
+ *</pre>
+ */
+ public final void writeNullField(String fieldName)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeNull();
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that has the specified numeric value. Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeNumber(value);
+ *</pre>
+ */
+ public final void writeNumberField(String fieldName, int value)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeNumber(value);
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that has the specified numeric value. Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeNumber(value);
+ *</pre>
+ */
+ public final void writeNumberField(String fieldName, long value)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeNumber(value);
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that has the specified numeric value. Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeNumber(value);
+ *</pre>
+ */
+ public final void writeNumberField(String fieldName, double value)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeNumber(value);
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that has the specified numeric value. Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeNumber(value);
+ *</pre>
+ */
+ public final void writeNumberField(String fieldName, float value)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeNumber(value);
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that has the specified numeric value.
+ * Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeNumber(value);
+ *</pre>
+ */
+ public final void writeNumberField(String fieldName, BigDecimal value)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeNumber(value);
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that contains specified data in base64-encoded form.
+ * Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeBinary(value);
+ *</pre>
+ */
+ public final void writeBinaryField(String fieldName, byte[] data)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeBinary(data);
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * (that will contain a Json Array value), and the START_ARRAY marker.
+ * Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeStartArray();
+ *</pre>
+ *<p>
+ * Note: caller still has to take care to close the array
+ * (by calling {#link #writeEndArray}) after writing all values
+ * of the value Array.
+ */
+ public final void writeArrayFieldStart(String fieldName)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeStartArray();
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * (that will contain a Json Object value), and the START_OBJECT marker.
+ * Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeStartObject();
+ *</pre>
+ *<p>
+ * Note: caller still has to take care to close the Object
+ * (by calling {#link #writeEndObject}) after writing all
+ * entries of the value Object.
+ */
+ public final void writeObjectFieldStart(String fieldName)
+ throws IOException, JsonGenerationException
+ {
+ writeFieldName(fieldName);
+ writeStartObject();
+ }
+
+ /**
+ * Convenience method for outputting a field entry ("member")
+ * that has contents of specific Java object as its value.
+ * Equivalent to:
+ *<pre>
+ * writeFieldName(fieldName);
+ * writeObject(pojo);
+ *</pre>
+ */
+ public final void writeObjectField(String fieldName, Object pojo)
+ throws IOException, JsonProcessingException
+ {
+ writeFieldName(fieldName);
+ writeObject(pojo);
+ }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, copy-through methods
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method for copying contents of the current event that
+ * the given parser instance points to.
+ * Note that the method <b>will not</b> copy any other events,
+ * such as events contained within Json Array or Object structures.
+ *<p>
+ * Calling this method will not advance the given
+ * parser, although it may cause parser to internally process
+ * more data (if it lazy loads contents of value events, for example)
+ */
+ public abstract void copyCurrentEvent(JsonParser jp)
+ throws IOException, JsonProcessingException;
+
+ /**
+ * Method for copying contents of the current event
+ * <b>and following events that it encloses</b>
+ * the given parser instance points to.
+ *<p>
+ * So what constitutes enclosing? Here is the list of
+ * events that have associated enclosed events that will
+ * get copied:
+ *<ul>
+ * <li>{@link JsonToken#START_OBJECT}:
+ * all events up to and including matching (closing)
+ * {@link JsonToken#END_OBJECT} will be copied
+ * </li>
+ * <li>{@link JsonToken#START_ARRAY}
+ * all events up to and including matching (closing)
+ * {@link JsonToken#END_ARRAY} will be copied
+ * </li>
+ * <li>{@link JsonToken#FIELD_NAME} the logical value (which
+ * can consist of a single scalar value; or a sequence of related
+ * events for structured types (Json Arrays, Objects)) will
+ * be copied along with the name itself. So essentially the
+ * whole <b>field entry</b> (name and value) will be copied.
+ * </li>
+ *</ul>
+ *<p>
+ * After calling this method, parser will point to the
+ * <b>last event</b> that was copied. This will either be
+ * the event parser already pointed to (if there were no
+ * enclosed events), or the last enclosed event copied.
+ */
+ public abstract void copyCurrentStructure(JsonParser jp)
+ throws IOException, JsonProcessingException;
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, context access
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * @return Context object that can give information about logical
+ * position within generated json content.
+ */
+ public abstract JsonStreamContext getOutputContext();
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, buffer handling
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called to flush any buffered content to the underlying
+ * target (output stream, writer), and to flush the target itself
+ * as well.
+ */
+ public abstract void flush()
+ throws IOException;
+
+ /**
+ * Method that can be called to determine whether this generator
+ * is closed or not. If it is closed, no more output can be done.
+ */
+ public abstract boolean isClosed();
+
+ /*
+ ////////////////////////////////////////////////////
+ // Closeable implementation
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method called to close this generator, so that no more content
+ * can be written.
+ *<p>
+ * Whether the underlying target (stream, writer) gets closed depends
+ * on whether this generator either manages the target (i.e. is the
+ * only one with access to the target -- case if caller passes a
+ * reference to the resource such as File, but not stream); or
+ * has feature {@link Feature#AUTO_CLOSE_TARGET} enabled.
+ * If either of above is true, the target is also closed. Otherwise
+ * (not managing, feature not enabled), target is not closed.
+ */
+ public abstract void close()
+ throws IOException;
+
+}
View
141 lib-src/org/codehaus/jackson/JsonLocation.java
@@ -0,0 +1,141 @@
+package org.codehaus.jackson;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * Object that encapsulates Location information used for reporting
+ * parsing (or potentially generation) errors, as well as current location
+ * within input streams.
+ */
+public class JsonLocation
+ implements java.io.Serializable // as per [JACKSON-168]
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Shared immutable "N/A location" that can be returned to indicate
+ * that no location information is available
+ *
+ * @since 1.3
+ */
+ public final static JsonLocation NA = new JsonLocation("N/A", -1L, -1L, -1, -1);
+
+ final long _totalBytes;
+ final long _totalChars;
+
+ final int _lineNr;
+ final int _columnNr;
+
+ /**
+ * Displayable description for input source: file path, url
+ */
+ final Object _sourceRef;
+
+ public JsonLocation(Object srcRef, long totalChars, int lineNr, int colNr)
+ {
+ /* Unfortunately, none of legal encodings are straight single-byte
+ * encodings. Could determine offset for UTF-16/UTF-32, but the
+ * most important one is UTF-8...
+ * so for now, we'll just not report any real byte count
+ */
+ this(srcRef, -1L, totalChars, lineNr, colNr);
+ }
+
+ @JsonCreator
+ public JsonLocation(@JsonProperty("sourceRef") Object sourceRef,
+ @JsonProperty("byteOffset") long totalBytes,
+ @JsonProperty("charOffset") long totalChars,
+ @JsonProperty("lineNr") int lineNr,
+ @JsonProperty("columnNr") int columnNr)
+ {
+ _sourceRef = sourceRef;
+ _totalBytes = totalBytes;
+ _totalChars = totalChars;
+ _lineNr = lineNr;
+ _columnNr = columnNr;
+ }
+
+ /**
+ * Reference to the original resource being read, if one available.
+ * For example, when a parser has been constructed by passing
+ * a {@link java.io.File} instance, this method would return
+ * that File. Will return null if no such reference is available,
+ * for example when {@link java.io.InputStream} was used to
+ * construct the parser instance.
+ */
+ public Object getSourceRef() { return _sourceRef; }
+
+ /**
+ * @return Line number of the location (1-based)
+ */
+ public int getLineNr() { return _lineNr; }
+
+ /**
+ * @return Column number of the location (1-based)
+ */
+ public int getColumnNr() { return _columnNr; }
+
+ /**
+ * @return Character offset within underlying stream, reader or writer,
+ * if available; -1 if not.
+ */
+ public long getCharOffset() { return _totalChars; }
+
+ /**
+ * @return Byte offset within underlying stream, reader or writer,
+ * if available; -1 if not.
+ */
+ public long getByteOffset()
+ {
+ return _totalBytes;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder(80);
+ sb.append("[Source: ");
+ if (_sourceRef == null) {
+ sb.append("UNKNOWN");
+ } else {
+ sb.append(_sourceRef.toString());
+ }
+ sb.append("; line: ");
+ sb.append(_lineNr);
+ sb.append(", column: ");
+ sb.append(_columnNr);
+ sb.append(']');
+ return sb.toString();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = (_sourceRef == null) ? 1 : _sourceRef.hashCode();
+ hash ^= _lineNr;
+ hash += _columnNr;
+ hash ^= (int) _totalChars;
+ hash += (int) _totalBytes;
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object other)
+ {
+ if (other == this) return true;
+ if (other == null) return false;
+ if (!(other instanceof JsonLocation)) return false;
+ JsonLocation otherLoc = (JsonLocation) other;
+
+ if (_sourceRef == null) {
+ if (otherLoc._sourceRef != null) return false;
+ } else if (!_sourceRef.equals(otherLoc._sourceRef)) return false;
+
+ return (_lineNr == otherLoc._lineNr)
+ && (_columnNr == otherLoc._columnNr)
+ && (_totalChars == otherLoc._totalChars)
+ && (getByteOffset() == otherLoc.getByteOffset())
+ ;
+ }
+}
View
417 lib-src/org/codehaus/jackson/JsonNode.java
@@ -0,0 +1,417 @@
+package org.codehaus.jackson;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+
+
+/**
+ * Base class for all JSON nodes, which form the basis of JSON
+ * Tree Model that Jackson implements.
+ * One way to think of these nodes is to considere them
+ * similar to DOM nodes in XML DOM trees.
+ *<p>
+ * As a general design rule, most accessors ("getters") are included
+ * in this base class, to allow for traversing structure without
+ * type casts. Most mutators, however, need to be accessed through
+ * specific sub-classes. This seems sensible because proper type
+ * information is generally available when building or modifying
+ * trees, but less often when reading a tree (newly built from
+ * parsed Json content).
+ *<p>
+ * Actual concrete sub-classes can be found from package
+ * {@link org.codehaus.jackson.node}.
+ */
+public abstract class JsonNode
+ implements Iterable<JsonNode>
+{
+ final static List<JsonNode> NO_NODES = Collections.emptyList();
+ final static List<String> NO_STRINGS = Collections.emptyList();
+
+ protected JsonNode() { }
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, type introspection
+ ////////////////////////////////////////////////////
+ */
+
+ // // First high-level division between values, containers and "missing"
+
+ /**
+ * Method that returns true for all value nodes: ones that
+ * are not containers, and that do not represent "missing" nodes
+ * in the path. Such value nodes represent String, Number, Boolean
+ * and null values from JSON.
+ *<p>
+ * Note: one and only one of methods {@link #isValueNode},
+ * {@link #isContainerNode} and {@link #isMissingNode} ever
+ * returns true for any given node.
+ */
+ public boolean isValueNode() { return false; }
+
+ /**
+ * Method that returns true for container nodes: Arrays and Objects.
+ *<p>
+ * Note: one and only one of methods {@link #isValueNode},
+ * {@link #isContainerNode} and {@link #isMissingNode} ever
+ * returns true for any given node.
+ */
+ public boolean isContainerNode() { return false; }
+
+ /**
+ * Method that returns true for "virtual" nodes which represent
+ * missing entries constructed by path accessor methods when
+ * there is no actual node matching given criteria.
+ *<p>
+ * Note: one and only one of methods {@link #isValueNode},
+ * {@link #isContainerNode} and {@link #isMissingNode} ever
+ * returns true for any given node.
+ */
+ public boolean isMissingNode() { return false; }
+
+ // // Then more specific type introspection
+ // // (along with defaults to be overridden)
+
+ /**
+ * @return True if this node represents Json Array
+ */
+ public boolean isArray() { return false; }
+
+ /**
+ * @return True if this node represents Json Object
+ */
+ public boolean isObject() { return false; }
+
+ /**
+ * Method that can be used to check if the node is a wrapper
+ * for a POJO ("Plain Old Java Object" aka "bean".
+ * Returns true only for
+ * instances of {@link org.codehaus.jackson.node.POJONode}.
+ *
+ * @return True if this node wraps a POJO
+ */
+ public boolean isPojo() { return false; }
+
+ /**
+ * @return True if this node represents a numeric Json
+ * value
+ */
+ public boolean isNumber() { return false; }
+
+ /**
+ * @return True if this node represents an integral (integer)
+ * numeric Json value
+ */
+ public boolean isIntegralNumber() { return false; }
+
+ /**
+ * @return True if this node represents a non-integral
+ * numeric Json value
+ */
+ public boolean isFloatingPointNumber() { return false; }
+
+ /**
+ * @return True if this node represents an integral
+ * numeric Json value that withs in Java int value space
+ */
+ public boolean isInt() { return false; }
+
+ /**
+ * @return True if this node represents an integral
+ * numeric Json value that fits in Java long value space
+ * (but not int value space, i.e. {@link #isInt} returns false)
+ */
+ public boolean isLong() { return false; }
+
+ public boolean isDouble() { return false; }
+ public boolean isBigDecimal() { return false; }
+ public boolean isBigInteger() { return false; }
+
+ public boolean isTextual() { return false; }
+
+ /**
+ * Method that can be used to check if this node was created from
+ * Json boolean value (literals "true" and "false").
+ */
+ public boolean isBoolean() { return false; }
+
+ /**
+ * Method that can be used to check if this node was created from
+ * Json liternal null value.
+ */
+ public boolean isNull() { return false; }
+
+ /**
+ * Method that can be used to check if this node represents
+ * binary data (Base64 encoded). Although this will be externally
+ * written as Json String value, {@link #isTextual} will
+ * return false if this method returns true.
+ *
+ * @return True if this node represents base64 encoded binary data
+ */
+ public boolean isBinary() { return false; }
+
+ /**
+ * Method that can be used for efficient type detection
+ * when using stream abstraction for traversing nodes.
+ * Will return the first {@link JsonToken} that equivalent
+ * stream event would produce (for most nodes there is just
+ * one token but for structured/container types multiple)
+ *
+ * @since 1.3
+ */
+ public abstract JsonToken asToken();
+
+ /**
+ * If this node is a numeric type (as per {@link #isNumber}),
+ * returns native type that node uses to store the numeric
+ * value.
+ */
+ public abstract JsonParser.NumberType getNumberType();
+
+ /*
+ ////////////////////////////////////////////////////
+ // Public API, value access
+ ////////////////////////////////////////////////////
+ */
+
+ /**
+ * Method to use for accessing String values.
+ * Does <b>NOT</b> do any conversions for non-String value nodes;
+ * for non-String values (ones for which {@link #isTextual} returns
+ * false) null will be returned.
+ * For String values, null is never returned (but empty Strings may be)
+ *
+ * @return Textual value this node contains, iff it is a textual
+ * json node (comes from Json String value entry)
+ */
+ public String getTextValue() { return null; }
+
+ /**
+ * Method to use for accessing binary content of binary nodes (nodes
+ * for which {@link #isBinary} returns true); or for Text Nodes
+ * (ones for which {@link #getTextValue} returns non-null value),
+ * to read decoded base64 data.
+ * For other types of nodes, returns null.
+ *
+ * @return Binary data this node contains, iff it is a binary
+ * node; null otherwise
+ */
+ public byte[] getBinaryValue() throws IOException
+ {
+ return null;
+ }
+
+ public boolean getBooleanValue() { return false; }
+
+ /**
+ * Returns numeric value for this node, <b>if and only if</b>
+ * this node is numeric ({@link #isNumber} returns true); otherwise
+ * returns null
+ *
+ * @return Number value this node contains, if any (null for non-number
+ * nodes).
+ */
+ public Number getNumberValue() { return null; }
+
+ public int getIntValue() { return 0; }
+ public long getLongValue() { return 0L; }
+ public double getDoubleValue() { return 0.0; }
+ public BigDecimal getDecimalValue() { return BigDecimal.ZERO; }
+ public BigInteger getBigIntegerValue() { return BigInteger.ZERO; }
+
+ /**
+ * Method for accessing value of the specified element of
+ * an array node. For other nodes, null is always returned.
+ *<p>
+ * For array nodes, index specifies
+ * exact location within array and allows for efficient iteration
+ * over child elements (underlying storage is guaranteed to
+ * be efficiently indexable, i.e. has random-access to elements).
+ * If index is less than 0, or equal-or-greater than
+ * <code>node.size()</code>, null is returned; no exception is
+ * thrown for any index.
+ *
+ * @return Node that represent value of the specified element,
+ * if this node is an array and has specified element.
+ * Null otherwise.
+ */
+ public JsonNode get(int index) { return null; }
+
+ /**
+ * Method for accessing value of the specified field of
+ * an object node. If this node is not an object (or it
+ * does not have a value for specified field name), or
+ * if there is no field with such name, null is returned.
+ *
+ * @return Node that represent value of the specified field,
+ * if this node is an object and has value for the specified
+ * field. Null otherwise.
+ */
+ public JsonNode get