gson でJSON読み込んで、Key と Value

先日、Jackson でJSON読込み key-value の BiConsumer を処理する - Oboe吹きプログラマの黙示録

Jackson でJSON読込み key-value の Stream生成 - Oboe吹きプログラマの黙示録
を書いたので、gson で同じことをします。

JSONキーは、"." で区切り、配列は、[n] でインデックスを表現します。

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.AbstractMap.SimpleEntry;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
/**
 * JsonView
 */
public class JsonView{

   public void read(String jsontxt, BiConsumer<String, Object> biconsumer){
      parseElement(JsonParser.parseReader(new StringReader(jsontxt)), "", biconsumer);
   }
   public void read(Reader reader, BiConsumer<String, Object> biconsumer){
      parseElement(JsonParser.parseReader(reader), "", biconsumer);
   }
   public void read(InputStream in, BiConsumer<String, Object> biconsumer){
      parseElement(JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)), "", biconsumer);
   }
   private void parseElement(JsonElement je, String parent, BiConsumer<String, Object> biconsumer){
      if (je.isJsonObject()) {
         JsonObject jo = (JsonObject)je;
         for(Entry<String, JsonElement> e:jo.entrySet()){
            parseElement(e.getValue(), parent + "." + e.getKey(), biconsumer);
         }
      }else if(je.isJsonArray()){
         JsonArray ary = je.getAsJsonArray();
         int i = 0;
         for(Iterator<JsonElement> it=ary.iterator();it.hasNext();i++){
            parseElement(it.next(), parent + "[" + i + "]", biconsumer);
         }
      }else if(je.isJsonNull()){
         biconsumer.accept(parent.substring(1), null);
      }else if(je.isJsonPrimitive()){
         String path = parent.substring(1);
         JsonPrimitive p = je.getAsJsonPrimitive();
         if (p.isNumber()){
            if (je.toString().indexOf(".") > 0) {
               biconsumer.accept(path, p.getAsDouble());
            }else{
               if (p.getAsLong() <= Integer.MAX_VALUE) {
                  biconsumer.accept(path, p.getAsLong());
               }else{
                  biconsumer.accept(path, p.getAsInt());
               }
            }
         }else if(p.isBoolean()){
            biconsumer.accept(path, p.getAsBoolean());
         }else if(p.isString()){
            biconsumer.accept(path, p.getAsString());
         }
      }
   }

   public void read(String jsontxt, Predicate<String> predicate, BiConsumer<String, Object> biconsumer){
      parseElement(JsonParser.parseReader(new StringReader(jsontxt)), "", predicate, biconsumer);
   }
   public void read(Reader reader, Predicate<String> predicate, BiConsumer<String, Object> biconsumer){
      parseElement(JsonParser.parseReader(reader), "", predicate, biconsumer);
   }
   public void read(InputStream in, Predicate<String> predicate, BiConsumer<String, Object> biconsumer){
      parseElement(JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)), "", predicate, biconsumer);
   }
   private void parseElement(JsonElement je, String parent, Predicate<String> predicate, BiConsumer<String, Object> biconsumer){
      if (je.isJsonObject()) {
         JsonObject jo = (JsonObject)je;
         for(Entry<String, JsonElement> e:jo.entrySet()){
            parseElement(e.getValue(), parent + "." + e.getKey(), biconsumer);
         }
      }else if(je.isJsonArray()){
         JsonArray ary = je.getAsJsonArray();
         int i = 0;
         for(Iterator<JsonElement> it=ary.iterator();it.hasNext();i++){
            parseElement(it.next(), parent + "[" + i + "]", biconsumer);
         }
      }else if(je.isJsonNull()){
         String path = parent.substring(1);
         if (predicate.test(path)){
            biconsumer.accept(path, null);
         }
      }else if(je.isJsonPrimitive()){
         String path = parent.substring(1);
         if (predicate.test(path)){
            JsonPrimitive p = je.getAsJsonPrimitive();
            if (p.isNumber()){
               if (je.toString().indexOf(".") > 0) {
                  biconsumer.accept(path, p.getAsDouble());
               }else{
                  if (p.getAsLong() <= Integer.MAX_VALUE) {
                     biconsumer.accept(path, p.getAsLong());
                  }else{
                     biconsumer.accept(path, p.getAsInt());
                  }
               }
            }else if(p.isBoolean()){
               biconsumer.accept(path, p.getAsBoolean());
            }else if(p.isString()){
               biconsumer.accept(path, p.getAsString());
            }
         }
      }
   }
   public Stream<Entry<String, Object>> stream(InputStream in){
      Stream.Builder<Entry<String, Object>> builder = Stream.builder();
      parseElement(JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)), "", builder);
      return  builder.build();
   }
   public Stream<Entry<String, Object>> stream(String jsontxt){
      Stream.Builder<Entry<String, Object>> builder = Stream.builder();
      parseElement(JsonParser.parseReader(new StringReader(jsontxt)), "", builder);
      return  builder.build();
   }
   public Stream<Entry<String, Object>> stream(Reader reader){
      Stream.Builder<Entry<String, Object>> builder = Stream.builder();
      parseElement(JsonParser.parseReader(reader), "", builder);
      return  builder.build();
   }

   private void parseElement(JsonElement je, String parent, Stream.Builder<Entry<String, Object>> builder){
      if (je.isJsonObject()) {
         JsonObject jo = (JsonObject)je;
         for(Entry<String, JsonElement> e:jo.entrySet()){
            parseElement(e.getValue(), parent + "." + e.getKey(), builder);
         }
      }else if(je.isJsonArray()){
         JsonArray ary = je.getAsJsonArray();
         int i = 0;
         for(Iterator<JsonElement> it=ary.iterator();it.hasNext();i++){
            parseElement(it.next(), parent + "[" + i + "]", builder);
         }
      }else if(je.isJsonNull()){
         builder.add(new SimpleEntry<String, Object>(parent.substring(1), null));
      }else if(je.isJsonPrimitive()){
         String path = parent.substring(1);
         JsonPrimitive p = je.getAsJsonPrimitive();
         if (p.isNumber()){
            if (je.toString().indexOf(".") > 0) {
               builder.add(new SimpleEntry<String, Object>(path, p.getAsDouble()));
            }else{
               if (p.getAsLong() <= Integer.MAX_VALUE) {
                  builder.add(new SimpleEntry<String, Object>(path, p.getAsLong()));
               }else{
                  builder.add(new SimpleEntry<String, Object>(path, p.getAsInt()));
               }
            }
         }else if(p.isBoolean()){
            builder.add(new SimpleEntry<String, Object>(path, p.getAsBoolean()));
         }else if(p.isString()){
            builder.add(new SimpleEntry<String, Object>(path, p.getAsString()));
         }
      }
   }
}

今頃になってこんなものと思いつつ、、
jsonview · yipuran/yipuran-gsonhelper Wiki · GitHub
として Git-Hub に入れた。もっと早く作ってればよかった。