Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/core/azure-core-experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 1.0.0-beta.7 (Unreleased)

- Added : API `fromObject()` in `BinaryData` which uses `JsonSerializer` present in the classpath.

## 1.0.0-beta.6 (2020-10-06)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

import com.azure.core.util.FluxUtil;
import com.azure.core.util.logging.ClientLogger;
import com.azure.core.util.serializer.JsonSerializerProviders;
import com.azure.core.util.serializer.ObjectSerializer;
import com.azure.core.util.serializer.JsonSerializer;
import com.azure.core.util.serializer.TypeReference;
import static com.azure.core.util.FluxUtil.monoError;

Expand All @@ -18,7 +20,6 @@
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
Expand Down Expand Up @@ -47,15 +48,20 @@
*/
public final class BinaryData {
private static final ClientLogger LOGGER = new ClientLogger(BinaryData.class);

private static JsonSerializer defaultJsonSerializer;
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
private static byte[] EMPTY_DATA = new byte[0];
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
private final byte[] data;

/**
* Create instance of {@link BinaryData} given the data.
* Create instance of {@link BinaryData} given the data. If {@code null} value is provided , it will be converted
* into empty byte array.
* @param data to represent as bytes.
* @throws NullPointerException If {@code data} is null.
*/
BinaryData(byte[] data) {
Objects.requireNonNull(data, "'data' cannot be null.");
if (Objects.isNull(data)) {
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
data = EMPTY_DATA;
}
this.data = Arrays.copyOf(data, data.length);
}

Expand All @@ -71,15 +77,6 @@ public InputStream toStream() {
return new ByteArrayInputStream(this.data);
}

/**
* Provides {@link Mono} of {@link InputStream} for the data represented by this {@link BinaryData} object.
*
* @return {@link InputStream} representation of the {@link BinaryData}.
*/
public Mono<InputStream> toStreamAsync() {
return Mono.fromCallable(() -> toStream());
}

/**
* Create {@link BinaryData} instance with given {@link InputStream} as source of data. The {@link InputStream} is
* not closed by this function.
Expand Down Expand Up @@ -144,39 +141,26 @@ public static Mono<BinaryData> fromFlux(Flux<ByteBuffer> data) {
.flatMap(bytes -> Mono.just(fromBytes(bytes)));
}

/**
* Create {@link BinaryData} instance with given data and character set.
*
* <p><strong>Create an instance from String</strong></p>
* {@codesnippet com.azure.core.experimental.util.BinaryDocument.from#String}
*
* @param data to use.
* @param charSet to use.
* @throws NullPointerException if {@code inputStream} is null.
* @return {@link BinaryData} representing the binary data.
*/
public static BinaryData fromString(String data, Charset charSet) {
Objects.requireNonNull(data, "'data' cannot be null.");

return new BinaryData(data.getBytes(charSet));
}

/**
* Create {@link BinaryData} instance with given data. The {@link String} is converted into bytes using
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
* {@link StandardCharsets#UTF_8} character set.
* {@link StandardCharsets#UTF_8} character set. If {@code null} data is provided , it will be converted into
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
* empty byte array.
*
* @param data to use.
* @throws NullPointerException if {@code inputStream} is null.
* @return {@link BinaryData} representing binary data.
*/
public static BinaryData fromString(String data) {
Objects.requireNonNull(data, "'data' cannot be null.");
if (Objects.isNull(data)) {
return new BinaryData(EMPTY_DATA);
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
} else {
return new BinaryData(data.getBytes(StandardCharsets.UTF_8));
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
}

return new BinaryData(data.getBytes(StandardCharsets.UTF_8));
}

/**
* Create {@link BinaryData} instance with given byte array data.
* Create {@link BinaryData} instance with given byte array data. If {@code null} value is provided , it will be
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
* converted into empty byte array.
*
* @param data to use.
* @return {@link BinaryData} representing the binary data.
Expand All @@ -185,16 +169,42 @@ public static BinaryData fromBytes(byte[] data) {
return new BinaryData(data);
}

/**
* Serialize the given {@link Object} into {@link BinaryData} using json serializer which is available in classpath.
* The serializer must implement {@link JsonSerializer} interface. A singleton instance of {@link JsonSerializer}
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
* is kept for this class to use. If {@code null} data is provided , it will be converted into empty byte array.
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
*
* @param data The {@link Object} which needs to be serialized into bytes.
* @throws IllegalStateException If a {@link JsonSerializer} cannot be found on the classpath.
* @return {@link BinaryData} representing binary data.
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
*
* @see JsonSerializer
*/
public static BinaryData fromObject(Object data) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this API is converting into JSON we may want to call it fromObjectJson.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we change it, we need to sync with .Net. I copied this API name from them.

if (Objects.isNull(data)) {
return new BinaryData(EMPTY_DATA);
}
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
loadDefaultSerializer();
defaultJsonSerializer.serialize(outputStream, data);

return new BinaryData(outputStream.toByteArray());
}

/**
* Serialize the given {@link Object} into {@link BinaryData} using the provided {@link ObjectSerializer}.
* If {@code null} data is provided , it will be converted into empty byte array.
*
* @param data The {@link Object} which needs to be serialized into bytes.
* @param serializer to use for serializing the object.
* @throws NullPointerException if {@code inputStream} or {@code serializer} is null.
* @throws NullPointerException if {@code serializer} is null.
* @return {@link BinaryData} representing binary data.
*/
public static BinaryData fromObject(Object data, ObjectSerializer serializer) {
Objects.requireNonNull(data, "'data' cannot be null.");
if (Objects.isNull(data)) {
return new BinaryData(EMPTY_DATA);
}

Objects.requireNonNull(serializer, "'serializer' cannot be null.");

final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Expand All @@ -204,19 +214,16 @@ public static BinaryData fromObject(Object data, ObjectSerializer serializer) {

/**
* Serialize the given {@link Object} into {@link Mono} {@link BinaryData} using the provided
* {@link ObjectSerializer}.
* {@link ObjectSerializer}. If {@code null} data is provided , it will be converted into empty byte array.
*
* @param data The {@link Object} which needs to be serialized into bytes.
* @param serializer to use for serializing the object.
* @throws NullPointerException if {@code inputStream} or {@code serializer} is null.
* @throws NullPointerException if {@code serializer} is null.
* @return {@link Mono} of {@link BinaryData} representing the binary data.
*/
public static Mono<BinaryData> fromObjectAsync(Object data, ObjectSerializer serializer) {
Objects.requireNonNull(data, "'data' cannot be null.");
Objects.requireNonNull(serializer, "'serializer' cannot be null.");

return Mono.fromCallable(() -> fromObject(data, serializer));

}

/**
Expand All @@ -238,16 +245,6 @@ public String toString() {
return new String(this.data, StandardCharsets.UTF_8);
}

/**
* Provides {@link String} representation of this {@link BinaryData} object given a character set.
*
* @param charSet to use to convert bytes into {@link String}.
* @return {@link String} representation of the the binary data.
*/
public String toString(Charset charSet) {
return new String(this.data, charSet);
}

/**
* Deserialize the bytes into the {@link Object} of given type by applying the provided {@link ObjectSerializer} on
* the data.
Expand Down Expand Up @@ -282,4 +279,43 @@ public <T> T toObject(Class<T> clazz, ObjectSerializer serializer) {
public <T> Mono<T> toObjectAsync(Class<T> clazz, ObjectSerializer serializer) {
return Mono.fromCallable(() -> toObject(clazz, serializer));
}

/**
* Deserialize the bytes into the {@link Object} of given type by applying the provided {@link ObjectSerializer} on
* the data. The serializer must implement {@link JsonSerializer} interface.
*
* @param clazz representing the type of the Object.
* @param <T> Generic type that the data is deserialized into.
* @return The {@link Object} of given type after deserializing the bytes.
*/
public <T> T toObject(Class<T> clazz) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we rename this API to something JSON specific? toJsonObject?

@JonathanGiles @srnagar

@hemanttanwar hemanttanwar Oct 21, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might force us, in future, to add other API for other formats.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JsonObject has a different meaning. So, I think toObject() is fine as we will return a strongly-typed user-defined object here.

Objects.requireNonNull(clazz, "'clazz' cannot be null.");

TypeReference<T> ref = TypeReference.createInstance(clazz);
InputStream jsonStream = new ByteArrayInputStream(this.data);
loadDefaultSerializer();
return defaultJsonSerializer.deserialize(jsonStream, ref);
}

/**
* Return a {@link Mono} by deserialize the bytes into the {@link Object} of given type after applying the Json
Comment thread
hemanttanwar marked this conversation as resolved.
Outdated
* serializer found on classpath.
*
* <p><strong>Gets the specified object</strong></p>
* {@codesnippet com.azure.core.experimental.util.BinaryDocument.to#ObjectAsync}
*
* @param clazz representing the type of the Object.
* @param <T> Generic type that the data is deserialized into.
* @throws NullPointerException if {@code clazz} or {@code serializer} is null.
* @return The {@link Object} of given type after deserializing the bytes.
*/
public <T> Mono<T> toObjectAsync(Class<T> clazz) {
return Mono.fromCallable(() -> toObject(clazz));
}

private static void loadDefaultSerializer() {
if (defaultJsonSerializer == null) {
defaultJsonSerializer = JsonSerializerProviders.createInstance();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,3 @@ public Mono<Void> serializeAsync(OutputStream stream, Object value) {
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,6 @@ public void createFromString() {
assertEquals(expected, data.toString());
}

@Test
public void createFromStringCharSet() {
// Arrange
final String expected = "Doe";

// Act
final BinaryData data = BinaryData.fromString(expected, StandardCharsets.UTF_8);

// Assert
assertArrayEquals(expected.getBytes(), data.toBytes());
assertEquals(expected, data.toString(StandardCharsets.UTF_8));
}

@Test
public void createFromByteArray() {
// Arrange
Expand Down Expand Up @@ -152,27 +139,6 @@ public void createFromStreamAsync() throws IOException {
.verifyComplete();
}

@Test
public void createToStreamAsync() {
// Arrange
final byte[] expected = "Doe".getBytes(StandardCharsets.UTF_8);
final BinaryData actual = BinaryData.fromStreamAsync(new ByteArrayInputStream(expected)).block();
// Act & Assert
StepVerifier.create(actual.toStreamAsync())
.assertNext(inutStream -> {
byte[] actualBytes = new byte[expected.length];

// Act
try {
inutStream.read(actualBytes, 0, expected.length);
} catch (IOException e) {
e.printStackTrace();
}
Assertions.assertArrayEquals(expected, actualBytes);
})
.verifyComplete();
}

@Test
public void createFromObjectAsync() {
// Arrange
Expand Down