Package org.jclouds.http.functions

Source Code of org.jclouds.http.functions.ParseFirstJsonValueNamed

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 com.google.common.base.Preconditions.checkNotNull;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
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;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.Closeables;
import com.google.common.util.concurrent.Atomics;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.inject.TypeLiteral;

/**
* @author Adrian Cole
*/
public class ParseFirstJsonValueNamed<T> implements Function<HttpResponse, T> {

   @Resource
   protected Logger logger = Logger.NULL;

   private final GsonWrapper json;
   private final TypeLiteral<T> type;
   private final ImmutableSet<String> nameChoices;

   /**
    * @param nameChoices
    *           tried in order, first match wins
    */
   public ParseFirstJsonValueNamed(GsonWrapper json, TypeLiteral<T> type, String... nameChoices) {
      this.json = checkNotNull(json, "json");
      this.type = checkNotNull(type, "type");
      this.nameChoices = ImmutableSet.copyOf(checkNotNull(nameChoices, "nameChoices"));
   }

   @Override
   public T apply(HttpResponse arg0) {
      if (arg0.getPayload() == null)
         return nothing();
      JsonReader reader = null;
      try {
         reader = new JsonReader(new InputStreamReader(arg0.getPayload().getInput()));
         // in case keys are not in quotes
         reader.setLenient(true);
         AtomicReference<String> name = Atomics.newReference();
         JsonToken token = reader.peek();
         for (; token != JsonToken.END_DOCUMENT && nnn(reader, token, name); token = skipAndPeek(token, reader)) {
         }
         if (name.get() == null) {
            logger.trace("did not object named %s in json from response %s", nameChoices, arg0);
            return nothing();
         } else if (nameChoices.contains(name.get())) {
            return json.delegate().<T> fromJson(reader, type.getType());
         } else {
            return nothing();
         }
      } catch (IOException e) {
         throw new RuntimeException(String.format(
               "error reading from stream, parsing object named %s from http response %s", nameChoices, arg0), e);
      } finally {
         Closeables.closeQuietly(reader);
         arg0.getPayload().release();
      }
   }

   @SuppressWarnings("unchecked")
   private T nothing() {
      if (type.getRawType().isAssignableFrom(Set.class))
         return (T) ImmutableSet.of();
      else if (type.getRawType().isAssignableFrom(List.class))
         return (T) ImmutableList.of();
      else if (type.getRawType().isAssignableFrom(Map.class))
         return (T) ImmutableMap.of();
      return null;
   }

   private boolean nnn(JsonReader reader, JsonToken token, AtomicReference<String> name) throws IOException {
      if (token == JsonToken.NAME) {
         String name2 = reader.nextName();
         if (nameChoices.contains(name2)) {
            name.set(name2);
            return false;
         }
      }
      return true;

   }

   private JsonToken skipAndPeek(JsonToken token, JsonReader reader) throws IOException {
      switch (token) {
      case BEGIN_ARRAY:
         reader.beginArray();
         break;
      case END_ARRAY:
         reader.endArray();
         break;
      case BEGIN_OBJECT:
         reader.beginObject();
         break;
      case END_OBJECT:
         reader.endObject();
         break;
      case NAME:
         // NOTE that we have already advanced on NAME in the eval block;
         break;
      case STRING:
         reader.nextString();
         break;
      case NUMBER:
         reader.nextString();
         break;
      case BOOLEAN:
         reader.nextBoolean();
         break;
      case NULL:
         reader.nextNull();
         break;
      case END_DOCUMENT:
         break;
      }
      return reader.peek();
   }
}
TOP

Related Classes of org.jclouds.http.functions.ParseFirstJsonValueNamed

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.