
org.jclouds.json.config.GsonModule Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jclouds-core Show documentation
Show all versions of jclouds-core Show documentation
Core components to access jclouds services
The newest version!
/*
* 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.json.config;
import static com.google.common.io.BaseEncoding.base16;
import java.beans.ConstructorProperties;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.date.DateService;
import org.jclouds.domain.JsonBall;
import org.jclouds.json.Json;
import org.jclouds.json.internal.DeserializationConstructorAndReflectiveTypeAdapterFactory;
import org.jclouds.json.internal.EnumTypeAdapterThatReturnsFromValue;
import org.jclouds.json.internal.GsonWrapper;
import org.jclouds.json.internal.NamingStrategies.AnnotationConstructorNamingStrategy;
import org.jclouds.json.internal.NamingStrategies.AnnotationOrNameFieldNamingStrategy;
import org.jclouds.json.internal.NamingStrategies.ExtractNamed;
import org.jclouds.json.internal.NamingStrategies.ExtractSerializedName;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.CollectionTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.FluentIterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableSetTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.IterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MultimapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.SetTypeAdapterFactory;
import org.jclouds.json.internal.NullHackJsonLiteralAdapter;
import org.jclouds.json.internal.OptionalTypeAdapterFactory;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.primitives.Bytes;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.FieldNamingStrategy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.ConstructorConstructor;
import com.google.gson.internal.Excluder;
import com.google.gson.internal.JsonReaderInternalAccess;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.google.inject.AbstractModule;
import com.google.inject.ImplementedBy;
import com.google.inject.Provides;
/**
* Contains logic for parsing objects from Strings.
*
* @author Adrian Cole
*/
public class GsonModule extends AbstractModule {
@SuppressWarnings("rawtypes")
@Provides
@Singleton
Gson provideGson(TypeAdapter jsonAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter,
ByteArrayAdapter byteArrayAdapter, PropertiesAdapter propertiesAdapter, JsonAdapterBindings bindings,
OptionalTypeAdapterFactory optional, SetTypeAdapterFactory set, ImmutableSetTypeAdapterFactory immutableSet,
MapTypeAdapterFactory map, MultimapTypeAdapterFactory multimap, IterableTypeAdapterFactory iterable,
CollectionTypeAdapterFactory collection, ListTypeAdapterFactory list,
ImmutableListTypeAdapterFactory immutableList, FluentIterableTypeAdapterFactory fluentIterable,
DefaultExclusionStrategy exclusionStrategy) {
FieldNamingStrategy serializationPolicy = new AnnotationOrNameFieldNamingStrategy(ImmutableSet.of(
new ExtractSerializedName(), new ExtractNamed()));
GsonBuilder builder = new GsonBuilder().setFieldNamingStrategy(serializationPolicy)
.setExclusionStrategies(exclusionStrategy);
// simple (type adapters)
builder.registerTypeAdapter(Properties.class, propertiesAdapter.nullSafe());
builder.registerTypeAdapter(Date.class, adapter.nullSafe());
builder.registerTypeAdapter(byte[].class, byteArrayAdapter.nullSafe());
builder.registerTypeAdapter(JsonBall.class, jsonAdapter.nullSafe());
builder.registerTypeAdapterFactory(optional);
builder.registerTypeAdapterFactory(iterable);
builder.registerTypeAdapterFactory(collection);
builder.registerTypeAdapterFactory(list);
builder.registerTypeAdapter(new TypeToken>() {
}.getType(), byteListAdapter.nullSafe());
builder.registerTypeAdapterFactory(immutableList);
builder.registerTypeAdapterFactory(set);
builder.registerTypeAdapterFactory(immutableSet);
builder.registerTypeAdapterFactory(map);
builder.registerTypeAdapterFactory(multimap);
builder.registerTypeAdapterFactory(fluentIterable);
AnnotationConstructorNamingStrategy deserializationPolicy = new AnnotationConstructorNamingStrategy(
ImmutableSet.of(ConstructorProperties.class, Inject.class), ImmutableSet.of(new ExtractNamed()));
builder.registerTypeAdapterFactory(new DeserializationConstructorAndReflectiveTypeAdapterFactory(
new ConstructorConstructor(ImmutableMap.>of()), serializationPolicy, Excluder.DEFAULT, deserializationPolicy));
// complicated (serializers/deserializers as they need context to operate)
builder.registerTypeHierarchyAdapter(Enum.class, new EnumTypeAdapterThatReturnsFromValue());
for (Map.Entry binding : bindings.getBindings().entrySet()) {
builder.registerTypeAdapter(binding.getKey(), binding.getValue());
}
for (TypeAdapterFactory factory : bindings.getFactories()) {
builder.registerTypeAdapterFactory(factory);
}
return builder.create();
}
@ImplementedBy(NoExclusions.class)
public interface DefaultExclusionStrategy extends ExclusionStrategy {
}
public static class NoExclusions implements DefaultExclusionStrategy {
public boolean shouldSkipField(FieldAttributes f) {
return false;
}
public boolean shouldSkipClass(Class> clazz) {
return false;
}
}
@ImplementedBy(CDateAdapter.class)
public abstract static class DateAdapter extends TypeAdapter {
}
@Provides
@Singleton
protected TypeAdapter provideJsonBallAdapter(NullHackJsonBallAdapter in) {
return in;
}
public static class NullHackJsonBallAdapter extends NullHackJsonLiteralAdapter {
@Override
protected JsonBall createJsonLiteralFromRawJson(String json) {
return new JsonBall(json);
}
}
@ImplementedBy(HexByteListAdapter.class)
public abstract static class ByteListAdapter extends TypeAdapter> {
}
@ImplementedBy(HexByteArrayAdapter.class)
public abstract static class ByteArrayAdapter extends TypeAdapter {
}
@Singleton
public static class HexByteListAdapter extends ByteListAdapter {
@Override
public void write(JsonWriter writer, List value) throws IOException {
writer.value(base16().lowerCase().encode(Bytes.toArray(value)));
}
@Override
public List read(JsonReader reader) throws IOException {
return Bytes.asList(base16().lowerCase().decode(reader.nextString()));
}
}
@Singleton
public static class HexByteArrayAdapter extends ByteArrayAdapter {
@Override
public void write(JsonWriter writer, byte[] value) throws IOException {
writer.value(base16().lowerCase().encode(value));
}
@Override
public byte[] read(JsonReader reader) throws IOException {
return base16().lowerCase().decode(reader.nextString());
}
}
@Singleton
public static class Iso8601DateAdapter extends DateAdapter {
private final DateService dateService;
@Inject
public Iso8601DateAdapter(DateService dateService) {
this.dateService = dateService;
}
public void write(JsonWriter writer, Date value) throws IOException {
writer.value(dateService.iso8601DateFormat(value));
}
public Date read(JsonReader reader) throws IOException {
return parseDate(reader.nextString());
}
protected Date parseDate(String toParse) {
try {
return dateService.iso8601DateParse(toParse);
} catch (RuntimeException e) {
return dateService.iso8601SecondsDateParse(toParse);
}
}
}
@Singleton
public static class PropertiesAdapter extends TypeAdapter {
private final Provider gson;
private final TypeToken
© 2015 - 2025 Weber Informatics LLC | Privacy Policy