/******************************************************************************* * Copyright (C) 2011, Google Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package com.google.eclipse.mechanic.internal; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Type; import java.net.URI; import java.util.Arrays; import java.util.List; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonIOException; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; /** * Parser for json-formatted information about a URI task provider. */ public class UriTaskProviderModelParser { private static final Gson GSON = new GsonBuilder() .registerTypeAdapter(UriTaskProviderModel.Metadata.class, new MetaDataAdapter()) .registerTypeAdapter(UriTaskProviderModel.class, new UriTaskModelAdapter()) .create(); private static final class Types { static final Type metadata = new TypeToken<UriTaskProviderModel.Metadata>(){}.getType(); public static Type uriArray = new TypeToken<URI[]>(){}.getType(); } private static class MetaDataAdapter implements JsonDeserializer<UriTaskProviderModel.Metadata> { public UriTaskProviderModel.Metadata deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jo = json.getAsJsonObject(); String description = deserialize(jo, "description"); if (description == null) { throw new JsonParseException("description is missing"); } return new UriTaskProviderModel.Metadata( deserialize(jo, "name"), description, deserialize(jo, "contact")); } private String deserialize(JsonObject jo, String field) { JsonElement val = jo.get(field); if (val == null) { return null; } return val.getAsString(); } } private static class UriTaskModelAdapter implements JsonDeserializer<UriTaskProviderModel> { private static final String TYPE = "com.google.eclipse.mechanic.UriTaskProviderModel"; public UriTaskProviderModel deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jo = json.getAsJsonObject(); JsonElement je = jo.get("type"); if (je == null || !je.getAsString().equals(TYPE)) { throw new IllegalArgumentException( String.format("URI task models must have an entry type='%s'", TYPE)); } UriTaskProviderModel.Metadata metadata = (UriTaskProviderModel.Metadata) context.deserialize( jo.get("metadata"), Types.metadata); if (metadata == null) { throw new JsonParseException("metadata is required"); } URI[] uriArray = (URI[]) context.deserialize(jo.get("tasks"), Types.uriArray); if (uriArray == null) { throw new JsonParseException("tasks is requried"); } List<URI> tasks = Arrays.asList(uriArray); return new UriTaskProviderModel(metadata, tasks); } } public static UriTaskProviderModel read(InputStream is) throws JsonSyntaxException, JsonIOException{ return GSON.fromJson(new InputStreamReader(is), UriTaskProviderModel.class); } /** * Parse a model from a string. * * This has to exist here because GSON isn't made available outside this * plug-in, and the {@link #read(InputStream)} function throws * JsonSyntaxException and JsonIOException. */ public static UriTaskProviderModel readForTests(String text) throws RuntimeException { return read(new ByteArrayInputStream(text.getBytes())); } }