Revert "Update to Jackson 2.4.3"

This reverts commit 7523d0b150.
This commit is contained in:
Chris Earle 2014-11-25 16:41:06 -05:00
parent 6692ac3b75
commit 08521a4066
5 changed files with 59 additions and 133 deletions

View File

@ -31,7 +31,6 @@
</parent> </parent>
<properties> <properties>
<jackson.version>2.4.3</jackson.version>
<lucene.version>5.0.0</lucene.version> <lucene.version>5.0.0</lucene.version>
<lucene.maven.version>5.0.0-snapshot-1641343</lucene.maven.version> <lucene.maven.version>5.0.0-snapshot-1641343</lucene.maven.version>
<tests.jvms>auto</tests.jvms> <tests.jvms>auto</tests.jvms>
@ -227,28 +226,28 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId> <artifactId>jackson-core</artifactId>
<version>${jackson.version}</version> <version>2.4.2</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId> <artifactId>jackson-dataformat-smile</artifactId>
<version>${jackson.version}</version> <version>2.4.2</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId> <artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version> <version>2.4.2</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId> <artifactId>jackson-dataformat-cbor</artifactId>
<version>${jackson.version}</version> <version>2.4.2</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>

View File

@ -157,9 +157,9 @@ public class XContentFactory {
return XContentType.YAML; return XContentType.YAML;
} }
// CBOR is not supported because it is a binary-only format // CBOR is not supported
for (int i = 1; i < length; i++) { for (int i = 0; i < length; i++) {
char c = content.charAt(i); char c = content.charAt(i);
if (c == '{') { if (c == '{') {
return XContentType.JSON; return XContentType.JSON;
@ -208,48 +208,41 @@ public class XContentFactory {
* Guesses the content type based on the provided input stream. * Guesses the content type based on the provided input stream.
*/ */
public static XContentType xContentType(InputStream si) throws IOException { public static XContentType xContentType(InputStream si) throws IOException {
// Need minimum of 3 bytes for everything (except really JSON)
int first = si.read(); int first = si.read();
int second = si.read(); if (first == -1) {
int third = si.read();
// Cannot short circuit based on third (or later fourth) because "{}" is valid JSON
if (first == -1 || second == -1) {
return null; return null;
} }
int second = si.read();
if (first == SmileConstants.HEADER_BYTE_1 && second == SmileConstants.HEADER_BYTE_2 && if (second == -1) {
third == SmileConstants.HEADER_BYTE_3) { return null;
return XContentType.SMILE;
} }
if (first == '-' && second == '-' && third == '-') { if (first == SmileConstants.HEADER_BYTE_1 && second == SmileConstants.HEADER_BYTE_2) {
return XContentType.YAML; int third = si.read();
if (third == SmileConstants.HEADER_BYTE_3) {
return XContentType.SMILE;
}
} }
if (first == '{' || second == '{') {
// Need 4 bytes for CBOR
int fourth = si.read();
if (first == '{' || second == '{' || third == '{' || fourth == '{') {
return XContentType.JSON; return XContentType.JSON;
} }
if (first == '-' && second == '-') {
// ensure that we don't only have two or three bytes (definitely not CBOR and everything else was checked) int third = si.read();
if (third != -1 && fourth != -1) { if (third == '-') {
if (isCBORObjectHeader((byte)first, (byte)second, (byte)third, (byte)fourth)) { return XContentType.YAML;
return XContentType.CBOR; }
} }
if (first == (CBORConstants.BYTE_OBJECT_INDEFINITE & 0xff)){
for (int i = 4; i < GUESS_HEADER_LENGTH; i++) { return XContentType.CBOR;
int val = si.read(); }
if (val == -1) { for (int i = 2; i < GUESS_HEADER_LENGTH; i++) {
return null; int val = si.read();
} if (val == -1) {
if (val == '{') { return null;
return XContentType.JSON; }
} if (val == '{') {
return XContentType.JSON;
} }
} }
return null; return null;
} }
@ -280,53 +273,20 @@ public class XContentFactory {
if (first == '{') { if (first == '{') {
return XContentType.JSON; return XContentType.JSON;
} }
if (length > 2) { if (length > 2 && first == SmileConstants.HEADER_BYTE_1 && bytes.get(1) == SmileConstants.HEADER_BYTE_2 && bytes.get(2) == SmileConstants.HEADER_BYTE_3) {
byte second = bytes.get(1); return XContentType.SMILE;
byte third = bytes.get(2); }
if (length > 2 && first == '-' && bytes.get(1) == '-' && bytes.get(2) == '-') {
if (first == SmileConstants.HEADER_BYTE_1 && second == SmileConstants.HEADER_BYTE_2 && third == SmileConstants.HEADER_BYTE_3) { return XContentType.YAML;
return XContentType.SMILE; }
} if (first == CBORConstants.BYTE_OBJECT_INDEFINITE){
if (first == '-' && second == '-' && third == '-') { return XContentType.CBOR;
return XContentType.YAML; }
} for (int i = 0; i < length; i++) {
if (length > 3 && isCBORObjectHeader(first, second, third, bytes.get(3))) { if (bytes.get(i) == '{') {
return XContentType.CBOR; return XContentType.JSON;
}
// note: technically this only needs length >= 2, but if the string is just " {", then it's not JSON, but
// " {}" is JSON (3 characters)
for (int i = 1; i < length; i++) {
if (bytes.get(i) == '{') {
return XContentType.JSON;
}
} }
} }
return null; return null;
} }
/**
* Determine if the specified bytes represent a CBOR encoded stream.
* <p />
* This performs two checks to verify that it is indeed valid/usable CBOR data:
* <ol>
* <li>Checks the first three bytes for the
* {@link CBORConstants#TAG_ID_SELF_DESCRIBE self-identifying CBOR tag (header)}</li>
* <li>Checks that the fourth byte represents a major type that is an object, as opposed to some other type (e.g.,
* text)</li>
* </ol>
*
* @param first The first byte of the header
* @param second The second byte of the header
* @param third The third byte of the header
* @param fourth The fourth byte represents the <em>first</em> byte of the CBOR data, indicating the data's type
*
* @return {@code true} if a CBOR byte stream is detected. {@code false} otherwise.
*/
private static boolean isCBORObjectHeader(byte first, byte second, byte third, byte fourth) {
// Determine if it uses the ID TAG (0xd9f7), then see if it starts with an object (equivalent to
// checking in JSON if it starts with '{')
return CBORConstants.hasMajorType(CBORConstants.MAJOR_TYPE_TAG, first) &&
(((second << 8) & 0xff00) | (third & 0xff)) == CBORConstants.TAG_ID_SELF_DESCRIBE &&
CBORConstants.hasMajorType(CBORConstants.MAJOR_TYPE_OBJECT, fourth);
}
} }

View File

@ -21,8 +21,6 @@ package org.elasticsearch.common.xcontent.cbor;
import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory; import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
import com.fasterxml.jackson.dataformat.cbor.CBORGenerator;
import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.FastStringReader; import org.elasticsearch.common.io.FastStringReader;
@ -45,8 +43,6 @@ public class CborXContent implements XContent {
static { static {
cborFactory = new CBORFactory(); cborFactory = new CBORFactory();
cborFactory.configure(CBORFactory.Feature.FAIL_ON_SYMBOL_HASH_OVERFLOW, false); // this trips on many mappings now... cborFactory.configure(CBORFactory.Feature.FAIL_ON_SYMBOL_HASH_OVERFLOW, false); // this trips on many mappings now...
// Enable prefixing the entire byte stream with a CBOR header ("tag")
cborFactory.configure(CBORGenerator.Feature.WRITE_TYPE_HEADER, true);
cborXContent = new CborXContent(); cborXContent = new CborXContent();
} }

View File

@ -29,45 +29,37 @@ import java.io.IOException;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
/** /**
* Tests {@link XContentFactory} type generation. *
*/ */
public class XContentFactoryTests extends ElasticsearchTestCase { public class XContentFactoryTests extends ElasticsearchTestCase {
@Test @Test
public void testGuessJson() throws IOException { public void testGuessJson() throws IOException {
assertType(XContentType.JSON); testGuessType(XContentType.JSON);
} }
@Test @Test
public void testGuessSmile() throws IOException { public void testGuessSmile() throws IOException {
assertType(XContentType.SMILE); testGuessType(XContentType.SMILE);
} }
@Test @Test
public void testGuessYaml() throws IOException { public void testGuessYaml() throws IOException {
assertType(XContentType.YAML); testGuessType(XContentType.YAML);
} }
@Test @Test
public void testGuessCbor() throws IOException { public void testGuessCbor() throws IOException {
assertType(XContentType.CBOR); testGuessType(XContentType.CBOR);
} }
private void assertType(XContentType type) throws IOException { private void testGuessType(XContentType type) throws IOException {
for (XContentBuilder builder : generateBuilders(type)) { XContentBuilder builder = XContentFactory.contentBuilder(type);
assertBuilderType(builder, type); builder.startObject();
} builder.field("field1", "value1");
} builder.endObject();
/**
* Assert the {@code builder} maps to the appropriate {@code type}.
*
* @param builder Builder to check.
* @param type Type to match.
* @throws IOException if any error occurs while checking the builder
*/
private void assertBuilderType(XContentBuilder builder, XContentType type) throws IOException {
assertThat(XContentFactory.xContentType(builder.bytes()), equalTo(type)); assertThat(XContentFactory.xContentType(builder.bytes()), equalTo(type));
BytesArray bytesArray = builder.bytes().toBytesArray(); BytesArray bytesArray = builder.bytes().toBytesArray();
assertThat(XContentFactory.xContentType(new BytesStreamInput(bytesArray.array(), bytesArray.arrayOffset(), bytesArray.length(), false)), equalTo(type)); assertThat(XContentFactory.xContentType(new BytesStreamInput(bytesArray.array(), bytesArray.arrayOffset(), bytesArray.length(), false)), equalTo(type));
@ -77,30 +69,4 @@ public class XContentFactoryTests extends ElasticsearchTestCase {
assertThat(XContentFactory.xContentType(builder.string()), equalTo(type)); assertThat(XContentFactory.xContentType(builder.string()), equalTo(type));
} }
} }
/**
* Generate builders to test various use cases to check.
*
* @param type The type to use.
* @return Never {@code null} array of unique {@link XContentBuilder}s testing different edge cases.
* @throws IOException if any error occurs while generating builders
*/
private XContentBuilder[] generateBuilders(XContentType type) throws IOException {
XContentBuilder[] builders = new XContentBuilder[] {
XContentFactory.contentBuilder(type), XContentFactory.contentBuilder(type)
};
// simple object
builders[0].startObject();
builders[0].field("field1", "value1");
builders[0].startObject("object1");
builders[0].field("field2", "value2");
builders[0].endObject();
builders[0].endObject();
// empty object
builders[1].startObject().endObject();
return builders;
}
} }

View File

@ -19,6 +19,10 @@
package org.elasticsearch.common.xcontent.cbor; package org.elasticsearch.common.xcontent.cbor;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentGenerator; import org.elasticsearch.common.xcontent.XContentGenerator;
@ -27,6 +31,7 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.test.ElasticsearchTestCase; import org.elasticsearch.test.ElasticsearchTestCase;
import org.junit.Test; import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;