Skip to content

Commit

Permalink
Merge branch 'flattening' of https://github.com/stankovski/AutoRest i…
Browse files Browse the repository at this point in the history
…nto readonly
  • Loading branch information
amarzavery committed Feb 27, 2016
2 parents 9c58d07 + 8778c0e commit c60a85b
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

package com.microsoft.azure;

import com.microsoft.azure.serializer.AzureJacksonMapperAdapter;
import com.microsoft.rest.ServiceCall;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceException;
import com.microsoft.rest.ServiceResponse;
import com.microsoft.rest.ServiceResponseCallback;
import com.microsoft.rest.ServiceResponseWithHeaders;
import com.microsoft.rest.credentials.ServiceClientCredentials;
import com.microsoft.rest.serializer.JacksonMapperAdapter;

import java.io.IOException;
import java.lang.reflect.Type;
Expand Down Expand Up @@ -63,10 +63,11 @@ public AzureClient() {
*
* @param clientBuilder customized http client.
* @param retrofitBuilder customized retrofit builder
* @param mapperAdapter the adapter for the Jackson object mapper
*/
public AzureClient(OkHttpClient.Builder clientBuilder, Retrofit.Builder retrofitBuilder) {
public AzureClient(OkHttpClient.Builder clientBuilder, Retrofit.Builder retrofitBuilder, JacksonMapperAdapter mapperAdapter) {
super(clientBuilder, retrofitBuilder);
this.mapperAdapter = new AzureJacksonMapperAdapter();
this.mapperAdapter = mapperAdapter;
}

/**
Expand Down Expand Up @@ -102,7 +103,7 @@ public <T> ServiceResponse<T> getPutOrPatchResult(Response<ResponseBody> respons
throw exception;
}

PollingState<T> pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType);
PollingState<T> pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter);
String url = response.raw().request().url().toString();

// Check provisioning state
Expand Down Expand Up @@ -193,7 +194,7 @@ public <T> AsyncPollingTask<T> getPutOrPatchResultAsync(Response<ResponseBody> r

PollingState<T> pollingState;
try {
pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType);
pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter);
} catch (IOException e) {
callback.failure(e);
return null;
Expand Down Expand Up @@ -275,7 +276,7 @@ public <T> ServiceResponse<T> getPostOrDeleteResult(Response<ResponseBody> respo
throw exception;
}

PollingState<T> pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType);
PollingState<T> pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter);

// Check provisioning state
while (!AzureAsyncOperation.getTerminalStatuses().contains(pollingState.getStatus())) {
Expand Down Expand Up @@ -365,7 +366,7 @@ public <T> AsyncPollingTask<T> getPostOrDeleteResultAsync(Response<ResponseBody>

PollingState<T> pollingState;
try {
pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType);
pollingState = new PollingState<>(response, this.getLongRunningOperationRetryTimeout(), resourceType, mapperAdapter);
} catch (IOException e) {
callback.failure(e);
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
package com.microsoft.azure;

import com.google.common.reflect.TypeToken;
import com.microsoft.azure.serializer.AzureJacksonMapperAdapter;
import com.microsoft.rest.AutoRestException;
import com.microsoft.rest.ServiceResponse;
import com.microsoft.rest.ServiceResponseBuilder;
Expand All @@ -29,13 +28,6 @@
* @param <E> the exception to throw in case of error.
*/
public class AzureServiceResponseBuilder<T, E extends AutoRestException> extends ServiceResponseBuilder<T, E> {
/**
* Create a ServiceResponseBuilder instance.
*/
public AzureServiceResponseBuilder() {
this(new AzureJacksonMapperAdapter());
}

/**
* Create a ServiceResponseBuilder instance.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
package com.microsoft.azure;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.microsoft.azure.serializer.AzureJacksonMapperAdapter;
import okhttp3.ResponseBody;
import retrofit2.Response;
import com.microsoft.rest.serializer.JacksonMapperAdapter;

import java.io.IOException;
import java.lang.reflect.Type;

import okhttp3.ResponseBody;
import retrofit2.Response;

/**
* An instance of this class defines the state of a long running operation.
*
Expand All @@ -38,21 +39,22 @@ public class PollingState<T> {
/** The error during the polling operations. */
private CloudError error;
/** The adapter for {@link com.fasterxml.jackson.databind.ObjectMapper}. */
private AzureJacksonMapperAdapter mapperAdapter;
private JacksonMapperAdapter mapperAdapter;

/**
* Initializes an instance of {@link PollingState}.
*
* @param response the response from Retrofit REST call.
* @param retryTimeout the long running operation retry timeout.
* @param resourceType the type of the resource the long running operation returns
* @param mapperAdapter the adapter for the Jackson object mapper
* @throws IOException thrown by deserialization
*/
public PollingState(Response<ResponseBody> response, Integer retryTimeout, Type resourceType) throws IOException {
public PollingState(Response<ResponseBody> response, Integer retryTimeout, Type resourceType, JacksonMapperAdapter mapperAdapter) throws IOException {
this.retryTimeout = retryTimeout;
this.setResponse(response);
this.resourceType = resourceType;
this.mapperAdapter = new AzureJacksonMapperAdapter();
this.mapperAdapter = mapperAdapter;

String responseContent = null;
PollingResource resource = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
package com.microsoft.azure.serializer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.microsoft.rest.serializer.FlatteningDeserializer;
import com.microsoft.rest.serializer.FlatteningSerializer;
import com.microsoft.rest.serializer.JacksonMapperAdapter;

/**
Expand All @@ -18,17 +20,16 @@ public final class AzureJacksonMapperAdapter extends JacksonMapperAdapter {
/**
* An instance of {@link ObjectMapper} to serialize/deserialize objects.
*/
private static ObjectMapper azureObjectMapper;
private ObjectMapper azureObjectMapper;

@Override
public ObjectMapper getObjectMapper() {
if (azureObjectMapper == null) {
azureObjectMapper = new ObjectMapper();
initializeObjectMapper(azureObjectMapper);
azureObjectMapper
.registerModule(FlatteningDeserializer.getModule())
.registerModule(FlatteningSerializer.getModule())
.registerModule(CloudErrorDeserializer.getModule());
azureObjectMapper.registerModule(FlatteningSerializer.getModule(getSimpleMapper()))
.registerModule(FlatteningDeserializer.getModule(getSimpleMapper()))
.registerModule(CloudErrorDeserializer.getModule(getSimpleMapper()));
}
return azureObjectMapper;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,38 @@
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.microsoft.azure.CloudError;
import com.microsoft.rest.serializer.JacksonMapperAdapter;

import java.io.IOException;

/**
* Custom serializer for serializing {@link CloudError} objects.
*/
public class CloudErrorDeserializer extends JsonDeserializer<CloudError> {
/** Object mapper for default deserializations. */
private ObjectMapper mapper;

/**
* Creates an instance of CloudErrorDeserializer.
*
* @param mapper the object mapper for default deserializations.
*/
protected CloudErrorDeserializer(ObjectMapper mapper) {
this.mapper = mapper;
}

/**
* Gets a module wrapping this serializer as an adapter for the Jackson
* ObjectMapper.
*
* @param mapper the object mapper for default deserializations.
* @return a simple module to be plugged onto Jackson ObjectMapper.
*/
public static SimpleModule getModule() {
public static SimpleModule getModule(ObjectMapper mapper) {
SimpleModule module = new SimpleModule();
module.addDeserializer(CloudError.class, new CloudErrorDeserializer());
module.addDeserializer(CloudError.class, new CloudErrorDeserializer(mapper));
return module;
}

Expand All @@ -46,7 +59,7 @@ public CloudError deserialize(JsonParser p, DeserializationContext ctxt) throws
return null;
}
JsonParser parser = new JsonFactory().createParser(errorNode.toString());
parser.setCodec(new JacksonMapperAdapter().getObjectMapper());
parser.setCodec(mapper);
return parser.readValueAs(CloudError.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,6 @@ public class ServiceResponseBuilder<T, E extends AutoRestException> {
*/
protected JacksonMapperAdapter mapperAdapter;

/**
* Create a ServiceResponseBuilder instance.
*/
public ServiceResponseBuilder() {
this(new JacksonMapperAdapter());
}

/**
* Create a ServiceResponseBuilder instance.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
*/

package com.microsoft.azure.serializer;
package com.microsoft.rest.serializer;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonFactory;
Expand All @@ -16,53 +16,58 @@
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.ResolvableDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.microsoft.azure.BaseResource;

import java.io.IOException;
import java.lang.reflect.Field;

/**
* Custom serializer for deserializing {@link BaseResource} with wrapped properties.
* Custom serializer for deserializing complex types with wrapped properties.
* For example, a property with annotation @JsonProperty(value = "properties.name")
* will be mapped to a top level "name" property in the POJO model.
*
* @param <T> the type to deserialize into.
*/
public class FlatteningDeserializer<T> extends StdDeserializer<T> implements ResolvableDeserializer {
public class FlatteningDeserializer extends StdDeserializer<Object> implements ResolvableDeserializer {
/**
* The default mapperAdapter for the current type.
*/
private final JsonDeserializer<?> defaultDeserializer;

/**
* The object mapper for default deserializations.
*/
private final ObjectMapper mapper;

/**
* Creates an instance of FlatteningDeserializer.
* @param vc handled type
* @param defaultDeserializer the default JSON mapperAdapter
* @param mapper the object mapper for default deserializations
*/
protected FlatteningDeserializer(Class<?> vc, JsonDeserializer<?> defaultDeserializer) {
protected FlatteningDeserializer(Class<?> vc, JsonDeserializer<?> defaultDeserializer, ObjectMapper mapper) {
super(vc);
this.defaultDeserializer = defaultDeserializer;
this.mapper = mapper;
}

/**
* Gets a module wrapping this serializer as an adapter for the Jackson
* ObjectMapper.
*
* @param mapper the object mapper for default deserializations
* @return a simple module to be plugged onto Jackson ObjectMapper.
*/
public static SimpleModule getModule() {
final Class<?> vc = BaseResource.class;
public static SimpleModule getModule(final ObjectMapper mapper) {
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (vc.isAssignableFrom(beanDesc.getBeanClass()) && vc != beanDesc.getBeanClass()) {
return new FlatteningDeserializer<BaseResource>(beanDesc.getBeanClass(), deserializer);
if (beanDesc.getBeanClass().getAnnotation(JsonFlatten.class) != null) {
return new FlatteningDeserializer(beanDesc.getBeanClass(), deserializer, mapper);
}
return deserializer;
}
Expand All @@ -72,16 +77,16 @@ public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, Bean

@SuppressWarnings("unchecked")
@Override
public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
JsonNode root = new AzureJacksonMapperAdapter().getObjectMapper().readTree(jp);
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
JsonNode root = mapper.readTree(jp);
final Class<?> tClass = this.defaultDeserializer.handledType();
for (Field field : tClass.getDeclaredFields()) {
JsonNode node = root;
JsonProperty property = field.getAnnotation(JsonProperty.class);
if (property != null) {
String value = property.value();
if (value.contains(".")) {
String[] values = value.split("\\.");
if (value.matches(".+[^\\\\]\\..+")) {
String[] values = value.split("((?<!\\\\))\\.");
for (String val : values) {
node = node.get(val);
if (node == null) {
Expand All @@ -94,7 +99,7 @@ public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOExcept
}
JsonParser parser = new JsonFactory().createParser(root.toString());
parser.nextToken();
return (T) defaultDeserializer.deserialize(parser, ctxt);
return defaultDeserializer.deserialize(parser, ctxt);
}

@Override
Expand Down
Loading

0 comments on commit c60a85b

Please sign in to comment.