Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
dc77d1b
- adds worfklow dispatch event to be able to manually trigger the wor…
baywet Jun 3, 2021
b73627f
Merge pull request #224 from microsoftgraph/feature/workflow-dispatch
baywet Jun 3, 2021
2aebd82
- updates sonarcloud configuration to match organization
baywet Jun 3, 2021
85b64cd
Merge pull request #225 from microsoftgraph/baywet-patch-1
baywet Jun 3, 2021
070de5b
Bump mockito-inline from 3.10.0 to 3.11.0
dependabot[bot] Jun 4, 2021
63b6dc3
Bump mockito-inline from 3.10.0 to 3.11.0
dependabot[bot] Jun 4, 2021
33cbaf9
Merge pull request #226 from microsoftgraph/dependabot/gradle/org.moc…
baywet Jun 4, 2021
9505b56
Merge pull request #227 from microsoftgraph/dependabot/maven/org.mock…
baywet Jun 4, 2021
cd5e4cb
Bump azure-core from 1.16.0 to 1.17.0
dependabot[bot] Jun 8, 2021
a3b7ebc
Bump azure-core from 1.16.0 to 1.17.0
dependabot[bot] Jun 8, 2021
fe6bfe0
Merge pull request #228 from microsoftgraph/dependabot/gradle/com.azu…
baywet Jun 8, 2021
35dd4fd
Merge pull request #229 from microsoftgraph/dependabot/maven/com.azur…
baywet Jun 8, 2021
ec55ce4
Bump org.sonarqube from 3.2.0 to 3.3
dependabot[bot] Jun 11, 2021
11397dc
Merge pull request #231 from microsoftgraph/dependabot/gradle/org.son…
baywet Jun 11, 2021
739b59e
- fixes a bug where passing null to additional data manager could lea…
baywet Jun 11, 2021
cde5553
- fixes a bug where the serializer would only look at first level pro…
baywet Jun 11, 2021
2b532c0
- code linting
baywet Jun 11, 2021
98e44d9
- more code linting
baywet Jun 11, 2021
0f3fb83
- pr feedback
baywet Jun 11, 2021
08f978e
- bumps patch version
baywet Jun 11, 2021
670f02a
Merge pull request #232 from microsoftgraph/bugfix/batch-serialization
baywet Jun 11, 2021
0cea75b
Merge pull request #233 from microsoftgraph/release/2-0-5
baywet Jun 11, 2021
735339e
Bump mockito-inline from 3.11.0 to 3.11.1
dependabot[bot] Jun 14, 2021
8af0ccd
Bump mockito-inline from 3.11.0 to 3.11.1
dependabot[bot] Jun 14, 2021
a3a02ea
Merge pull request #235 from microsoftgraph/dependabot/maven/org.mock…
baywet Jun 14, 2021
51aa1d1
Merge pull request #234 from microsoftgraph/dependabot/gradle/org.moc…
baywet Jun 14, 2021
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
3 changes: 2 additions & 1 deletion .github/workflows/api-level-lint.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: "Checks the SDK only using APIs from the targeted API level"

on:
on:
workflow_dispatch:
push:
branches:
- dev
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: "CodeQL"

on:
workflow_dispatch:
push:
branches: [dev, master]
pull_request:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/conflicting-pr-label.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ name: PullRequestConflicting
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
workflow_dispatch:
push:
branches: [ master, dev ]
pull_request:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/sample-build-check.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: "samples build check"

on:
workflow_dispatch:
push:
paths:
- '**/*.java'
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: Static analysis with SonarCloud
on:
workflow_dispatch:
push:
branches:
- master
Expand Down
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ plugins {
id 'signing'
id 'jacoco'
id 'com.github.spotbugs' version '4.7.1'
id "org.sonarqube" version "3.2.0"
id "org.sonarqube" version "3.3"
}

java {
Expand Down Expand Up @@ -91,8 +91,8 @@ def pomConfig = {

sonarqube {
properties {
property "sonar.projectKey", "msgraph-sdk-java-core"
property "sonar.organization", "microsoftgraph"
property "sonar.projectKey", "microsoftgraph_msgraph-sdk-java-core"
property "sonar.organization", "microsoftgraph2"
Copy link
Contributor

Choose a reason for hiding this comment

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

What happened to microsoftgraph org?

property "sonar.host.url", "https://sonarcloud.io"
}
}
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mavenGroupId = com.microsoft.graph
mavenArtifactId = microsoft-graph-core
mavenMajorVersion = 2
mavenMinorVersion = 0
mavenPatchVersion = 4
mavenPatchVersion = 5
mavenArtifactSuffix =

#These values are used to run functional tests
Expand Down
4 changes: 2 additions & 2 deletions gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ dependencies {
// Use JUnit test framework
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2'
testImplementation 'org.mockito:mockito-inline:3.10.0'
testImplementation 'org.mockito:mockito-inline:3.11.1'

api 'com.squareup.okhttp3:okhttp:4.9.1'

implementation 'com.google.guava:guava:30.1.1-jre'

implementation 'com.google.code.gson:gson:2.8.7'
api 'com.azure:azure-core:1.16.0'
api 'com.azure:azure-core:1.17.0'
}
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-core</artifactId>
<version>1.16.0</version>
<version>1.17.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand All @@ -46,7 +46,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.10.0</version>
<version>3.11.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
8 changes: 4 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ repositories {

dependencies {
// Include the sdk as a dependency
implementation 'com.microsoft.graph:microsoft-graph-core:2.0.4'
implementation 'com.microsoft.graph:microsoft-graph-core:2.0.5'
// This dependency is only needed if you are using the TokenCrendentialAuthProvider
implementation 'com.azure:azure-identity:1.2.5'
implementation 'com.azure:azure-identity:1.3.1'
}
```

Expand All @@ -37,11 +37,11 @@ Add the dependency in `dependencies` in pom.xml
<!-- Include the sdk as a dependency -->
<groupId>com.microsoft.graph</groupId>
<artifactId>microsoft-graph-core</artifactId>
<version>2.0.4</version>
<version>2.0.5</version>
<!-- This dependency is only needed if you are using the TokenCrendentialAuthProvider -->
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.2.5</version>
<version>1.3.1</version>
</dependency>
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class TelemetryHandler implements Interceptor{
/**
* Current SDK version
*/
public static final String VERSION = "v2.0.4";
public static final String VERSION = "v2.0.5";
/**
* Verion prefix
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// ------------------------------------------------------------------------------
// Copyright (c) 2017 Microsoft Corporation
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down Expand Up @@ -38,12 +38,12 @@
public class AdditionalDataManager extends HashMap<String, JsonElement> {

private static final long serialVersionUID = 8641634955796941429L;

private final transient IJsonBackedObject jsonBackedObject;

/**
* Instanciates a new additional data manager from the json backed object
*
*
* @param jsonBackedObject the object to read values from
*/
public AdditionalDataManager(@Nullable final IJsonBackedObject jsonBackedObject) {
Expand All @@ -56,15 +56,15 @@ public AdditionalDataManager(@Nullable final IJsonBackedObject jsonBackedObject)
*
* @param json the raw JSON to set as additionalData
*/
final void setAdditionalData(JsonObject json) {
final void setAdditionalData(final JsonObject json) {
// Get the names of all the fields on this object's hierarchy
Set<String> objectFields = getFields();
final Set<String> objectFields = getFields();

// Get the keys on this JSON
Set<String> jsonKeys = getJsonKeys(json);
final Set<String> jsonKeys = getJsonKeys(json);

// Get all keys present in JSON and *NOT* present in fields
Set<String> additionalDataKeys = new HashSet<>(jsonKeys);
final Set<String> additionalDataKeys = new HashSet<>(jsonKeys);
additionalDataKeys.removeAll(objectFields);

// set the additionalData
Expand All @@ -73,23 +73,25 @@ final void setAdditionalData(JsonObject json) {
}
}

private Set<String> getJsonKeys(JsonObject json) {
Set<String> keys = new HashSet<>();
Set<Map.Entry<String, JsonElement>> entries = json.entrySet();
private Set<String> getJsonKeys(final JsonObject json) {
final Set<String> keys = new HashSet<>();
final Set<Map.Entry<String, JsonElement>> entries = json.entrySet();
for (Map.Entry<String, JsonElement> entry : entries) {
keys.add(entry.getKey());
}
return keys;
}

private Set<String> getFields() {
Field[] fields = jsonBackedObject.getClass().getFields();
Set<String> serializingFields = new HashSet<>();
for (Field field : fields) {
SerializedName serializedName;
if (null != (serializedName = field.getAnnotation(SerializedName.class))
&& null != field.getAnnotation(Expose.class)) {
serializingFields.add(serializedName.value());
final Set<String> serializingFields = new HashSet<>();
if(jsonBackedObject != null ) {
final Field[] fields = jsonBackedObject.getClass().getFields();
for (Field field : fields) {
final SerializedName serializedName = field.getAnnotation(SerializedName.class);
if (null != serializedName
&& null != field.getAnnotation(Expose.class)) {
serializingFields.add(serializedName.value());
}
}
}
return serializingFields;
Expand Down
141 changes: 53 additions & 88 deletions src/main/java/com/microsoft/graph/serializer/DefaultSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,109 +223,74 @@ else if (fieldObject instanceof IJsonBackedObject) {
public <T> String serializeObject(@Nonnull final T serializableObject) {
Objects.requireNonNull(serializableObject, "parameter serializableObject cannot be null");
logger.logDebug("Serializing type " + serializableObject.getClass().getSimpleName());
JsonElement outJsonTree = gson.toJsonTree(serializableObject);

if (serializableObject instanceof IJsonBackedObject) {
outJsonTree = getDataFromAdditionalDataManager(outJsonTree, serializableObject);
} else if (outJsonTree.isJsonObject()) {
final Field[] fields = serializableObject.getClass().getDeclaredFields();
JsonObject outJson = outJsonTree.getAsJsonObject();
for(Field field : fields) {
if(outJson.has(field.getName())) {
final Type[] interfaces = field.getType().getGenericInterfaces();
for(Type interfaceType : interfaces) {
if(interfaceType == IJsonBackedObject.class && outJson.get(field.getName()).isJsonObject()) {
try {
final JsonElement outdatedValue = outJson.remove(field.getName());
outJson.add(field.getName(), getDataFromAdditionalDataManager(outdatedValue.getAsJsonObject(), field.get(serializableObject)));
} catch (IllegalAccessException ex ) {
logger.logDebug("Couldn't access prop" + field.getName());
}
break;
}
}
}
}
}

return outJsonTree.toString();
}
private <T> JsonElement getDataFromAdditionalDataManager(JsonElement outJsonTree, final T serializableObject) {
final IJsonBackedObject serializableJsonObject = (IJsonBackedObject) serializableObject;
final AdditionalDataManager additionalData = serializableJsonObject.additionalDataManager();

// If the item is a valid Graph object, add its additional data
if (outJsonTree.isJsonObject()) {
final JsonObject outJson = outJsonTree.getAsJsonObject();

addAdditionalDataFromManagerToJson(additionalData, outJson);
getChildAdditionalData(serializableJsonObject, outJson);

return outJson;
} else {
return outJsonTree;
final JsonElement outJsonTree = gson.toJsonTree(serializableObject);
if(outJsonTree != null) {
getChildAdditionalData(serializableObject, outJsonTree);
return outJsonTree.toString();
}
return "";
}

/**
* Recursively populates additional data for each child object
*
* @param serializableObject the child to get additional data for
* @param outJson the serialized output JSON to add to
*/
@SuppressWarnings("unchecked")
private void getChildAdditionalData(final IJsonBackedObject serializableObject, final JsonObject outJson) {
if(outJson == null)
return;
// Use reflection to iterate through fields for eligible Graph children
for (java.lang.reflect.Field field : serializableObject.getClass().getFields()) {
try {
final Object fieldObject = field.get(serializableObject);
final JsonElement fieldJsonElement = outJson.get(field.getName());
if(fieldObject == null || fieldJsonElement == null)
continue;

// If the object is a HashMap, iterate through its children
if (fieldObject instanceof Map && fieldJsonElement.isJsonObject()) {
final Map<String, Object> serializableChildren = (Map<String, Object>) fieldObject;
final Iterator<Entry<String, Object>> it = serializableChildren.entrySet().iterator();
final JsonObject fieldJsonObject = fieldJsonElement.getAsJsonObject();

while (it.hasNext()) {
final Map.Entry<String, Object> pair = (Map.Entry<String, Object>)it.next();
final Object child = pair.getValue();
final JsonElement childJsonElement = fieldJsonObject.get(pair.getKey().toString());
// If the item is a valid Graph object, add its additional data
addAdditionalDataFromJsonElementToJson(child, childJsonElement);
}
}
// If the object is a list of Graph objects, iterate through elements
else if (fieldObject instanceof List && fieldJsonElement.isJsonArray()) {
final JsonArray fieldArrayValue = fieldJsonElement.getAsJsonArray();
final List<?> fieldObjectList = (List<?>) fieldObject;
for (int index = 0; index < fieldObjectList.size(); index++) {
final Object item = fieldObjectList.get(index);
final JsonElement itemJsonElement = fieldArrayValue.get(index);
addAdditionalDataFromJsonElementToJson(item, itemJsonElement);
}
}
// If the object is a valid Graph object, add its additional data
addAdditionalDataFromJsonElementToJson(fieldObject, fieldJsonElement);
} catch (IllegalArgumentException | IllegalAccessException e) {
logger.logError("Unable to access child fields of " + serializableObject.getClass().getSimpleName(), e);
}
}
}
private void getChildAdditionalData(final Object serializableObject, final JsonElement outJson) {
if(outJson == null || serializableObject == null || !outJson.isJsonObject())
return;
final JsonObject outJsonObject = outJson.getAsJsonObject();
// Use reflection to iterate through fields for eligible Graph children
for (java.lang.reflect.Field field : serializableObject.getClass().getFields()) {
try {
final Object fieldObject = field.get(serializableObject);
final JsonElement fieldJsonElement = outJsonObject.get(field.getName());
if(fieldObject == null || fieldJsonElement == null)
continue;

// If the object is a HashMap, iterate through its children
if (fieldObject instanceof Map && fieldJsonElement.isJsonObject()) {
final Map<String, Object> serializableChildren = (Map<String, Object>) fieldObject;
final Iterator<Entry<String, Object>> it = serializableChildren.entrySet().iterator();
final JsonObject fieldJsonObject = fieldJsonElement.getAsJsonObject();

while (it.hasNext()) {
final Map.Entry<String, Object> pair = (Map.Entry<String, Object>)it.next();
final Object child = pair.getValue();
final JsonElement childJsonElement = fieldJsonObject.get(pair.getKey().toString());
// If the item is a valid Graph object, add its additional data
getChildAdditionalData(child, childJsonElement);
}
}
// If the object is a list of Graph objects, iterate through elements
else if (fieldObject instanceof List && fieldJsonElement.isJsonArray()) {
final JsonArray fieldArrayValue = fieldJsonElement.getAsJsonArray();
final List<?> fieldObjectList = (List<?>) fieldObject;
for (int index = 0; index < fieldObjectList.size(); index++) {
final Object item = fieldObjectList.get(index);
final JsonElement itemJsonElement = fieldArrayValue.get(index);
getChildAdditionalData(item, itemJsonElement);
}
} else if(fieldJsonElement.isJsonObject()) {
// If the object is a valid Graph object, add its additional data
final JsonObject fieldJsonObject = fieldJsonElement.getAsJsonObject();
addAdditionalDataFromJsonObjectToJson(fieldObject, fieldJsonObject);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
logger.logError("Unable to access child fields of " + serializableObject.getClass().getSimpleName(), e);
}
}
}

/**
* Add each non-transient additional data property to the given JSON node
*
* @param item the object containing additional data
* @param itemJsonElement the JSON node to add the additional data properties to
* @param itemJsonObject the JSON node to add the additional data properties to
*/
private void addAdditionalDataFromJsonElementToJson (final Object item, final JsonElement itemJsonElement) {
if (item instanceof IJsonBackedObject && itemJsonElement.isJsonObject()) {
final JsonObject itemJsonObject = itemJsonElement.getAsJsonObject();
private void addAdditionalDataFromJsonObjectToJson (final Object item, final JsonObject itemJsonObject) {
if (item instanceof IJsonBackedObject && itemJsonObject != null) {
final IJsonBackedObject serializableItem = (IJsonBackedObject) item;
final AdditionalDataManager itemAdditionalData = serializableItem.additionalDataManager();
addAdditionalDataFromManagerToJson(itemAdditionalData, itemJsonObject);
Expand Down
Loading