diff --git a/README.md b/README.md index 40bac578..1fa2a6d8 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,11 @@ git clone git@github.com:ModelSolv/SwagEdit.git Open Eclipse and select `File > Import... > Maven > Existing Maven Project` and select the folder SwagEdit. This will put the project SwagEdit into your current workspace. -# Install RepreZen -## From http://products.modelsolv.com/swagedit/kepler/ +## Use a published update site You can now install SwagEdit into your Eclipse by clicking on `Help > Install New Software... > Add...` -This will show a dialog box from where you can select the location of the update site. Use "http://products.modelsolv.com/swagedit/kepler/" as URL. +This will show a dialog box from where you can select the location of the update site. Use "http://products.modelsolv.com/swagedit/kepler/" as URL. -## Build a local update site +## Build a local update site from sources From inside your SwagEdit folder, run the following command: diff --git a/com.reprezen.swagedit/src/com/reprezen/swagedit/json/schema.json b/com.reprezen.swagedit/src/com/reprezen/swagedit/json/schema.json index 1301acd7..3d9be8ea 100644 --- a/com.reprezen.swagedit/src/com/reprezen/swagedit/json/schema.json +++ b/com.reprezen.swagedit/src/com/reprezen/swagedit/json/schema.json @@ -991,6 +991,7 @@ "$ref": "#/definitions/schema" }, { + "title": "boolean", "type": "boolean" } ], @@ -1005,6 +1006,7 @@ "$ref": "#/definitions/schema" }, { + "title": "schema array", "type": "array", "minItems": 1, "items": { @@ -1587,9 +1589,11 @@ "format": { "anyOf": [ { + "title": "user-defined format", "type": "string" }, { + "title": "pre-defined format", "type": "string", "enum": [ "int32", diff --git a/com.reprezen.swagedit/src/com/reprezen/swagedit/validation/SwaggerError.java b/com.reprezen.swagedit/src/com/reprezen/swagedit/validation/SwaggerError.java index 17f545b6..c0afe295 100644 --- a/com.reprezen.swagedit/src/com/reprezen/swagedit/validation/SwaggerError.java +++ b/com.reprezen.swagedit/src/com/reprezen/swagedit/validation/SwaggerError.java @@ -10,15 +10,22 @@ *******************************************************************************/ package com.reprezen.swagedit.validation; +import java.util.Arrays; +import java.util.Comparator; import java.util.HashMap; +import java.util.LinkedList; import java.util.Map; import java.util.Set; +import java.util.TreeSet; import org.eclipse.core.resources.IMarker; import org.yaml.snakeyaml.error.MarkedYAMLException; import org.yaml.snakeyaml.error.YAMLException; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.base.Strings; +import com.google.common.collect.Lists; +import com.reprezen.swagedit.json.JsonSchemaManager; public class SwaggerError { @@ -31,6 +38,7 @@ public class SwaggerError { public int level; public int line; public int indent = 0; + private static final JsonNode swaggerSchema = new JsonSchemaManager().getSwaggerSchema().asJson();; public SwaggerError(int line, int level, String message) { this.line = line; @@ -75,7 +83,7 @@ String getMessage(boolean withIndent) { return builder.toString(); } - + return message; } @@ -102,6 +110,17 @@ String getMessage(boolean withIndent) { @Override public String getMessage() { + Set orderedErrorLocations = new TreeSet<>(new Comparator() { + @Override + public int compare(String o1, String o2) { + if (errors.get(o1).size() != errors.get(o2).size()) { + return errors.get(o1).size() - errors.get(o2).size(); + } + return o1.compareTo(o2); + } + }); + orderedErrorLocations.addAll(errors.keySet()); + final StringBuilder builder = new StringBuilder(); final String tabs = Strings.repeat("\t", indent); @@ -109,20 +128,62 @@ public String getMessage() { builder.append("Failed to match exactly one schema:"); builder.append("\n"); - for (String key: errors.keySet()) { + for (String location : orderedErrorLocations) { builder.append(tabs); builder.append(" - "); - builder.append(key); + builder.append(getHumanFriendlyText(location)); builder.append(":"); builder.append("\n"); - for (SwaggerError e: errors.get(key)) { + for (SwaggerError e : errors.get(location)) { builder.append(e.getMessage(true)); } } return builder.toString(); } + + protected String getHumanFriendlyText(String location) { + JsonNode swaggerSchemaNode = findNode(location); + if (swaggerSchemaNode == null) { + return location; + } + JsonNode title = swaggerSchemaNode.get("title"); + if (title != null) { + return title.asText(); + } + // "$ref":"#/definitions/headerParameterSubSchema" + JsonNode ref = swaggerSchemaNode.get("$ref"); + if (ref != null) { + return ref.asText().substring(ref.asText().lastIndexOf("/") + 1); + } + return location; + } + + protected JsonNode findNode(String path) { + JsonNode result = findNode(Lists.newLinkedList(Arrays.asList(path.split("/"))), swaggerSchema); + return result; + } + + protected JsonNode findNode(LinkedList path, JsonNode root) { + // retrieves the first element, and also *removes* it + String firstSegment = path.pop(); + if (Strings.isNullOrEmpty(firstSegment)) { + return findNode(path, root); + } + int firstSegmentAsNumber = -1; + try { + firstSegmentAsNumber = Integer.parseInt(firstSegment); + } catch (NumberFormatException e) { + // ignore + } + JsonNode nodeForSegment = firstSegmentAsNumber == -1 ? root.get(firstSegment) + : root.get(firstSegmentAsNumber); + if (path.isEmpty()) { + return nodeForSegment; + } + return findNode(path, nodeForSegment); + } } }