Skip to content

Commit 6123832

Browse files
Modularized Parse.Core
1 parent 8255eb6 commit 6123832

File tree

102 files changed

+1798
-617
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+1798
-617
lines changed

Parse/Internal/Authentication/IParseAuthenticationProvider.cs renamed to ParseCore/Internal/Authentication/IParseAuthenticationProvider.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
using System.Threading;
55
using System.Threading.Tasks;
66

7-
namespace Parse.Internal {
8-
interface IParseAuthenticationProvider {
7+
namespace Parse.Core.Internal {
8+
public interface IParseAuthenticationProvider {
99
/// <summary>
1010
/// Authenticates with the service.
1111
/// </summary>
1212
/// <param name="cancellationToken">The cancellation token.</param>
1313
Task<IDictionary<string, object>> AuthenticateAsync(CancellationToken cancellationToken);
14-
14+
1515
/// <summary>
1616
/// Deauthenticates (logs out) the user associated with this provider. This
1717
/// call may block.

Parse/Internal/Cloud/Controller/IParseCloudCodeController.cs renamed to ParseCore/Internal/Cloud/Controller/IParseCloudCodeController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
using System.Threading;
66
using System.Threading.Tasks;
77

8-
namespace Parse.Internal {
9-
interface IParseCloudCodeController {
8+
namespace Parse.Core.Internal {
9+
public interface IParseCloudCodeController {
1010
Task<T> CallFunctionAsync<T>(String name,
1111
IDictionary<string, object> parameters,
1212
string sessionToken,

Parse/Internal/Cloud/Controller/ParseCloudCodeController.cs renamed to ParseCore/Internal/Cloud/Controller/ParseCloudCodeController.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
using System.Threading;
66
using System.Threading.Tasks;
77
using Parse.Utilities;
8+
using Parse.Common.Internal;
89

9-
namespace Parse.Internal {
10-
internal class ParseCloudCodeController : IParseCloudCodeController {
10+
namespace Parse.Core.Internal {
11+
public class ParseCloudCodeController : IParseCloudCodeController {
1112
private readonly IParseCommandRunner commandRunner;
1213

13-
internal ParseCloudCodeController(IParseCommandRunner commandRunner) {
14+
public ParseCloudCodeController(IParseCommandRunner commandRunner) {
1415
this.commandRunner = commandRunner;
1516
}
1617

@@ -22,13 +23,13 @@ public Task<T> CallFunctionAsync<T>(String name,
2223
method: "POST",
2324
sessionToken: sessionToken,
2425
data: NoObjectsEncoder.Instance.Encode(parameters) as IDictionary<string, object>);
25-
26+
2627
return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => {
2728
var decoded = ParseDecoder.Instance.Decode(t.Result.Item2) as IDictionary<string, object>;
2829
if (!decoded.ContainsKey("result")) {
2930
return default(T);
3031
}
31-
return (T)Conversion.ConvertTo<T>(decoded["result"]);
32+
return Conversion.To<T>(decoded["result"]);
3233
});
3334
}
3435
}

Parse/Internal/Command/IParseCommandRunner.cs renamed to ParseCore/Internal/Command/IParseCommandRunner.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
using System.Threading;
77
using System.Threading.Tasks;
88

9-
namespace Parse.Internal {
10-
internal interface IParseCommandRunner {
9+
namespace Parse.Core.Internal {
10+
public interface IParseCommandRunner {
1111
/// <summary>
1212
/// Executes <see cref="ParseCommand"/> and convert the result into Dictionary.
1313
/// </summary>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright (c) 2015-present, Parse, LLC. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory.
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Text;
7+
using Parse.Common.Internal;
8+
using System.Linq;
9+
10+
namespace Parse.Core.Internal {
11+
/// <summary>
12+
/// ParseCommand is an <see cref="HttpRequest"/> with pre-populated
13+
/// headers.
14+
/// </summary>
15+
public class ParseCommand : HttpRequest {
16+
public IDictionary<string, object> DataObject { get; private set; }
17+
public override Stream Data {
18+
get {
19+
if (base.Data != null) {
20+
return base.Data;
21+
}
22+
23+
return base.Data = (DataObject != null
24+
? new MemoryStream(Encoding.UTF8.GetBytes(Json.Encode(DataObject)))
25+
: null);
26+
}
27+
set { base.Data = value; }
28+
}
29+
30+
public ParseCommand(string relativeUri,
31+
string method,
32+
string sessionToken = null,
33+
IList<KeyValuePair<string, string>> headers = null,
34+
IDictionary<string, object> data = null) : this(relativeUri: relativeUri,
35+
method: method,
36+
sessionToken: sessionToken,
37+
headers: headers,
38+
stream: null,
39+
contentType: data != null ? "application/json" : null) {
40+
DataObject = data;
41+
}
42+
43+
public ParseCommand(string relativeUri,
44+
string method,
45+
string sessionToken = null,
46+
IList<KeyValuePair<string, string>> headers = null,
47+
Stream stream = null,
48+
string contentType = null) {
49+
Uri = new Uri(new Uri(ParseClient.CurrentConfiguration.Server), relativeUri);
50+
Method = method;
51+
Data = stream;
52+
Headers = new List<KeyValuePair<string, string>>(headers ?? Enumerable.Empty<KeyValuePair<string, string>>());
53+
54+
if (!string.IsNullOrEmpty(sessionToken)) {
55+
Headers.Add(new KeyValuePair<string, string>("X-Parse-Session-Token", sessionToken));
56+
}
57+
if (!string.IsNullOrEmpty(contentType)) {
58+
Headers.Add(new KeyValuePair<string, string>("Content-Type", contentType));
59+
}
60+
}
61+
62+
public ParseCommand(ParseCommand other) {
63+
this.Uri = other.Uri;
64+
this.Method = other.Method;
65+
this.DataObject = other.DataObject;
66+
this.Headers = new List<KeyValuePair<string, string>>(other.Headers);
67+
}
68+
}
69+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright (c) 2015-present, Parse, LLC. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory.
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Net;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Parse.Common.Internal;
9+
10+
namespace Parse.Core.Internal {
11+
public class ParseCommandRunner : IParseCommandRunner {
12+
private readonly IHttpClient httpClient;
13+
private readonly IInstallationIdController installationIdController;
14+
15+
public ParseCommandRunner(IHttpClient httpClient, IInstallationIdController installationIdController) {
16+
this.httpClient = httpClient;
17+
this.installationIdController = installationIdController;
18+
}
19+
20+
public Task<Tuple<HttpStatusCode, IDictionary<string, object>>> RunCommandAsync(ParseCommand command,
21+
IProgress<ParseUploadProgressEventArgs> uploadProgress = null,
22+
IProgress<ParseDownloadProgressEventArgs> downloadProgress = null,
23+
CancellationToken cancellationToken = default(CancellationToken)) {
24+
return PrepareCommand(command).ContinueWith(commandTask => {
25+
return httpClient.ExecuteAsync(commandTask.Result, uploadProgress, downloadProgress, cancellationToken).OnSuccess(t => {
26+
cancellationToken.ThrowIfCancellationRequested();
27+
28+
var response = t.Result;
29+
var contentString = response.Item2;
30+
int responseCode = (int)response.Item1;
31+
if (responseCode >= 500) {
32+
// Server error, return InternalServerError.
33+
throw new ParseException(ParseException.ErrorCode.InternalServerError, response.Item2);
34+
} else if (contentString != null) {
35+
IDictionary<string, object> contentJson = null;
36+
try {
37+
if (contentString.StartsWith("[")) {
38+
var arrayJson = Json.Parse(contentString);
39+
contentJson = new Dictionary<string, object> { { "results", arrayJson } };
40+
} else {
41+
contentJson = Json.Parse(contentString) as IDictionary<string, object>;
42+
}
43+
} catch (Exception e) {
44+
throw new ParseException(ParseException.ErrorCode.OtherCause,
45+
"Invalid response from server", e);
46+
}
47+
if (responseCode < 200 || responseCode > 299) {
48+
int code = (int)(contentJson.ContainsKey("code") ? (long)contentJson["code"] : (int)ParseException.ErrorCode.OtherCause);
49+
string error = contentJson.ContainsKey("error") ?
50+
contentJson["error"] as string :
51+
contentString;
52+
throw new ParseException((ParseException.ErrorCode)code, error);
53+
}
54+
return new Tuple<HttpStatusCode, IDictionary<string, object>>(response.Item1,
55+
contentJson);
56+
}
57+
return new Tuple<HttpStatusCode, IDictionary<string, object>>(response.Item1, null);
58+
});
59+
}).Unwrap();
60+
}
61+
62+
private const string revocableSessionTokenTrueValue = "1";
63+
private Task<ParseCommand> PrepareCommand(ParseCommand command) {
64+
ParseCommand newCommand = new ParseCommand(command);
65+
66+
Task<ParseCommand> installationIdTask = installationIdController.GetAsync().ContinueWith(t => {
67+
newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Installation-Id", t.Result.ToString()));
68+
return newCommand;
69+
});
70+
71+
// TODO (richardross): Inject configuration instead of using shared static here.
72+
ParseClient.Configuration configuration = ParseClient.CurrentConfiguration;
73+
newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Application-Id", configuration.ApplicationId));
74+
newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Client-Version", ParseClient.VersionString));
75+
76+
if (configuration.AdditionalHTTPHeaders != null) {
77+
foreach (var header in configuration.AdditionalHTTPHeaders) {
78+
newCommand.Headers.Add(header);
79+
}
80+
}
81+
82+
if (!string.IsNullOrEmpty(configuration.VersionInfo.BuildVersion)) {
83+
newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-App-Build-Version", configuration.VersionInfo.BuildVersion));
84+
}
85+
if (!string.IsNullOrEmpty(configuration.VersionInfo.DisplayVersion)) {
86+
newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-App-Display-Version", configuration.VersionInfo.DisplayVersion));
87+
}
88+
if (!string.IsNullOrEmpty(configuration.VersionInfo.OSVersion)) {
89+
newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-OS-Version", configuration.VersionInfo.OSVersion));
90+
}
91+
92+
// TODO (richardross): I hate the idea of having this super tightly coupled static variable in here.
93+
// Lets eventually get rid of it.
94+
if (!string.IsNullOrEmpty(ParseClient.MasterKey)) {
95+
newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Master-Key", ParseClient.MasterKey));
96+
} else {
97+
newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Windows-Key", configuration.WindowsKey));
98+
}
99+
100+
// TODO (richardross): Inject this instead of using static here.
101+
if (ParseUser.IsRevocableSessionEnabled) {
102+
newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Revocable-Session", revocableSessionTokenTrueValue));
103+
}
104+
105+
return installationIdTask;
106+
}
107+
}
108+
}

Parse/Internal/Config/Controller/IParseConfigController.cs renamed to ParseCore/Internal/Config/Controller/IParseConfigController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
using System.Threading.Tasks;
55
using System.Threading;
66

7-
namespace Parse.Internal {
8-
interface IParseConfigController {
7+
namespace Parse.Core.Internal {
8+
public interface IParseConfigController {
99
/// <summary>
1010
/// Gets the current config controller.
1111
/// </summary>

Parse/Internal/Config/Controller/IParseCurrentConfigController.cs renamed to ParseCore/Internal/Config/Controller/IParseCurrentConfigController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
using System;
44
using System.Threading.Tasks;
55

6-
namespace Parse.Internal {
7-
interface IParseCurrentConfigController {
6+
namespace Parse.Core.Internal {
7+
public interface IParseCurrentConfigController {
88
/// <summary>
99
/// Gets the current config async.
1010
/// </summary>

Parse/Internal/Config/Controller/ParseConfigController.cs renamed to ParseCore/Internal/Config/Controller/ParseConfigController.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,24 @@
33
using System;
44
using System.Threading.Tasks;
55
using System.Threading;
6+
using Parse.Common.Internal;
67

7-
namespace Parse.Internal {
8+
namespace Parse.Core.Internal {
89
/// <summary>
910
/// Config controller.
1011
/// </summary>
1112
internal class ParseConfigController : IParseConfigController {
13+
private readonly IParseCommandRunner commandRunner;
14+
1215
/// <summary>
1316
/// Initializes a new instance of the <see cref="ParseConfigController"/> class.
1417
/// </summary>
15-
public ParseConfigController() {
16-
CurrentConfigController = new ParseCurrentConfigController();
18+
public ParseConfigController(IParseCommandRunner commandRunner, IStorageController storageController) {
19+
this.commandRunner = commandRunner;
20+
CurrentConfigController = new ParseCurrentConfigController(storageController);
1721
}
1822

23+
public IParseCommandRunner CommandRunner { get; internal set; }
1924
public IParseCurrentConfigController CurrentConfigController { get; internal set; }
2025

2126
public Task<ParseConfig> FetchConfigAsync(String sessionToken, CancellationToken cancellationToken) {
@@ -24,7 +29,7 @@ public Task<ParseConfig> FetchConfigAsync(String sessionToken, CancellationToken
2429
sessionToken: sessionToken,
2530
data: null);
2631

27-
return ParseClient.ParseCommandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(task => {
32+
return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(task => {
2833
cancellationToken.ThrowIfCancellationRequested();
2934
return new ParseConfig(task.Result.Item2);
3035
}).OnSuccess(task => {

0 commit comments

Comments
 (0)