Skip to content

Commit

Permalink
Deserialize using gzip
Browse files Browse the repository at this point in the history
  • Loading branch information
chidozieononiwu committed Jun 13, 2024
1 parent 6cc8658 commit c8648eb
Show file tree
Hide file tree
Showing 12 changed files with 203 additions and 34 deletions.
39 changes: 35 additions & 4 deletions src/dotnet/APIView/APIView/Model/CodeFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace ApiView
Expand All @@ -20,11 +22,16 @@ public class CodeFile
ReadCommentHandling = JsonCommentHandling.Skip
};

private static readonly JsonSerializerOptions _deSerializerOptions = new JsonSerializerOptions
private static readonly JsonSerializerOptions _treeStyleParserDeserializerOptions = new JsonSerializerOptions
{
Converters = { new StructuredTokenConverter() }
};

private static readonly JsonSerializerOptions _treeStyleParserSerializerOptions = new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
};

private string _versionString;

private static HashSet<string> _collapsibleLanguages = new HashSet<string>(new string[] { "Swagger" });
Expand Down Expand Up @@ -73,10 +80,18 @@ public override string ToString()
public static bool IsCollapsibleSectionSSupported(string language) => _collapsibleLanguages.Contains(language);

#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
public static async Task<CodeFile> DeserializeAsync(Stream stream, bool hasSections = false)
public static async Task<CodeFile> DeserializeAsync(Stream stream, bool hasSections = false, bool useTreeStyleParserDeserializerOptions = false)
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
CodeFile codeFile = await JsonSerializer.DeserializeAsync<CodeFile>(stream, _deSerializerOptions);
CodeFile codeFile = null;
if (useTreeStyleParserDeserializerOptions)
{
codeFile = await JsonSerializer.DeserializeAsync<CodeFile>(stream, _treeStyleParserDeserializerOptions);
}
else
{
codeFile = await JsonSerializer.DeserializeAsync<CodeFile>(stream, _serializerOptions);
}

if (hasSections == false && codeFile.LeafSections == null && IsCollapsibleSectionSSupported(codeFile.Language))
hasSections = true;
Expand Down Expand Up @@ -152,7 +167,23 @@ public static async Task<CodeFile> DeserializeAsync(Stream stream, bool hasSecti

public async Task SerializeAsync(Stream stream)
{
await JsonSerializer.SerializeAsync(stream, this, _serializerOptions);
if (this.APIForest.Count > 0)
{
using (var tempStream = new MemoryStream())
{
await JsonSerializer.SerializeAsync(tempStream, this, _treeStyleParserSerializerOptions);
tempStream.Position = 0;

using (var compressionStream = new GZipStream(stream, CompressionMode.Compress, leaveOpen: true))
{
await tempStream.CopyToAsync(compressionStream);
}
}
}
else
{
await JsonSerializer.SerializeAsync(stream, this, _serializerOptions);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,14 @@
--name-color: #{$base-text-color};
--code-color: #d1377e;
--code-comment: green;
--literal-color: #008509;
--enum-color: #8700BD;
--java-doc-color: #8c8c8c;
--java-comment-color: #8c8c8c;
--java-field-name-color: #871094;
--java-method-name-color: #00627A;
--java-keyword-color: #0033B3;
--java-anotation-name-color: 9E880D;
--java-anotation-name-color: #9E880D;
--java-string-literal-color: #067D17;
--java-number-color: #1750EB;
--alert-success-color: #0a3622;
Expand Down
10 changes: 9 additions & 1 deletion src/dotnet/APIView/APIViewWeb/Languages/JsonLanguageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using ApiView;

Expand All @@ -11,7 +12,7 @@ namespace APIViewWeb
public class JsonLanguageService : LanguageService
{
public override string Name { get; } = "Json";
public override string[] Extensions { get; } = { ".json" };
public override string[] Extensions { get; } = { ".json", ".json.tgz" };

public override bool CanUpdate(string versionString) => false;

Expand All @@ -23,6 +24,13 @@ public override bool IsSupportedFile(string name)

public override async Task<CodeFile> GetCodeFileAsync(string originalName, Stream stream, bool runAnalysis)
{
if (originalName.EndsWith(".tgz", StringComparison.OrdinalIgnoreCase))
{
using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true))
{
return await CodeFile.DeserializeAsync(gzipStream, useTreeStyleParserDeserializerOptions: true);
}
}
return await CodeFile.DeserializeAsync(stream, true);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public async Task<ActionResult<PagedList<APIRevisionListItemModel>>> GetAPIRevis
/// </summary>
/// <param name="deleteParams"></param>
/// <returns></returns>
[HttpPut("/delete", Name = "DeleteAPIRevisions")]
[HttpPut("delete", Name = "DeleteAPIRevisions")]
public async Task DeleteAPIRevisionsAsync([FromBody] APIRevisionSoftDeleteParam deleteParams)
{
foreach (var apiRevisionId in deleteParams.apiRevisionIds)
Expand All @@ -55,7 +55,7 @@ public async Task DeleteAPIRevisionsAsync([FromBody] APIRevisionSoftDeleteParam
/// </summary>
/// <param name="deleteParams"></param>
/// <returns></returns>
[HttpPut("/restore", Name = "RestoreAPIRevisions")]
[HttpPut("restore", Name = "RestoreAPIRevisions")]
public async Task RestoreAPIRevisionsAsync([FromBody] APIRevisionSoftDeleteParam deleteParams)
{
foreach (var apiRevisionId in deleteParams.apiRevisionIds)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public CommentsController(ILogger<CommentsController> logger,
/// </summary>
/// <param name="reviewId"></param>
/// <returns></returns>
[HttpGet("/{reviewId}", Name = "GetComments")]
[HttpGet("{reviewId}", Name = "GetComments")]
public async Task<ActionResult<IEnumerable<CommentItemModel>>> GetCommentsAsync(string reviewId)
{
var comments = await _commentsManager.GetCommentsAsync(reviewId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
using Microsoft.AspNetCore.SignalR;
using System.Diagnostics;
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace APIViewWeb.LeanControllers
{
Expand All @@ -27,12 +29,13 @@ public class ReviewsController : BaseApiController
public readonly UserPreferenceCache _preferenceCache;
private readonly ICosmosUserProfileRepository _userProfileRepository;
private readonly IHubContext<SignalRHub> _signalRHubContext;
private readonly IWebHostEnvironment _env;

public ReviewsController(ILogger<ReviewsController> logger,
IAPIRevisionsManager reviewRevisionsManager, IReviewManager reviewManager,
ICommentsManager commentManager, IBlobCodeFileRepository codeFileRepository,
IConfiguration configuration, UserPreferenceCache preferenceCache,
ICosmosUserProfileRepository userProfileRepository, IHubContext<SignalRHub> signalRHub)
ICosmosUserProfileRepository userProfileRepository, IHubContext<SignalRHub> signalRHub, IWebHostEnvironment env)
{
_logger = logger;
_apiRevisionsManager = reviewRevisionsManager;
Expand All @@ -43,6 +46,7 @@ public ReviewsController(ILogger<ReviewsController> logger,
_preferenceCache = preferenceCache;
_userProfileRepository = userProfileRepository;
_signalRHubContext = signalRHub;
_env = env;

}

Expand Down Expand Up @@ -113,7 +117,7 @@ public async Task<ActionResult<CodePanelData>> GetReviewContentAsync(string revi
{
var comments = await _commentsManager.GetCommentsAsync(reviewId);

var activeRevisionReviewCodeFile = await _codeFileRepository.GetCodeFileWithCompressionAsync(activeAPIRevision.Id, activeAPIRevision.Files[0].FileId, false);
var activeRevisionReviewCodeFile = await _codeFileRepository.GetCodeFileWithCompressionAsync(activeAPIRevision.Id, activeAPIRevision.Files[0].FileId, _env.IsProduction());

var result = new CodePanelData();

Expand All @@ -127,7 +131,7 @@ public async Task<ActionResult<CodePanelData>> GetReviewContentAsync(string revi
if (!string.IsNullOrEmpty(diffApiRevisionId))
{
var diffAPIRevision = await _apiRevisionsManager.GetAPIRevisionAsync(User, diffApiRevisionId);
var diffRevisionReviewCodeFile = await _codeFileRepository.GetCodeFileWithCompressionAsync(diffAPIRevision.Id, diffAPIRevision.Files[0].FileId);
var diffRevisionReviewCodeFile = await _codeFileRepository.GetCodeFileWithCompressionAsync(diffAPIRevision.Id, diffAPIRevision.Files[0].FileId, _env.IsProduction());
codePanelRawData.APIForest = CodeFileHelpers.ComputeAPIForestDiff(activeRevisionReviewCodeFile.APIForest, diffRevisionReviewCodeFile.APIForest);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public async Task<CodeFile> GetCodeFileWithCompressionAsync(string revisionId, s
}
var info = await client.DownloadAsync();
using var gzipStream = new GZipStream(info.Value.Content, CompressionMode.Decompress);
codeFile = await CodeFile.DeserializeAsync(gzipStream);
codeFile = await CodeFile.DeserializeAsync(gzipStream, useTreeStyleParserDeserializerOptions: true);
if (updateCache)
{
using var _ = _cache.CreateEntry(key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,15 @@ export class ApiRevisionOptionsComponent implements OnChanges {
let apiRevision = mappedApiRevisions.shift();

if (latestGAApiRevision === null) {
let versionParts = apiRevision.version.match(semVarRegex);
if (versionParts.groups?.prelabel === undefined && versionParts.groups?.prenumber === undefined &&
versionParts.groups?.prenumsep === undefined && versionParts.groups?.presep === undefined) {
apiRevision.isLatestGA = true;
latestGAApiRevision = apiRevision;
continue;
if (apiRevision.version) {
let versionParts = apiRevision.version.match(semVarRegex);

if (versionParts.groups?.prelabel === undefined && versionParts.groups?.prenumber === undefined &&
versionParts.groups?.prenumsep === undefined && versionParts.groups?.presep === undefined) {
apiRevision.isLatestGA = true;
latestGAApiRevision = apiRevision;
continue;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
.code-line-content {
grid-column: 2;
position: relative;
white-space: pre;
}

.line-number {
Expand Down Expand Up @@ -164,20 +165,31 @@
}
}

.csharp {
.comment {
color: var(--code-comment);
}

.keyword {
color: var(--keyword-color);
}

.tname {
color: var(--class-color);
}
.comment {
color: var(--code-comment);
}

.keyword {
color: var(--keyword-color);
}

.tname {
color: var(--class-color);
}

.mname {
color: var(--name-color);
}

.enum {
color: var(--enum-color);
}

.literal .sliteral {
color: var(--literal-color);
}


.java {
.javadoc {
color: var(--java-doc-color);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ export class ReviewsListComponent implements OnInit, AfterViewInit {
`Use <code>api-extractor</code> to generate a <a href="https://api-extractor.com/pages/setup/generating_docs/">docModel file</a>`,
`Upload generated api.json file`
];
this.acceptedFilesForReviewUpload = ".json";
this.acceptedFilesForReviewUpload = ".api.json";
this.createReviewForm.get('selectedFile')?.enable();
this.createReviewForm.get('filePath')?.disable();
break;
Expand Down Expand Up @@ -381,7 +381,7 @@ export class ReviewsListComponent implements OnInit, AfterViewInit {
this.createReviewInstruction = [
`Upload JSON API review token file.`
];
this.acceptedFilesForReviewUpload = ".json";
this.acceptedFilesForReviewUpload = ".json, .tgz";
this.createReviewForm.get('selectedFile')?.enable();
this.createReviewForm.get('filePath')?.disable();
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ export class RevisionsListComponent implements OnInit, OnChanges {
this.showDiffButton = (value.length == 2) ? true : false;
let canDelete = (value.length > 0)? true : false;
for (const revision of value) {
if (revision.createdBy != this.userProfile?.userName || revision.apiRevisionType != "Manual")
if (revision.createdBy != this.userProfile?.userName || revision.apiRevisionType != "manual")
{
canDelete = false;
break;
Expand Down
Loading

0 comments on commit c8648eb

Please sign in to comment.