예제 #1
0
 private static void RemoveReferenceDefinitions(SwaggerObject root)
 {
     // Remove definitions and parameters which has been added into _documentObjectCache
     if (root.Dictionary.ContainsKey(DefinitionsKey))
     {
         root.Dictionary.Remove(DefinitionsKey);
     }
     if (root.Dictionary.ContainsKey(ParametersKey))
     {
         root.Dictionary.Remove(ParametersKey);
     }
 }
예제 #2
0
        private SwaggerObjectBase Build(JToken token)
        {
            var jObject = token as JObject;

            if (jObject != null)
            {
                JToken referenceToken;

                // Only one $ref is allowed inside a swagger JObject
                if (jObject.TryGetValue("$ref", out referenceToken))
                {
                    if (referenceToken.Type != JTokenType.String && referenceToken.Type != JTokenType.Null)
                    {
                        throw new JsonException($"JSON reference $ref property must have a string or null value, instead of {referenceToken.Type}, location: {referenceToken.Path}.");
                    }

                    SwaggerReferenceObject deferredObject = new SwaggerReferenceObject();
                    var formatted = RestApiHelper.FormatReferenceFullPath((string)referenceToken);
                    deferredObject.DeferredReference = formatted.Item1;
                    deferredObject.ReferenceName     = formatted.Item2;

                    // For swagger, other properties are still allowed besides $ref, e.g.
                    // "schema": {
                    //   "$ref": "#/defintions/foo"
                    //   "example": { }
                    // }
                    // Use Token property to keep other properties
                    // These properties cannot be referenced
                    jObject.Remove("$ref");
                    deferredObject.Token = jObject;
                    return(deferredObject);
                }
                else
                {
                    string location = GetLocation(token);

                    SwaggerObject existingObject;
                    if (_documentObjectCache.TryGetValue(location, out existingObject))
                    {
                        return(existingObject);
                    }

                    var swaggerObject = new SwaggerObject {
                        Location = location
                    };

                    foreach (KeyValuePair <string, JToken> property in jObject)
                    {
                        swaggerObject.Dictionary.Add(property.Key, Build(property.Value));
                    }

                    _documentObjectCache.Add(location, swaggerObject);
                    return(swaggerObject);
                }
            }

            var jArray = token as JArray;

            if (jArray != null)
            {
                var swaggerArray = new SwaggerArray();
                foreach (var property in jArray)
                {
                    swaggerArray.Array.Add(Build(property));
                }

                return(swaggerArray);
            }

            return(new SwaggerValue
            {
                Token = token
            });
        }
예제 #3
0
        private SwaggerObjectBase LoadCore(JToken token, string swaggerPath, bool isExample = false)
        {
            // Fetch from cache first
            var location         = JsonLocationHelper.GetLocation(token);
            var jsonLocationInfo = new JsonLocationInfo(swaggerPath, location);

            if (_documentObjectCache.TryGetValue(jsonLocationInfo, out SwaggerObjectBase existingObject))
            {
                return(existingObject);
            }

            if (token is JObject jObject)
            {
                // Only one $ref is allowed inside a swagger JObject
                if (jObject.TryGetValue(ReferenceKey, out JToken referenceToken) && !isExample)
                {
                    if (referenceToken.Type != JTokenType.String && referenceToken.Type != JTokenType.Null)
                    {
                        throw new JsonException($"JSON reference $ref property must have a string or null value, instead of {referenceToken.Type}, location: {referenceToken.Path}.");
                    }

                    var swaggerReference = RestApiHelper.FormatReferenceFullPath((string)referenceToken);
                    switch (swaggerReference.Type)
                    {
                    case SwaggerFormattedReferenceType.InternalReference:
                        var deferredObject = new SwaggerReferenceObject
                        {
                            DeferredReference = swaggerReference.Path,
                            ReferenceName     = swaggerReference.Name,
                            Location          = location
                        };

                        // For swagger, other properties are still allowed besides $ref, e.g.
                        // "schema": {
                        //   "$ref": "#/definitions/foo"
                        //   "example": { }
                        // }
                        // Use Token property to keep other properties
                        // These properties cannot be referenced
                        jObject.Remove("$ref");
                        deferredObject.Token = jObject;
                        _documentObjectCache.Add(jsonLocationInfo, deferredObject);
                        return(deferredObject);

                    case SwaggerFormattedReferenceType.ExternalReference:
                        jObject.Remove("$ref");

                        var externalJObject = LoadExternalReference(Path.Combine(Path.GetDirectoryName(swaggerPath), swaggerReference.ExternalFilePath));
                        RestApiHelper.CheckSpecificKey(externalJObject, ReferenceKey, () =>
                        {
                            throw new DocfxException($"{ReferenceKey} in {swaggerReference.ExternalFilePath} is not supported in external reference currently.");
                        });
                        foreach (var item in externalJObject)
                        {
                            if (jObject.TryGetValue(item.Key, out JToken value))
                            {
                                Logger.LogWarning($"{item.Key} inside {jObject.Path} would be overwritten by the value of same key inside {swaggerReference.ExternalFilePath} with path {externalJObject.Path}.");
                            }
                            jObject[item.Key] = item.Value;
                        }

                        var resolved = new SwaggerValue
                        {
                            Location = location,
                            Token    = jObject
                        };
                        _documentObjectCache.Add(jsonLocationInfo, resolved);
                        return(resolved);

                    case SwaggerFormattedReferenceType.ExternalEmbeddedReference:
                        // Defer resolving external reference to resolve step, to prevent loop reference.
                        var externalDeferredObject = new SwaggerReferenceObject
                        {
                            ExternalFilePath  = Path.Combine(Path.GetDirectoryName(swaggerPath), swaggerReference.ExternalFilePath),
                            DeferredReference = swaggerReference.Path,
                            ReferenceName     = swaggerReference.Name,
                            Location          = location
                        };
                        jObject.Remove("$ref");
                        externalDeferredObject.Token = jObject;
                        _documentObjectCache.Add(jsonLocationInfo, externalDeferredObject);
                        return(externalDeferredObject);

                    default:
                        throw new DocfxException($"{referenceToken} does not support type {swaggerReference.Type}.");
                    }
                }

                var swaggerObject = new SwaggerObject {
                    Location = location
                };
                foreach (KeyValuePair <string, JToken> property in jObject)
                {
                    swaggerObject.Dictionary.Add(property.Key, LoadCore(property.Value, swaggerPath, isExample || IsExampleProperty(property.Key, jObject?.Parent?.Parent?.Path)));
                }

                _documentObjectCache.Add(jsonLocationInfo, swaggerObject);
                return(swaggerObject);
            }

            if (token is JArray jArray)
            {
                var swaggerArray = new SwaggerArray {
                    Location = location
                };
                foreach (var property in jArray)
                {
                    swaggerArray.Array.Add(LoadCore(property, swaggerPath, isExample));
                }

                return(swaggerArray);
            }

            return(new SwaggerValue
            {
                Location = location,
                Token = token
            });
        }
예제 #4
0
        private SwaggerObjectBase Build(JToken token, string swaggerDir)
        {
            // Fetch from cache first
            var location = GetLocation(token);
            SwaggerObjectBase existingObject;

            if (_documentObjectCache.TryGetValue(location, out existingObject))
            {
                return(existingObject);
            }

            var jObject = token as JObject;

            if (jObject != null)
            {
                // Only one $ref is allowed inside a swagger JObject
                JToken referenceToken;
                if (jObject.TryGetValue(ReferenceKey, out referenceToken))
                {
                    if (referenceToken.Type != JTokenType.String && referenceToken.Type != JTokenType.Null)
                    {
                        throw new JsonException($"JSON reference $ref property must have a string or null value, instead of {referenceToken.Type}, location: {referenceToken.Path}.");
                    }

                    var swaggerReference = RestApiHelper.FormatReferenceFullPath((string)referenceToken);
                    switch (swaggerReference.Type)
                    {
                    case SwaggerFormattedReferenceType.InternalReference:
                        var deferredObject = new SwaggerReferenceObject
                        {
                            DeferredReference = swaggerReference.Path,
                            ReferenceName     = swaggerReference.Name,
                            Location          = location
                        };

                        // For swagger, other properties are still allowed besides $ref, e.g.
                        // "schema": {
                        //   "$ref": "#/definitions/foo"
                        //   "example": { }
                        // }
                        // Use Token property to keep other properties
                        // These properties cannot be referenced
                        jObject.Remove("$ref");
                        deferredObject.Token = jObject;
                        _documentObjectCache.Add(location, deferredObject);
                        return(deferredObject);

                    case SwaggerFormattedReferenceType.ExternalReference:
                        jObject.Remove("$ref");

                        var externalJObject = LoadExternalReference(Path.Combine(swaggerDir, swaggerReference.Path));
                        RestApiHelper.CheckSpecificKey(externalJObject, ReferenceKey, () =>
                        {
                            throw new DocfxException($"{ReferenceKey} in {swaggerReference.Path} is not supported in external reference currently.");
                        });
                        foreach (var item in externalJObject)
                        {
                            JToken value;
                            if (jObject.TryGetValue(item.Key, out value))
                            {
                                Logger.LogWarning($"{item.Key} inside {jObject.Path} would be overwritten by the value of same key inside {swaggerReference.Path} with path {externalJObject.Path}.");
                            }
                            jObject[item.Key] = item.Value;
                        }

                        return(new SwaggerValue
                        {
                            Location = location,
                            Token = jObject
                        });

                    default:
                        throw new DocfxException($"{referenceToken} does not support type {swaggerReference.Type}.");
                    }
                }

                var swaggerObject = new SwaggerObject {
                    Location = location
                };
                foreach (KeyValuePair <string, JToken> property in jObject)
                {
                    swaggerObject.Dictionary.Add(property.Key, Build(property.Value, swaggerDir));
                }

                _documentObjectCache.Add(location, swaggerObject);
                return(swaggerObject);
            }

            var jArray = token as JArray;

            if (jArray != null)
            {
                var swaggerArray = new SwaggerArray {
                    Location = location
                };
                foreach (var property in jArray)
                {
                    swaggerArray.Array.Add(Build(property, swaggerDir));
                }

                return(swaggerArray);
            }

            return(new SwaggerValue
            {
                Location = location,
                Token = token
            });
        }