Skip to content
This repository was archived by the owner on Feb 12, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 67 additions & 15 deletions src/main/java/org/raml/parser/visitor/MediaTypeResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,26 +109,78 @@ private boolean isValidMediaType(String value)
public List<ValidationResult> resolve(MappingNode bodyNode)
{
List<ValidationResult> validationResults = new ArrayList<ValidationResult>();
if (mediaType == null)
{
return validationResults;
}
for (NodeTuple tuple : bodyNode.getValue())
{
if (!MEDIA_TYPE_KEYS.contains(((ScalarNode) tuple.getKeyNode()).getValue()))
{
return validationResults;
}

if (mediaType!=null){

NodeTuple mediaTypeNodeTuple = findNodeByKey(bodyNode, mediaType);

//if mediaTypeNode is null create it, but do not add it to the parent node yet
if (mediaTypeNodeTuple == null){
Node keyNode = new ScalarNode(Tag.STR, mediaType, null, null, null);
Node valueNode = new MappingNode(Tag.MAP, new ArrayList<NodeTuple>(), false);
NodeTuple newTuple = new NodeTuple(keyNode, valueNode);
mediaTypeNodeTuple = newTuple;
}

moveOrphanedNodes(mediaTypeNodeTuple, bodyNode);

// in case the mediaTypeNodeTuple was not yet appended to the parent node,
// append it but only if it is not empty
if (!bodyNode.getValue().contains(mediaTypeNodeTuple) &&
!((MappingNode)mediaTypeNodeTuple.getValueNode()).getValue().isEmpty()){
bodyNode.getValue().add(mediaTypeNodeTuple);
}
}
List<NodeTuple> copy = new ArrayList<NodeTuple>(bodyNode.getValue());
Node keyNode = new ScalarNode(Tag.STR, mediaType, null, null, null);
Node valueNode = new MappingNode(Tag.MAP, copy, false);
bodyNode.getValue().clear();
bodyNode.getValue().add(new NodeTuple(keyNode, valueNode));

return validationResults;
}

/**
* It is moving all orphaned schema/example/formParameters nodes from the source node under the
* targetTouple node.
*
* @param targetTouple the target node which should become new parent of orphaned nodes
* @param sourceNode the current parent node of the possibly orphaned nodes
*/
private void moveOrphanedNodes(NodeTuple targetTouple, MappingNode sourceNode) {

List<NodeTuple> tuplesToRemove = new ArrayList<NodeTuple>();

for (NodeTuple sourceTuple : sourceNode.getValue())
{
String mediaTypeKey = ((ScalarNode) sourceTuple.getKeyNode()).getValue();

// if it is an orphaned schema/example/formParameters
if (MEDIA_TYPE_KEYS.contains(mediaTypeKey))
{
// move it to the targetTouple
tuplesToRemove.add(sourceTuple);
MappingNode targetToupleNode = (MappingNode)targetTouple.getValueNode();
NodeTuple existingTuple = findNodeByKey(targetToupleNode, mediaTypeKey);
if (existingTuple!=null){
targetToupleNode.getValue().remove(existingTuple);
}
targetToupleNode.getValue().add(sourceTuple);
}
}

// remove the orphaned schema/example/formParameters that were marked for removal earlier
for (NodeTuple toRemove: tuplesToRemove){
sourceNode.getValue().remove(toRemove);
}
}

private NodeTuple findNodeByKey(MappingNode parentNode, String key) {
for (NodeTuple tuple : parentNode.getValue())
{
if (key.equals(((ScalarNode) tuple.getKeyNode()).getValue())){
return tuple;
}
}
return null;
}

/**
* if no explicit media type is defined in either the request or
* response body, the default one is applied
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.raml.model.ActionType.GET;
Expand All @@ -28,6 +29,7 @@
import org.apache.commons.io.IOUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.internal.matchers.NotNull;
import org.raml.model.ActionType;
import org.raml.model.MimeType;
import org.raml.model.Raml;
Expand Down Expand Up @@ -93,6 +95,42 @@ public void emptyBody()
assertThat(resource.getAction(PUT).getBody().size(), is(1));
assertThat(resource.getAction(PUT).getResponses().get("200").getBody().size(), is(1));
}

@Test
public void mergedWithType()
{
Resource resource = raml.getResource("/mergedWithType");
Map<String, MimeType> getResponseBody = resource.getAction(ActionType.GET).getResponses().get("200").getBody();
assertThat(getResponseBody.size(), is(2));

assertThat(getResponseBody.containsKey("application/json"), is(true));
MimeType applicationJson = getResponseBody.get("application/json");
assertThat(applicationJson.getSchema(), notNullValue());
assertThat(applicationJson.getSchema().contains("merged"), is(true));
assertThat(applicationJson.getExample(), notNullValue());
assertThat(applicationJson.getExample().contains("foo"), is(true));

assertThat(getResponseBody.containsKey("text/html"), is(true));
MimeType textHtml = getResponseBody.get("text/html");
assertThat(textHtml.getSchema(), nullValue());
assertThat(textHtml.getExample(), notNullValue());
assertThat(textHtml.getExample().contains("dummy resource example"), is(true));
}

@Test
public void merged()
{
Resource resource = raml.getResource("/merged");
Map<String, MimeType> getResponseBody = resource.getAction(ActionType.GET).getResponses().get("200").getBody();
assertThat(getResponseBody.size(), is(1));

assertThat(getResponseBody.containsKey("application/json"), is(false));
assertThat(getResponseBody.containsKey("text/html"), is(true));

MimeType textHtml = getResponseBody.get("text/html");
assertThat(textHtml.getSchema().contains("merged"), is(true));
assertThat(textHtml.getExample(), nullValue());
}

@Test
public void noBody()
Expand Down Expand Up @@ -123,4 +161,5 @@ public void emitter()
assertThat(raml2.getResources().get("/simple").getActions().size(),
is(raml1.getResources().get("/simple").getActions().size()));
}

}
51 changes: 51 additions & 0 deletions src/test/resources/org/raml/media-type.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,26 @@ resourceTypes:
type: typeParent
put:
is: [traitOne]
- dummy:
get:
responses:
200:
body:
example: |
{
"id": "foo"
}
application/json:
schema: |
{ "$schema": "http://json-schema.org/draft-03/schema",
"type": "object",
"description": "A dummy schema",
"properties": {
"id": { "type": "string" }
}
}
text/html:
example: dummy resource example

/simple:
type: typeChild
Expand All @@ -57,3 +77,34 @@ resourceTypes:
get:
responses:
200:

/merged:
get:
responses:
200:
body:
text/html:
schema: |
{ "$schema": "http://json-schema.org/draft-03/schema",
"type": "object",
"description": "A merged schema",
"properties": {
"id": { "type": "string" }
}
}

/mergedWithType:
type: dummy
get:
responses:
200:
body:
schema: |
{ "$schema": "http://json-schema.org/draft-03/schema",
"type": "object",
"description": "A merged schema",
"properties": {
"id": { "type": "string" }
}
}