diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java index ef04fd83..018cb0f1 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java @@ -16,7 +16,6 @@ package org.springframework.restdocs.curl; -import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashMap; @@ -59,7 +58,7 @@ public class CurlRequestSnippet extends TemplatedSnippet { } @Override - protected Map createModel(Operation operation) throws IOException { + protected Map createModel(Operation operation) { Map model = new HashMap(); model.put("url", getUrl(operation)); model.put("options", getOptions(operation)); @@ -70,7 +69,7 @@ public class CurlRequestSnippet extends TemplatedSnippet { return String.format("'%s'", operation.getRequest().getUri()); } - private String getOptions(Operation operation) throws IOException { + private String getOptions(Operation operation) { StringWriter command = new StringWriter(); PrintWriter printer = new PrintWriter(command); writeOptionToIncludeHeadersInOutput(printer); @@ -101,8 +100,7 @@ public class CurlRequestSnippet extends TemplatedSnippet { } } - private void writePartsIfNecessary(OperationRequest request, PrintWriter writer) - throws IOException { + private void writePartsIfNecessary(OperationRequest request, PrintWriter writer) { for (OperationRequestPart part : request.getParts()) { writer.printf(" -F '%s=", part.getName()); if (!StringUtils.hasText(part.getSubmittedFileName())) { @@ -120,8 +118,7 @@ public class CurlRequestSnippet extends TemplatedSnippet { } } - private void writeContent(OperationRequest request, PrintWriter writer) - throws IOException { + private void writeContent(OperationRequest request, PrintWriter writer) { if (request.getContent().length > 0) { writer.print(String.format(" -d '%s'", new String(request.getContent()))); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java index b98e33c8..322474d6 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpRequestSnippet.java @@ -16,7 +16,6 @@ package org.springframework.restdocs.http; -import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; @@ -64,7 +63,7 @@ public class HttpRequestSnippet extends TemplatedSnippet { } @Override - protected Map createModel(Operation operation) throws IOException { + protected Map createModel(Operation operation) { Map model = new HashMap(); model.put("method", operation.getRequest().getMethod()); model.put( @@ -104,7 +103,7 @@ public class HttpRequestSnippet extends TemplatedSnippet { return headers; } - private String getRequestBody(OperationRequest request) throws IOException { + private String getRequestBody(OperationRequest request) { StringWriter httpRequest = new StringWriter(); PrintWriter writer = new PrintWriter(httpRequest); if (request.getContent().length > 0) { @@ -131,8 +130,7 @@ public class HttpRequestSnippet extends TemplatedSnippet { || HttpMethod.POST.equals(request.getMethod()); } - private void writeParts(OperationRequest request, PrintWriter writer) - throws IOException { + private void writeParts(OperationRequest request, PrintWriter writer) { writer.println(); for (Entry> parameter : request.getParameters().entrySet()) { for (String value : parameter.getValue()) { @@ -153,8 +151,7 @@ public class HttpRequestSnippet extends TemplatedSnippet { writer.printf("--%s%n", MULTIPART_BOUNDARY); } - private void writePart(OperationRequestPart part, PrintWriter writer) - throws IOException { + private void writePart(OperationRequestPart part, PrintWriter writer) { writePart(part.getName(), new String(part.getContent()), part.getHeaders() .getContentType(), writer); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java index 07f9a5b0..b3483a54 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/http/HttpResponseSnippet.java @@ -16,7 +16,6 @@ package org.springframework.restdocs.http; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -56,7 +55,7 @@ public class HttpResponseSnippet extends TemplatedSnippet { } @Override - protected Map createModel(Operation operation) throws IOException { + protected Map createModel(Operation operation) { OperationResponse response = operation.getResponse(); HttpStatus status = response.getStatus(); Map model = new HashMap(); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java index 551d83ab..a182d8df 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java @@ -28,6 +28,7 @@ import java.util.Set; import org.springframework.restdocs.operation.Operation; import org.springframework.restdocs.operation.OperationResponse; +import org.springframework.restdocs.snippet.ModelCreationException; import org.springframework.restdocs.snippet.Snippet; import org.springframework.restdocs.snippet.SnippetException; import org.springframework.restdocs.snippet.TemplatedSnippet; @@ -85,9 +86,14 @@ public class LinksSnippet extends TemplatedSnippet { } @Override - protected Map createModel(Operation operation) throws IOException { + protected Map createModel(Operation operation) { OperationResponse response = operation.getResponse(); - validate(this.linkExtractor.extractLinks(response)); + try { + validate(this.linkExtractor.extractLinks(response)); + } + catch (IOException ex) { + throw new ModelCreationException(ex); + } Map model = new HashMap<>(); model.put("links", createLinksModel()); return model; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java index 802d34c1..33aa114c 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java @@ -24,6 +24,7 @@ import java.util.Map; import org.springframework.http.MediaType; import org.springframework.restdocs.operation.Operation; +import org.springframework.restdocs.snippet.ModelCreationException; import org.springframework.restdocs.snippet.SnippetException; import org.springframework.restdocs.snippet.TemplatedSnippet; import org.springframework.util.Assert; @@ -61,16 +62,8 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { } @Override - protected Map createModel(Operation operation) throws IOException { - MediaType contentType = getContentType(operation); - ContentHandler contentHandler; - if (contentType != null - && MediaType.APPLICATION_XML.isCompatibleWith(contentType)) { - contentHandler = new XmlContentHandler(getContent(operation)); - } - else { - contentHandler = new JsonContentHandler(getContent(operation)); - } + protected Map createModel(Operation operation) { + ContentHandler contentHandler = getContentHandler(operation); validateFieldDocumentation(contentHandler); @@ -89,6 +82,24 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { return model; } + private ContentHandler getContentHandler(Operation operation) { + MediaType contentType = getContentType(operation); + ContentHandler contentHandler; + try { + if (contentType != null + && MediaType.APPLICATION_XML.isCompatibleWith(contentType)) { + contentHandler = new XmlContentHandler(getContent(operation)); + } + else { + contentHandler = new JsonContentHandler(getContent(operation)); + } + } + catch (IOException ex) { + throw new ModelCreationException(ex); + } + return contentHandler; + } + private void validateFieldDocumentation(ContentHandler payloadHandler) { List missingFields = payloadHandler .findMissingFields(this.fieldDescriptors); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java index 0a89f4c2..bafbdd37 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java @@ -16,7 +16,6 @@ package org.springframework.restdocs.request; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -62,7 +61,7 @@ public abstract class AbstractParametersSnippet extends TemplatedSnippet { } @Override - protected Map createModel(Operation operation) throws IOException { + protected Map createModel(Operation operation) { verifyParameterDescriptors(operation); Map model = new HashMap<>(); diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java index 4082d282..b67a9985 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java @@ -16,7 +16,6 @@ package org.springframework.restdocs.request; -import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -64,7 +63,7 @@ public class PathParametersSnippet extends AbstractParametersSnippet { } @Override - protected Map createModel(Operation operation) throws IOException { + protected Map createModel(Operation operation) { Map model = super.createModel(operation); model.put("path", removeQueryStringIfPresent(extractUrlTemplate(operation))); return model; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/ModelCreationException.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/ModelCreationException.java new file mode 100644 index 00000000..db93a778 --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/ModelCreationException.java @@ -0,0 +1,35 @@ +package org.springframework.restdocs.snippet; + +import org.springframework.restdocs.operation.Operation; + +/** + * An exception that can be thrown by a {@link TemplatedSnippet} to indicate that a + * failure has occurred during model creation. + * + * @author Andy Wilkinson + * @see TemplatedSnippet#createModel(Operation) + */ +@SuppressWarnings("serial") +public class ModelCreationException extends RuntimeException { + + /** + * Creates a new {@code ModelCreationException} with the given {@code cause}. + * + * @param cause the cause + */ + public ModelCreationException(Throwable cause) { + super(cause); + } + + /** + * Creates a new {@code ModelCreationException} with the given {@code message} and + * {@code cause}. + * + * @param message the message + * @param cause the cause + */ + public ModelCreationException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java index 87050ce5..1e7dcc1d 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/TemplatedSnippet.java @@ -69,7 +69,16 @@ public abstract class TemplatedSnippet implements Snippet { } } - protected abstract Map createModel(Operation operation) - throws IOException; + /** + * Create the model that should be used during template rendering to document the + * given {@code operation}. Any additional attributes that were supplied when this + * {@code TemplatedSnippet} were created will be automatically added to the model + * prior to rendering. + * + * @param operation The operation + * @return the model + * @throws ModelCreationException if model creation fails + */ + protected abstract Map createModel(Operation operation); } \ No newline at end of file