Skip to content

Commit d1b880a

Browse files
author
cbales
committed
Merge branch 'master' into cbales-working
2 parents 12ca27f + 00a0747 commit d1b880a

21 files changed

+29798
-17
lines changed

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Currently the following target languages are supported by this writer:
1010
- Objective-C
1111
- Python
1212
- TypeScript
13+
- PHP
1314

1415
# Contents
1516
- [Prerequisites](#prerequisites)
@@ -19,8 +20,8 @@ Currently the following target languages are supported by this writer:
1920
- [License](#license)
2021

2122
## Prerequisites
22-
- [Visual Studio SDK](https://www.microsoft.com/en-us/download/details.aspx?id=40758)
23-
- [Visual Studio Modeling SDK](https://www.microsoft.com/en-us/download/details.aspx?id=40754)
23+
- [Visual Studio SDK](https://msdn.microsoft.com/en-us/library/bb166441.aspx)
24+
- [Visual Studio Modeling SDK](https://msdn.microsoft.com/en-us/library/bb126259.aspx)
2425

2526
# Getting started
2627

@@ -123,6 +124,21 @@ Note: You can also check in a template by `odcjObject.LongDescriptionContains("f
123124

124125
**Note: Includes/Excludes and Ignore/Matches were used before Vipr had full support for annotations; now that annotations have been added to Vipr usage of these parameters should be limited to legacy scenarios**
125126

127+
## Building against Graph Metadata
128+
129+
There are currently several steps we take to form the metadata into one that will successfully generate SDKs in the shape we expect:
130+
131+
- Remove capability annotations (see [#132](https://github.com/Microsoft/Vipr/issues/132))
132+
- Add navigation annotation to thumbnail
133+
```xml
134+
<Annotation String="navigable" Term="Org.OData.Core.V1.LongDescription"/>
135+
```
136+
- Remove HasStream properties from ```onenotePage``` and ```onenoteEntityBaseModel```
137+
- Add ```ContainsTarget="true"``` to navigation properties that do not have a corresponding EntitySet
138+
- Add long descriptions to types and properties from [docs](https://developer.microsoft.com/en-us/graph/docs/concepts/overview)
139+
140+
In order to build against metadata other than that stored in the [metadata](https://github.com/microsoftgraph/MSGraph-SDK-Code-Generator/tree/master/metadata) directory, you will need to perform the first four on this list.
141+
126142
## Contributing
127143

128144
Before we can accept your pull request, you'll need to electronically complete Microsoft's [Contributor License Agreement](https://cla.microsoft.com/). If you've done this for other Microsoft projects, then you're already covered.

Templates/Android/BaseModel.template.tt

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<#@ template debug="true" hostspecific="true" language="C#" #>
33
<#@ output extension="\\" #>
44
<#
5+
56
CustomT4Host host = (CustomT4Host) Host;
67
var model = host.CurrentModel;
78
CodeWriterAndroid writer = (CodeWriterAndroid) host.CodeWriter;
@@ -620,7 +621,7 @@ public {1} {2}{3}{4} {{";
620621
var format =
621622
@" /**
622623
* The {0}.
623-
* {4}
624+
* {4}
624625
*/
625626
@SerializedName(""{1}"")
626627
@Expose
@@ -630,7 +631,7 @@ public {1} {2}{3}{4} {{";
630631
var collectionFormat =
631632
@" /**
632633
* The {0}.
633-
* {4}
634+
* {4}
634635
*/
635636
public transient {2} {3};
636637

@@ -675,7 +676,7 @@ public {1} {2}{3}{4} {{";
675676
var format =
676677
@" /**
677678
* The {0}.
678-
* {1}
679+
* {1}
679680
*/
680681
@SerializedName(""{2}"")
681682
@Expose
@@ -799,4 +800,59 @@ public {1} {2}{3}{4} {{";
799800
return
800801
@"// **NOTE** This file was generated by a tool and any changes will be overwritten.";
801802
}
803+
804+
/*
805+
* Add additional methods to a generated class
806+
* @param className The class that you will be adding methods to
807+
* @return The additional text to add to the generated file
808+
*/
809+
public string AddCustomCode(string className) {
810+
CustomMethods customMethods = new CustomMethods();
811+
var type = customMethods.GetType();
812+
var property = type.GetFields().Where(x => x.Name == className).FirstOrDefault();
813+
814+
return property != null ? property.GetValue(customMethods).ToString() : string.Empty;
815+
}
816+
817+
/*
818+
* Add additional import statements to a generated class
819+
* @param className The class that you will be adding methods to
820+
* @return The additional text to add to the generated file
821+
*/
822+
public string AddCustomImport(string className) {
823+
CustomImports customImports = new CustomImports();
824+
var type = customImports.GetType();
825+
var property = type.GetFields().Where(x => x.Name == className).FirstOrDefault();
826+
827+
return property != null ? property.GetValue(customImports).ToString() : string.Empty;
828+
}
829+
830+
/*
831+
* Find and replace overwrite values for the given class
832+
* @param className The class that you will be applying overwrites to
833+
* @return An empty string (does not write anything new to the file)
834+
*/
835+
public string PostProcess(string className)
836+
{
837+
//Load the StringBuilder with the file contents
838+
var strb = this.GenerationEnvironment;
839+
840+
//Get the list of available classes to overwrite
841+
CustomOverwrites customOverwrites = new CustomOverwrites();
842+
var type = customOverwrites.GetType();
843+
844+
//Load the dictionary that corresponds to the current class
845+
var results = type.GetFields().Where(x => x.Name == className).FirstOrDefault();
846+
847+
if (results != null) {
848+
var dictionary = (Dictionary<string, string>)results.GetValue(this);
849+
//Find and replace for each item in the dictionary
850+
foreach (var item in dictionary) {
851+
strb.Replace(item.Key, item.Value);
852+
}
853+
}
854+
//This seems to be a requirement of the template builder
855+
//Specifying a return type of "void" throws an error
856+
return string.Empty;
857+
}
802858
#>
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<# // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. #>
2+
<#@ template debug="true" hostspecific="true" language="C#" #>
3+
<#@ include file="BaseModel.template.tt"#>
4+
<#@ output extension="\\" #>
5+
<#=writer.WriteHeader()#>
6+
package com.microsoft.graph.extensions;
7+
8+
import com.microsoft.graph.concurrency.ChunkedUploadResponseHandler;
9+
import com.microsoft.graph.core.ClientException;
10+
import com.microsoft.graph.core.GraphErrorCodes;
11+
import com.microsoft.graph.http.BaseRequest;
12+
import com.microsoft.graph.http.HttpMethod;
13+
import com.microsoft.graph.options.Option;
14+
15+
import java.util.List;
16+
17+
/**
18+
* The chunk upload request.
19+
*/
20+
public class ChunkedUploadRequest {
21+
22+
/**
23+
* Content Range header name.
24+
*/
25+
private static final String CONTENT_RANGE_HEADER_NAME = "Content-Range";
26+
27+
/**
28+
* Content Range value format.
29+
*/
30+
private static final String CONTENT_RANGE_FORMAT = "bytes %1$d-%2$d/%3$d";
31+
32+
/**
33+
* The seconds for retry delay.
34+
*/
35+
private static final int RETRY_DELAY = 2 * 1000;
36+
37+
/**
38+
* The chunk data sent to the server.
39+
*/
40+
private final byte[] mData;
41+
42+
/**
43+
* The base request.
44+
*/
45+
private final BaseRequest mBaseRequest;
46+
47+
/**
48+
* The max retry for single request.
49+
*/
50+
private final int mMaxRetry;
51+
52+
/**
53+
* The retry counter.
54+
*/
55+
private int mRetryCount;
56+
57+
/**
58+
* Construct the ChunkedUploadRequest
59+
*
60+
* @param requestUrl The upload url.
61+
* @param client The OneDrive client.
62+
* @param options The query options.
63+
* @param chunk The chunk byte array.
64+
* @param chunkSize The chunk array size.
65+
* @param maxRetry The limit on retry.
66+
* @param beginIndex The begin index of this chunk in the input stream.
67+
* @param totalLength The total length of the input stream.
68+
*/
69+
public ChunkedUploadRequest(final String requestUrl,
70+
final IGraphServiceClient client,
71+
final List<Option> options,
72+
final byte[] chunk,
73+
final int chunkSize,
74+
final int maxRetry,
75+
final int beginIndex,
76+
final int totalLength) {
77+
this.mData = new byte[chunkSize];
78+
System.arraycopy(chunk, 0, this.mData, 0, chunkSize);
79+
this.mRetryCount = 0;
80+
this.mMaxRetry = maxRetry;
81+
this.mBaseRequest = new BaseRequest(requestUrl, client, options, ChunkedUploadResult.class) {
82+
};
83+
this.mBaseRequest.setHttpMethod(HttpMethod.PUT);
84+
this.mBaseRequest.addHeader(CONTENT_RANGE_HEADER_NAME,
85+
String.format(
86+
CONTENT_RANGE_FORMAT,
87+
beginIndex,
88+
beginIndex + chunkSize - 1,
89+
totalLength));
90+
}
91+
92+
/**
93+
* Upload a chunk with tries.
94+
*
95+
* @param responseHandler The handler handle http response.
96+
* @param <UploadType> The upload item type.
97+
* @return The upload result.
98+
*/
99+
public <UploadType> ChunkedUploadResult upload(
100+
final ChunkedUploadResponseHandler<UploadType> responseHandler) {
101+
while (this.mRetryCount < this.mMaxRetry) {
102+
try {
103+
Thread.sleep(RETRY_DELAY * this.mRetryCount * this.mRetryCount);
104+
} catch (final InterruptedException e) {
105+
this.mBaseRequest.getClient().getLogger().logError("Exception while waiting upload file retry", e);
106+
}
107+
108+
ChunkedUploadResult result = null;
109+
110+
try {
111+
result = this.mBaseRequest
112+
.getClient()
113+
.getHttpProvider()
114+
.send(mBaseRequest, ChunkedUploadResult.class, this.mData, responseHandler);
115+
} catch (final ClientException e) {
116+
this.mBaseRequest.getClient().getLogger().logDebug("Request failed with, retry if necessary.");
117+
}
118+
119+
if (result != null && result.chunkCompleted()) {
120+
return result;
121+
}
122+
123+
this.mRetryCount++;
124+
}
125+
126+
return new ChunkedUploadResult(
127+
new ClientException("Upload session failed to many times.", null,
128+
GraphErrorCodes.UploadSessionIncomplete));
129+
}
130+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<# // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. #>
2+
<#@ template debug="true" hostspecific="true" language="C#" #>
3+
<#@ include file="BaseModel.template.tt"#>
4+
<#@ output extension="\\" #>
5+
<#=writer.WriteHeader()#>
6+
package com.microsoft.graph.extensions;
7+
8+
import com.microsoft.graph.core.ClientException;
9+
import com.microsoft.graph.core.GraphErrorCodes;
10+
import com.microsoft.graph.http.GraphServiceException;
11+
12+
/**
13+
* Wrapper class for different upload response from server.
14+
*/
15+
public class ChunkedUploadResult<UploadType> {
16+
/**
17+
* The uploaded item response.
18+
*/
19+
private final UploadType mUploadedItem;
20+
21+
/**
22+
* The next session response.
23+
*/
24+
private final UploadSession mSession;
25+
26+
/**
27+
* The error happened during upload.
28+
*/
29+
private final ClientException mError;
30+
31+
/**
32+
* Construct result with item created.
33+
*
34+
* @param uploaded The created item.
35+
*/
36+
public ChunkedUploadResult(UploadType uploaded) {
37+
this.mUploadedItem = uploaded;
38+
this.mSession = null;
39+
this.mError = null;
40+
}
41+
42+
/**
43+
* Construct result with next session.
44+
*
45+
* @param session The next session.
46+
*/
47+
public ChunkedUploadResult(UploadSession session) {
48+
this.mSession = session;
49+
this.mUploadedItem = null;
50+
this.mError = null;
51+
}
52+
53+
/**
54+
* Construct result with error.
55+
*
56+
* @param error The error occurred during uploading.
57+
*/
58+
public ChunkedUploadResult(ClientException error) {
59+
this.mError = error;
60+
this.mUploadedItem = null;
61+
this.mSession = null;
62+
}
63+
64+
/**
65+
* Construct result with server exception.
66+
*
67+
* @param exception The exception received from server.
68+
*/
69+
public ChunkedUploadResult(GraphServiceException exception) {
70+
this(new ClientException(exception.getMessage(/* verbose */ true), exception, GraphErrorCodes.UploadSessionFailed));
71+
}
72+
73+
/**
74+
* Checks the chunk upload is completed.
75+
*
76+
* @return true if current chunk upload is completed.
77+
*/
78+
public boolean chunkCompleted() {
79+
return this.mUploadedItem != null || this.mSession != null;
80+
}
81+
82+
/**
83+
* Checks the whole upload is completed.
84+
*
85+
* @return true if the response is a an item.
86+
*/
87+
public boolean uploadCompleted() {
88+
return this.mUploadedItem != null;
89+
}
90+
91+
/**
92+
* Checks if error happened.
93+
*
94+
* @return true if current request has error.
95+
*/
96+
public boolean hasError() {
97+
return this.mError != null;
98+
}
99+
100+
/**
101+
* Get the uploaded item.
102+
*
103+
* @return The item.
104+
*/
105+
public UploadType getItem() {
106+
return this.mUploadedItem;
107+
}
108+
109+
/**
110+
* Get the next session.
111+
*
112+
* @return The next session for uploading.
113+
*/
114+
public UploadSession getSession() {
115+
return this.mSession;
116+
}
117+
118+
/**
119+
* Get the error.
120+
*
121+
* @return The error.
122+
*/
123+
public ClientException getError() {
124+
return this.mError;
125+
}
126+
}

0 commit comments

Comments
 (0)