diff --git a/core/src/main/java/org/jclouds/http/functions/ParseFirstJsonValueNamed.java b/core/src/main/java/org/jclouds/http/functions/ParseFirstJsonValueNamed.java index ccd058a898..52d98885a1 100644 --- a/core/src/main/java/org/jclouds/http/functions/ParseFirstJsonValueNamed.java +++ b/core/src/main/java/org/jclouds/http/functions/ParseFirstJsonValueNamed.java @@ -27,8 +27,11 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Resource; + import org.jclouds.http.HttpResponse; import org.jclouds.json.internal.GsonWrapper; +import org.jclouds.logging.Logger; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; @@ -44,6 +47,9 @@ import com.google.inject.TypeLiteral; */ public class ParseFirstJsonValueNamed implements Function { + @Resource + protected Logger logger = Logger.NULL; + private final GsonWrapper json; private final TypeLiteral type; private final String name; @@ -68,8 +74,11 @@ public class ParseFirstJsonValueNamed implements Function { for (; token != JsonToken.END_DOCUMENT && nnn(this.name, reader, token, name); token = skipAndPeek(token, reader)) ; - if (name.get().equals(this.name)) { - return json.delegate().fromJson(reader, type.getType()); + if (name.get() == null) { + logger.trace("did not object named %s in json from response %s", this.name, arg0); + return nothing(); + } else if (name.get().equals(this.name)) { + return json.delegate(). fromJson(reader, type.getType()); } else { return nothing(); } diff --git a/core/src/test/java/org/jclouds/http/functions/ParseFirstJsonValueNamedTest.java b/core/src/test/java/org/jclouds/http/functions/ParseFirstJsonValueNamedTest.java new file mode 100644 index 0000000000..0f043bc8b9 --- /dev/null +++ b/core/src/test/java/org/jclouds/http/functions/ParseFirstJsonValueNamedTest.java @@ -0,0 +1,138 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.jclouds.http.functions; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.jclouds.http.HttpResponse; +import org.jclouds.io.Payloads; +import org.jclouds.json.config.GsonModule; +import org.jclouds.json.internal.GsonWrapper; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Guice; +import com.google.inject.TypeLiteral; + +/** + * + * @author Adrian Cole + */ +@Test(testName = "ParseFirstJsonValueNamedTest") +public class ParseFirstJsonValueNamedTest { + + GsonWrapper json = Guice.createInjector(new GsonModule()).getInstance(GsonWrapper.class); + + static class Event { + private String name; + private String source; + + private Event(String name, String source) { + this.name = name; + this.source = source; + } + + @Override + public String toString() { + return String.format("(name=%s, source=%s)", name, source); + } + } + + public void testParseNestedElements() throws IOException { + String nested = "{ \"count\":1 ,\"event\" : [ {name:'GREETINGS',source:'guest'} ] }"; + HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie") + .payload(Payloads.newPayload(nested)).build(); + + List val = new ParseFirstJsonValueNamed>(json, new TypeLiteral>() { + }, "event").apply(response); + assertEquals(val.toString(), "[(name=GREETINGS, source=guest)]"); + } + + public void testParseNestedElementsWhenNotFoundIsEmpty() throws IOException { + String nested = "{ \"count\":1 ,\"evant\" : [ {name:'GREETINGS',source:'guest'} ] }"; + HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie") + .payload(Payloads.newPayload(nested)).build(); + + List val = new ParseFirstJsonValueNamed>(json, new TypeLiteral>() { + }, "event").apply(response); + assertEquals(val.toString(), "[]"); + } + + public void testParseNestedElementsButNothing() throws IOException { + String nested = "{ \"count\":1 ,\"event\" : [ ] }"; + HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie") + .payload(Payloads.newPayload(nested)).build(); + + List val = new ParseFirstJsonValueNamed>(json, new TypeLiteral>() { + }, "event").apply(response); + assertEquals(val.toString(), "[]"); + } + + public void testParseNestedFurtherElements() throws IOException { + String nestedFurther = "{ \"listaccountsresponse\" : { \"count\":1 ,\"event\" : [ {name:'GREETINGS',source:'guest'} ] } }"; + HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie") + .payload(Payloads.newPayload(nestedFurther)).build(); + + List val = new ParseFirstJsonValueNamed>(json, new TypeLiteral>() { + }, "event").apply(response); + assertEquals(val.toString(), "[(name=GREETINGS, source=guest)]"); + } + + public void testParseNestedFurtherElementsButNothing() throws IOException { + String nestedFurther = "{ \"listaccountsresponse\" : { \"count\":1 ,\"event\" : [ ] } }"; + HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie") + .payload(Payloads.newPayload(nestedFurther)).build(); + + List val = new ParseFirstJsonValueNamed>(json, new TypeLiteral>() { + }, "event").apply(response); + assertEquals(val.toString(), "[]"); + } + + public void testParseNoPayloadEmptyList() throws IOException { + HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie").build(); + + List val = new ParseFirstJsonValueNamed>(json, new TypeLiteral>() { + }, "event").apply(response); + assertEquals(val, ImmutableList. of()); + } + + public void testParseNoPayloadEmptyMap() throws IOException { + HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie").build(); + + Map val = new ParseFirstJsonValueNamed>(json, + new TypeLiteral>() { + }, "event").apply(response); + assertEquals(val, ImmutableMap. of()); + } + + public void testParseNoPayloadEmptySet() throws IOException { + HttpResponse response = HttpResponse.builder().statusCode(200).message("goodie").build(); + + Set val = new ParseFirstJsonValueNamed>(json, new TypeLiteral>() { + }, "event").apply(response); + assertEquals(val, ImmutableSet. of()); + } +}