You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2018/04/21 13:46:25 UTC
[juneau] branch master updated: Improvements to Swagger API
This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new e7e7e47 Improvements to Swagger API
e7e7e47 is described below
commit e7e7e475dbab9e053fd55b0a6adbf52fda7399bb
Author: JamesBognar <ja...@apache.org>
AuthorDate: Sat Apr 21 09:45:56 2018 -0400
Improvements to Swagger API
---
.../main/java/org/apache/juneau/config/Config.java | 2 +-
.../org/apache/juneau/utils/StringUtilsTest.java | 24 +-
.../java/org/apache/juneau/dto/html5/Select.java | 19 +
.../org/apache/juneau/dto/swagger/Swagger.java | 15 +-
.../apache/juneau/dto/swagger/ui/SwaggerUI.java | 2 +-
.../src/main/java/org/apache/juneau/BeanMap.java | 2 +-
.../org/apache/juneau/internal/StringUtils.java | 4 +-
.../org/apache/juneau/parser/ParseException.java | 56 +-
.../org/apache/juneau/parser/ParserSession.java | 24 +-
.../juneau/examples/rest/AtomFeedResource.java | 16 +-
.../examples/rest/CodeFormatterResource.java | 16 +-
.../examples/rest/DockerRegistryResource.java | 15 +-
.../juneau/examples/rest/JsonSchemaResource.java | 16 +-
.../examples/rest/MethodExampleResource.java | 16 +-
.../juneau/examples/rest/PhotosResource.java | 16 +-
.../examples/rest/PredefinedLabelsResource.java | 16 +-
.../juneau/examples/rest/RequestEchoResource.java | 16 +-
.../examples/rest/SampleRemoteableServlet.java | 17 +-
.../juneau/examples/rest/SqlQueryResource.java | 26 +-
.../examples/rest/SystemPropertiesResource.java | 36 +-
.../juneau/examples/rest/TempDirResource.java | 16 +-
.../examples/rest/UrlEncodedFormResource.java | 16 +-
.../rest/addressbook/AddressBookResource.java | 16 +-
.../{AddPetMenuItem.java => AddOrderMenuItem.java} | 35 +-
.../examples/rest/petstore/AddPetMenuItem.java | 13 +-
.../juneau/examples/rest/petstore/CreateOrder.java | 19 +-
.../juneau/examples/rest/petstore/Order.java | 14 +-
.../apache/juneau/examples/rest/petstore/Pet.java | 4 +
.../petstore/{CreatePet.java => PetCreate.java} | 23 +-
.../juneau/examples/rest/petstore/PetStore.java | 50 +-
.../examples/rest/petstore/PetStoreResource.java | 309 +++++---
.../petstore/{CreatePet.java => PetUpdate.java} | 23 +-
.../juneau/examples/rest/petstore/Species.java | 5 +
.../apache/juneau/examples/rest/petstore/Tag.java | 12 +
.../juneau/examples/rest/petstore/Orders.json | 6 +-
.../juneau/examples/rest/RootContentTest.java | 2 +-
.../microservice/resources/ConfigResource.java | 70 +-
.../microservice/resources/LogsResource.java | 14 +-
.../org/apache/juneau/rest/test/NlsResource.java | 26 +-
.../apache/juneau/rest/test/JacocoDummyTest.java | 2 +-
.../org/apache/juneau/rest/test/RestUtilsTest.java | 2 +-
.../apache/juneau/rest/BasicRestCallHandler.java | 1 +
.../apache/juneau/rest/BasicRestInfoProvider.java | 342 ++++-----
.../apache/juneau/rest/BasicRestServletGroup.java | 2 +-
.../java/org/apache/juneau/rest/RequestBody.java | 111 +--
.../java/org/apache/juneau/rest/RestContext.java | 2 +-
.../org/apache/juneau/rest/RestContextBuilder.java | 31 +-
.../org/apache/juneau/rest/RestJavaMethod.java | 1 +
.../java/org/apache/juneau/rest/RestRequest.java | 1 +
.../java/org/apache/juneau/rest/RestResponse.java | 1 +
.../java/org/apache/juneau/rest/RestServlet.java | 2 +-
.../juneau/rest/annotation/MethodSwagger.java | 245 +++++++
.../juneau/rest/annotation/ResourceSwagger.java | 356 +++++++++
.../apache/juneau/rest/annotation/RestMethod.java | 3 +-
.../juneau/rest/annotation/RestResource.java | 3 +-
.../juneau/rest/remoteable/RemoteableServlet.java | 14 +-
.../juneau/rest/response/DefaultHandler.java | 1 +
.../rest/util/BoundedServletInputStream.java | 144 ++++
.../rest/{ => util}/FinishablePrintWriter.java | 11 +-
.../{ => util}/FinishableServletOutputStream.java | 9 +-
.../juneau/rest/util/MockHttpServletRequest.java | 799 +++++++++++++++++++++
.../juneau/rest/util/MockHttpServletResponse.java | 240 +++++++
.../apache/juneau/rest/{ => util}/RestUtils.java | 15 +-
63 files changed, 2581 insertions(+), 784 deletions(-)
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
index 4f3704c..9787f6e 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
@@ -1678,7 +1678,7 @@ public final class Config extends Context implements ConfigEventListener, Writab
default: return (T)base64Decode(s);
}
} catch (Exception e) {
- throw new ParseException("Value could not be converted to a byte array.").initCause(e);
+ throw new ParseException(e, "Value could not be converted to a byte array.");
}
}
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
index 44eaa14..5b0934b 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
@@ -668,24 +668,24 @@ public class StringUtilsTest {
public void testParseISO8601Date() throws Exception {
WriterSerializer s = JsonSerializer.create().ssq().pojoSwaps(DateSwap.ISO8601DTPZ.class).timeZone(TimeZone.getTimeZone("GMT")).build();
- assertNull(parseISO8601Date(null));
- assertNull(parseISO8601Date(""));
+ assertNull(parseIsoDate(null));
+ assertNull(parseIsoDate(""));
TestUtils.setTimeZone("GMT");
try {
- assertEquals("'2000-01-01T00:00:00.000Z'", s.serialize(parseISO8601Date("2000")));
- assertEquals("'2000-02-01T00:00:00.000Z'", s.serialize(parseISO8601Date("2000-02")));
- assertEquals("'2000-02-03T00:00:00.000Z'", s.serialize(parseISO8601Date("2000-02-03")));
- assertEquals("'2000-02-03T04:00:00.000Z'", s.serialize(parseISO8601Date("2000-02-03T04")));
- assertEquals("'2000-02-03T04:05:00.000Z'", s.serialize(parseISO8601Date("2000-02-03T04:05")));
- assertEquals("'2000-02-03T04:05:06.000Z'", s.serialize(parseISO8601Date("2000-02-03T04:05:06")));
- assertEquals("'2000-02-03T04:00:00.000Z'", s.serialize(parseISO8601Date("2000-02-03 04")));
- assertEquals("'2000-02-03T04:05:00.000Z'", s.serialize(parseISO8601Date("2000-02-03 04:05")));
- assertEquals("'2000-02-03T04:05:06.000Z'", s.serialize(parseISO8601Date("2000-02-03 04:05:06")));
+ assertEquals("'2000-01-01T00:00:00.000Z'", s.serialize(parseIsoDate("2000")));
+ assertEquals("'2000-02-01T00:00:00.000Z'", s.serialize(parseIsoDate("2000-02")));
+ assertEquals("'2000-02-03T00:00:00.000Z'", s.serialize(parseIsoDate("2000-02-03")));
+ assertEquals("'2000-02-03T04:00:00.000Z'", s.serialize(parseIsoDate("2000-02-03T04")));
+ assertEquals("'2000-02-03T04:05:00.000Z'", s.serialize(parseIsoDate("2000-02-03T04:05")));
+ assertEquals("'2000-02-03T04:05:06.000Z'", s.serialize(parseIsoDate("2000-02-03T04:05:06")));
+ assertEquals("'2000-02-03T04:00:00.000Z'", s.serialize(parseIsoDate("2000-02-03 04")));
+ assertEquals("'2000-02-03T04:05:00.000Z'", s.serialize(parseIsoDate("2000-02-03 04:05")));
+ assertEquals("'2000-02-03T04:05:06.000Z'", s.serialize(parseIsoDate("2000-02-03 04:05:06")));
// ISO8601 doesn't support milliseconds, so it gets trimmed.
- assertEquals("'2000-02-03T04:05:06.000Z'", s.serialize(parseISO8601Date("2000-02-03 04:05:06,789")));
+ assertEquals("'2000-02-03T04:05:06.000Z'", s.serialize(parseIsoDate("2000-02-03 04:05:06,789")));
} finally {
TestUtils.unsetTimeZone();
}
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/html5/Select.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/html5/Select.java
index a4c178a..a8595a4 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/html5/Select.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/html5/Select.java
@@ -13,6 +13,7 @@
package org.apache.juneau.dto.html5;
import org.apache.juneau.annotation.*;
+import org.apache.juneau.internal.*;
/**
* DTO for an HTML <a class="doclink" href="https://www.w3.org/TR/html5/forms.html#the-select-element"><select></a>
@@ -134,6 +135,24 @@ public class Select extends HtmlElementContainer {
return this;
}
+ /**
+ * Convenience method for selecting a child {@link Option} after the options have already been populated.
+ *
+ * @param optionValue The option value.
+ * @return This object (for method chaining).
+ */
+ public Select choose(Object optionValue) {
+ if (optionValue != null) {
+ for (Object o : getChildren()) {
+ if (o instanceof Option) {
+ Option o2 = (Option)o;
+ if (StringUtils.isEquals(optionValue.toString(), o2.getAttr(String.class, "value")))
+ o2.selected(true);
+ }
+ }
+ }
+ return this;
+ }
//--------------------------------------------------------------------------------
// Overridden methods
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java
index 6bf836d..5f2d824 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java
@@ -38,6 +38,13 @@ public class Swagger extends SwaggerElement {
/** Represents a null swagger */
public static final Swagger NULL = new Swagger();
+ private static final Comparator<String> PATH_COMPARATOR = new Comparator<String>() {
+ @Override /* Comparator */
+ public int compare(String o1, String o2) {
+ return o1.replace('{', '@').compareTo(o2.replace('{', '@'));
+ }
+ };
+
private String
swagger = "2.0",
host,
@@ -618,7 +625,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger setPaths(Map<String,OperationMap> value) {
- paths = newSortedMap(value, null);
+ paths = newSortedMap(value, PATH_COMPARATOR);
return this;
}
@@ -637,7 +644,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addPaths(Map<String,OperationMap> values) {
- paths = addToSortedMap(paths, values, null);
+ paths = addToSortedMap(paths, values, PATH_COMPARATOR);
return this;
}
@@ -651,7 +658,7 @@ public class Swagger extends SwaggerElement {
*/
public Swagger path(String path, String methodName, Operation operation) {
if (paths == null)
- paths = new TreeMap<>();
+ paths = new TreeMap<>(PATH_COMPARATOR);
OperationMap p = paths.get(path);
if (p == null) {
p = new OperationMap();
@@ -681,7 +688,7 @@ public class Swagger extends SwaggerElement {
@SuppressWarnings({ "unchecked", "rawtypes" })
public Swagger paths(Object...values) {
if (paths == null)
- paths = new TreeMap<>();
+ paths = new TreeMap<>(PATH_COMPARATOR);
paths = addToMap((Map)paths, values, String.class, Map.class, String.class, Operation.class);
return this;
}
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ui/SwaggerUI.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ui/SwaggerUI.java
index 945e306..6e8f063 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ui/SwaggerUI.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ui/SwaggerUI.java
@@ -201,7 +201,7 @@ public class SwaggerUI extends PojoSwap<Swagger,Div> {
private Div opBlock(Session s, String path, String opName, Operation op) {
String opClass = op.isDeprecated() ? "deprecated" : opName.toLowerCase();
- if (! STANDARD_METHODS.contains(opClass))
+ if (! op.isDeprecated() && ! STANDARD_METHODS.contains(opClass))
opClass = "other";
return div()._class("op-block op-block-closed " + opClass).children(
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
index 810effd..bf89ba0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
@@ -168,7 +168,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
put(e.getKey(), e.getValue());
propertyCache = null;
} catch (IllegalArgumentException e) {
- throw new BeanRuntimeException("IllegalArgumentException occurred on call to class constructor ''{0}'' with argument types ''{1}''", c.getName(), JsonSerializer.DEFAULT_LAX.toString(ClassUtils.getClasses(args)));
+ throw new BeanRuntimeException(e, meta.classMeta.innerClass, "IllegalArgumentException occurred on call to class constructor ''{0}'' with argument types ''{1}''", c.getName(), JsonSerializer.DEFAULT_LAX.toString(ClassUtils.getClasses(args)));
} catch (Exception e) {
throw new BeanRuntimeException(e);
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
index 8805c10..14153b4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -204,7 +204,7 @@ public final class StringUtils {
return new AtomicInteger(Integer.decode(s));
throw new ParseException("Unsupported Number type: {0}", type.getName());
} catch (NumberFormatException e) {
- throw new ParseException("Invalid number: ''{0}'', class=''{1}''", s, type.getSimpleName()).initCause(e);
+ throw new ParseException(e, "Invalid number: ''{0}'', class=''{1}''", s, type.getSimpleName());
}
}
@@ -1140,7 +1140,7 @@ public final class StringUtils {
* @return The parsed date.
* @throws IllegalArgumentException
*/
- public static Date parseISO8601Date(String date) throws IllegalArgumentException {
+ public static Date parseIsoDate(String date) throws IllegalArgumentException {
if (isEmpty(date))
return null;
date = date.trim().replace(' ', 'T'); // Convert to 'standard' ISO8601
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParseException.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParseException.java
index 4acc7bb..56a12cf 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParseException.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParseException.java
@@ -30,6 +30,36 @@ public class ParseException extends FormattedException {
/**
* Constructor.
*
+ * @param message The {@link MessageFormat}-style message.
+ * @param args Optional {@link MessageFormat}-style arguments.
+ */
+ public ParseException(String message, Object...args) {
+ super(message, args);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param causedBy The cause of this exception.
+ * @param message The {@link MessageFormat}-style message.
+ * @param args Optional {@link MessageFormat}-style arguments.
+ */
+ public ParseException(Throwable causedBy, String message, Object...args) {
+ super(causedBy, message, args);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param causedBy The cause of this exception.
+ */
+ public ParseException(Throwable causedBy) {
+ super(causedBy);
+ }
+
+ /**
+ * Constructor.
+ *
* @param session The parser session.
* @param message The exception message containing {@link MessageFormat}-style arguments.
* @param args Optional {@link MessageFormat}-style arguments.
@@ -41,11 +71,13 @@ public class ParseException extends FormattedException {
/**
* Constructor.
*
+ * @param session The parser session.
+ * @param causedBy The cause of this exception.
* @param message The exception message containing {@link MessageFormat}-style arguments.
* @param args Optional {@link MessageFormat}-style arguments.
*/
- public ParseException(String message, Object...args) {
- this(null, message, args);
+ public ParseException(ParserSession session, Throwable causedBy, String message, Object...args) {
+ super(causedBy, getMessage(session, message, args));
}
/**
@@ -58,14 +90,6 @@ public class ParseException extends FormattedException {
super(causedBy, getMessage(session, causedBy.getMessage()));
}
- /**
- * Constructor.
- *
- * @param causedBy The inner exception.
- */
- public ParseException(Exception causedBy) {
- super(causedBy, getMessage(null, causedBy.getMessage()));
- }
private static String getMessage(ParserSession session, String msg, Object... args) {
if (args.length != 0)
@@ -109,16 +133,4 @@ public class ParseException extends FormattedException {
t = (ParseException)t.getCause();
return t;
}
-
- /**
- * Sets the inner cause for this exception.
- *
- * @param cause The inner cause.
- * @return This object (for method chaining).
- */
- @Override /* Throwable */
- public synchronized ParseException initCause(Throwable cause) {
- super.initCause(cause);
- return this;
- }
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
index ff4e2a1..b03477e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -513,11 +513,11 @@ public abstract class ParserSession extends BeanSession {
} catch (StackOverflowError e) {
throw new ParseException(this, "Depth too deep. Stack overflow occurred.");
} catch (IOException e) {
- throw new ParseException(this, "I/O exception occurred. exception={0}, message={1}.",
- e.getClass().getSimpleName(), e.getLocalizedMessage()).initCause(e);
+ throw new ParseException(this, e, "I/O exception occurred. exception={0}, message={1}.",
+ e.getClass().getSimpleName(), e.getLocalizedMessage());
} catch (Exception e) {
- throw new ParseException(this, "Exception occurred. exception={0}, message={1}.",
- e.getClass().getSimpleName(), e.getLocalizedMessage()).initCause(e);
+ throw new ParseException(this, e, "Exception occurred. exception={0}, message={1}.",
+ e.getClass().getSimpleName(), e.getLocalizedMessage());
} finally {
checkForWarnings();
}
@@ -604,11 +604,11 @@ public abstract class ParserSession extends BeanSession {
} catch (StackOverflowError e) {
throw new ParseException(this, "Depth too deep. Stack overflow occurred.");
} catch (IOException e) {
- throw new ParseException(this, "I/O exception occurred. exception={0}, message={1}.",
- e.getClass().getSimpleName(), e.getLocalizedMessage()).initCause(e);
+ throw new ParseException(this, e, "I/O exception occurred. exception={0}, message={1}.",
+ e.getClass().getSimpleName(), e.getLocalizedMessage());
} catch (Exception e) {
- throw new ParseException(this, "Exception occurred. exception={0}, message={1}.",
- e.getClass().getSimpleName(), e.getLocalizedMessage()).initCause(e);
+ throw new ParseException(this, e, "Exception occurred. exception={0}, message={1}.",
+ e.getClass().getSimpleName(), e.getLocalizedMessage());
} finally {
checkForWarnings();
}
@@ -659,11 +659,11 @@ public abstract class ParserSession extends BeanSession {
} catch (StackOverflowError e) {
throw new ParseException(this, "Depth too deep. Stack overflow occurred.");
} catch (IOException e) {
- throw new ParseException(this, "I/O exception occurred. exception={0}, message={1}.",
- e.getClass().getSimpleName(), e.getLocalizedMessage()).initCause(e);
+ throw new ParseException(this, e, "I/O exception occurred. exception={0}, message={1}.",
+ e.getClass().getSimpleName(), e.getLocalizedMessage());
} catch (Exception e) {
- throw new ParseException(this, "Exception occurred. exception={0}, message={1}.",
- e.getClass().getSimpleName(), e.getLocalizedMessage()).initCause(e);
+ throw new ParseException(this, e, "Exception occurred. exception={0}, message={1}.",
+ e.getClass().getSimpleName(), e.getLocalizedMessage());
} finally {
checkForWarnings();
}
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java
index f91c4a3..424991c 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/AtomFeedResource.java
@@ -52,15 +52,13 @@ import org.apache.juneau.rest.widget.*;
@Property(name=BEAN_examples, value="{'org.apache.juneau.dto.atom.Feed': $F{AtomFeedResource_example.json}}")
},
encoders=GzipEncoder.class,
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class AtomFeedResource extends BasicRestServletJena {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java
index cb44fbe..82fe991 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/CodeFormatterResource.java
@@ -42,15 +42,13 @@ import org.apache.juneau.rest.annotation.*;
},
style="aside {display:table-caption;}"
),
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
@SuppressWarnings({"serial"})
public class CodeFormatterResource extends BasicRestServlet {
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
index a8e5461..90f8627 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
@@ -39,15 +39,12 @@ import org.apache.juneau.rest.helper.*;
// Pull in aside contents from file.
aside="$F{resources/DockerRegistryResourceAside.html}"
),
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class DockerRegistryResource extends BasicRestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java
index 07839df..0dc53a2 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/JsonSchemaResource.java
@@ -49,15 +49,13 @@ import org.apache.juneau.rest.widget.*;
"</div>"
}
),
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'}"
+ )
)
public class JsonSchemaResource extends BasicRestServletJena {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
index b9f6e4d..376e924 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/MethodExampleResource.java
@@ -41,15 +41,13 @@ import org.apache.juneau.utils.*;
"</div>"
}
),
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class MethodExampleResource extends BasicRestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
index 6c6bc3e..58b576a 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
@@ -54,15 +54,13 @@ import org.apache.juneau.serializer.*;
// Make the anchor text on URLs be just the path relative to the servlet.
@Property(name=HTML_uriAnchorText, value="SERVLET_RELATIVE")
},
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class PhotosResource extends BasicRestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PredefinedLabelsResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PredefinedLabelsResource.java
index da0befb..630a978 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PredefinedLabelsResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PredefinedLabelsResource.java
@@ -41,15 +41,13 @@ import org.apache.juneau.rest.widget.*;
"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/$R{servletClassSimple}.java"
}
),
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class PredefinedLabelsResource extends BasicRestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
index 800fa13..f94cb96 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
@@ -63,15 +63,13 @@ import org.apache.juneau.transforms.*;
// Add a special filter for Enumerations
EnumerationSwap.class
},
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class RequestEchoResource extends BasicRestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SampleRemoteableServlet.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SampleRemoteableServlet.java
index c32de94..6bcf1ea 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SampleRemoteableServlet.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SampleRemoteableServlet.java
@@ -37,16 +37,13 @@ import org.apache.juneau.rest.remoteable.*;
),
// Allow us to use method=POST from a browser.
allowedMethodParams="*",
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
-
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class SampleRemoteableServlet extends RemoteableServlet {
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
index 78e6e21..8216770 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
@@ -54,15 +54,13 @@ import org.apache.juneau.rest.widget.*;
"</div>"
}
),
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class SqlQueryResource extends BasicRestServlet {
private static final long serialVersionUID = 1L;
@@ -146,11 +144,11 @@ public class SqlQueryResource extends BasicRestServlet {
name=POST,
path="/",
summary="Execute one or more queries",
- swagger= {
- "responses:{",
- "200:{ description:'Query results.\nEach entry in the array is a result of one query.\nEach result can be a result set (for queries) or update count (for updates).', 'x-example':[[{col1:'val1'},{col2:'val2'},{col3:'val3'}],123]}",
- "}",
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200:{ description:'Query results.\nEach entry in the array is a result of one query.\nEach result can be a result set (for queries) or update count (for updates).', 'x-example':[[{col1:'val1'},{col2:'val2'},{col3:'val3'}],123]}"
+ }
+ )
)
public List<Object> doPost(
@Body(description="Query input", example="{sql:'select * from sys.systables',pos:1,limit:100}") PostInput in
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
index 369057b..dc1faf2 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
@@ -81,15 +81,13 @@ import org.apache.juneau.rest.widget.*;
// Support GZIP encoding on Accept-Encoding header.
encoders=GzipEncoder.class,
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class SystemPropertiesResource extends BasicRestServlet {
private static final long serialVersionUID = 1L;
@@ -98,11 +96,11 @@ public class SystemPropertiesResource extends BasicRestServlet {
name=GET, path="/",
summary="Show all system properties",
description="Returns all system properties defined in the JVM.",
- swagger={
- "responses:{",
- "200: {description:'Returns a map of key/value pairs.', x-example:{key1:'val1',key2:'val2'}}",
- "}"
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200: {description:'Returns a map of key/value pairs.', x-example:{key1:'val1',key2:'val2'}}"
+ }
+ )
)
@SuppressWarnings({"rawtypes", "unchecked"})
public Map getSystemProperties(
@@ -118,11 +116,11 @@ public class SystemPropertiesResource extends BasicRestServlet {
name=GET, path="/{propertyName}",
summary="Get system property",
description="Returns the value of the specified system property.",
- swagger={
- "responses:{",
- "200: {description:'The system property value, or null if not found'}",
- "}"
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200: {description:'The system property value, or null if not found'}"
+ }
+ )
)
public String getSystemProperty(
@Path(description="The system property name.", example="PATH") String propertyName
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
index baa58a8..58d28c6 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
@@ -63,15 +63,13 @@ import org.apache.juneau.utils.*;
@Property(name=DIRECTORY_RESOURCE_allowDeletes, value="true"),
@Property(name=DIRECTORY_RESOURCE_allowUploads, value="false")
},
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class TempDirResource extends DirectoryResource {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UrlEncodedFormResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UrlEncodedFormResource.java
index 2da113e..4c7edbc 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UrlEncodedFormResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UrlEncodedFormResource.java
@@ -48,15 +48,13 @@ import org.apache.juneau.transforms.*;
"</div>"
}
),
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class UrlEncodedFormResource extends BasicRestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
index 3370f5c..14f4637 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java
@@ -115,15 +115,13 @@ import org.apache.juneau.utils.*;
encoders=GzipEncoder.class,
// Swagger info.
- swagger={
- "info: {",
- "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
- "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
- "version:'2.0',",
- "termsOfService:'You are on your own.'",
- "},",
- "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
- }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'"
+ )
)
public class AddressBookResource extends BasicRestServletJena {
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddPetMenuItem.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddOrderMenuItem.java
similarity index 75%
copy from juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddPetMenuItem.java
copy to juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddOrderMenuItem.java
index a493027..458c6e3 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddPetMenuItem.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddOrderMenuItem.java
@@ -15,42 +15,49 @@ package org.apache.juneau.examples.rest.petstore;
import static org.apache.juneau.dto.html5.HtmlBuilder.*;
import static org.apache.juneau.http.HttpMethodName.*;
+import java.util.*;
+import java.util.Map;
+
+import org.apache.juneau.dto.html5.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.widget.*;
/**
* Menu item for adding a Pet.
*/
-public class AddPetMenuItem extends MenuItemWidget {
+public class AddOrderMenuItem extends MenuItemWidget {
@Override /* MenuItemWidget */
public String getLabel(RestRequest req) throws Exception {
return "add";
}
+ @SuppressWarnings("unchecked")
@Override /* Widget */
public Object getContent(RestRequest req) throws Exception {
+ Map<Long,String> petNames = (Map<Long,String>)req.getAttribute("availablePets");
+
+ List<Option> options = new ArrayList<>();
+ for (Map.Entry<Long,String> e : petNames.entrySet())
+ options.add(option(e.getKey(), e.getValue()));
+
+
return div(
- form().id("form").action("servlet:/").method(POST).children(
+ form().id("form").action("servlet:/store/order").method(POST).children(
table(
tr(
- th("Name:"),
- td(input().name("name").type("text")),
- td(new Tooltip("(?)", "The name of the pet.", br(), "e.g. 'Fluffy'"))
- ),
- tr(
- th("Species:"),
+ th("Pet:"),
td(
- select().name("kind").children(
- option("CAT"), option("DOG"), option("BIRD"), option("FISH"), option("MOUSE"), option("RABBIT"), option("SNAKE")
+ select().name("petId").children(
+ options.toArray()
)
),
- td(new Tooltip("(?)", "The kind of animal."))
+ td(new Tooltip("(?)", "The pet to purchase."))
),
tr(
- th("Price:"),
- td(input().name("price").type("number").placeholder("1.0").step("0.01").min(1).max(100)),
- td(new Tooltip("(?)", "The price to charge for this pet."))
+ th("Ship date:"),
+ td(input().name("shipDate").type("date")),
+ td(new Tooltip("(?)", "The requested ship date."))
),
tr(
td().colspan(2).style("text-align:right").children(
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddPetMenuItem.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddPetMenuItem.java
index a493027..985c194 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddPetMenuItem.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/AddPetMenuItem.java
@@ -31,7 +31,7 @@ public class AddPetMenuItem extends MenuItemWidget {
@Override /* Widget */
public Object getContent(RestRequest req) throws Exception {
return div(
- form().id("form").action("servlet:/").method(POST).children(
+ form().id("form").action("servlet:/pet").method(POST).children(
table(
tr(
th("Name:"),
@@ -41,18 +41,23 @@ public class AddPetMenuItem extends MenuItemWidget {
tr(
th("Species:"),
td(
- select().name("kind").children(
- option("CAT"), option("DOG"), option("BIRD"), option("FISH"), option("MOUSE"), option("RABBIT"), option("SNAKE")
+ select().name("species").children(
+ option("cat"), option("dog"), option("bird"), option("fish"), option("mouse"), option("rabbit"), option("snake")
)
),
td(new Tooltip("(?)", "The kind of animal."))
),
tr(
th("Price:"),
- td(input().name("price").type("number").placeholder("1.0").step("0.01").min(1).max(100)),
+ td(input().name("price").type("number").placeholder("1.0").step("0.01").min(1).max(100).value(9.99)),
td(new Tooltip("(?)", "The price to charge for this pet."))
),
tr(
+ th("Tags:"),
+ td(input().name("tags").type("text")),
+ td(new Tooltip("(?)", "Arbitrary textual tags (comma-delimited).", br(), "e.g. 'fluffy,friendly'"))
+ ),
+ tr(
td().colspan(2).style("text-align:right").children(
button("reset", "Reset"),
button("button","Cancel").onclick("window.location.href='/'"),
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreateOrder.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreateOrder.java
index 5bc4bca..9f62861 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreateOrder.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreateOrder.java
@@ -12,36 +12,33 @@
// ***************************************************************************************************************************
package org.apache.juneau.examples.rest.petstore;
+import java.util.*;
+
import org.apache.juneau.annotation.*;
+import org.apache.juneau.internal.*;
/**
* Bean for creating {@link Order} objects.
*/
public class CreateOrder {
private final long petId;
- private final int quantity;
- private final String shipDate;
+ private final Date shipDate;
- @BeanConstructor(properties="petId,quantity,shipDate")
- public CreateOrder(long petId, int quantity, String shipDate) {
+ @BeanConstructor(properties="petId,shipDate")
+ public CreateOrder(long petId, Date shipDate) {
this.petId = petId;
- this.quantity = quantity;
this.shipDate = shipDate;
}
public static CreateOrder example() {
- return new CreateOrder(123, 10, "2012-12-21");
+ return new CreateOrder(123, StringUtils.parseIsoDate("2012-12-21"));
}
public long getPetId() {
return petId;
}
- public int getQuantity() {
- return quantity;
- }
-
- public String getShipDate() {
+ public Date getShipDate() {
return shipDate;
}
}
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Order.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Order.java
index 9886fc1..73dc1cf 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Order.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Order.java
@@ -18,11 +18,10 @@ import org.apache.juneau.annotation.*;
import org.apache.juneau.html.annotation.*;
import org.apache.juneau.transforms.*;
-@Bean(fluentSetters=true, properties="id,petId,quantity,shipDate,status")
-@Example("{id:123,petId:456,quantity:100,shipDate:'2012-12-21',status:'APPROVED'}")
+@Bean(fluentSetters=true, properties="id,petId,shipDate,status")
+@Example("{id:123,petId:456,shipDate:'2012-12-21',status:'APPROVED'}")
public class Order {
private long id, petId;
- private int quantity;
private Date shipDate;
private OrderStatus status;
@@ -46,15 +45,6 @@ public class Order {
return this;
}
- public int getQuantity() {
- return quantity;
- }
-
- public Order quantity(int quantity) {
- this.quantity = quantity;
- return this;
- }
-
@Swap(DateSwap.ISO8601D.class)
public Date getShipDate() {
return shipDate;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Pet.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Pet.java
index 240a2a7..7b20f89 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Pet.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Pet.java
@@ -128,4 +128,8 @@ public class Pet {
this.price = price;
return this;
}
+
+ public java.net.URI getEdit() {
+ return java.net.URI.create("servlet:/pet/edit/{id}");
+ }
}
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreatePet.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetCreate.java
similarity index 78%
copy from juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreatePet.java
copy to juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetCreate.java
index 2e91036..3dcaa0b 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreatePet.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetCreate.java
@@ -12,33 +12,28 @@
// ***************************************************************************************************************************
package org.apache.juneau.examples.rest.petstore;
-import java.util.*;
-
import org.apache.juneau.annotation.*;
-import org.apache.juneau.utils.*;
/**
* Bean for creating {@link Pet} objects.
*/
-public class CreatePet {
+public class PetCreate {
private final String name;
private final float price;
private final String species;
- private final List<String> tags;
- private final PetStatus status;
+ private final String[] tags;
- @BeanConstructor(properties="name,price,species,tags,status")
- public CreatePet(String name, float price, String species, List<String> tags, PetStatus status) {
+ @BeanConstructor(properties="name,price,species,tags")
+ public PetCreate(String name, float price, String species, String[] tags) {
this.name = name;
this.price = price;
this.species = species;
this.tags = tags;
- this.status = status;
}
- public static CreatePet example() {
- return new CreatePet("Doggie", 9.99f, "doc", AList.create("friendly","cute"), PetStatus.AVAILABLE);
+ public static PetCreate example() {
+ return new PetCreate("Doggie", 9.99f, "doc", new String[] {"friendly","cute"});
}
public String getName() {
@@ -53,11 +48,7 @@ public class CreatePet {
return species;
}
- public List<String> getTags() {
+ public String[] getTags() {
return tags;
}
-
- public PetStatus getStatus() {
- return status;
- }
}
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStore.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStore.java
index 7c786f2..20866f1 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStore.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStore.java
@@ -17,7 +17,6 @@ import java.util.*;
import java.util.concurrent.*;
import org.apache.juneau.*;
-import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.transform.*;
import org.apache.juneau.utils.*;
@@ -187,29 +186,47 @@ public class PetStore {
return value;
}
- public Pet create(CreatePet c) {
+ public Pet create(PetCreate pc) {
Pet p = new Pet();
- p.name(c.getName());
- p.price(c.getPrice());
- p.species(getSpecies(c.getName()));
- p.tags(getTags(c.getTags()));
- p.status(c.getStatus());
+ p.name(pc.getName());
+ p.price(pc.getPrice());
+ p.species(getSpecies(pc.getSpecies()));
+ p.tags(getTags(pc.getTags()));
+ p.status(PetStatus.AVAILABLE);
return add(p);
}
+ public Pet update(PetUpdate pu) throws IdNotFound {
+ Pet p = petDb.get(pu.getId());
+ if (p == null)
+ throw new IdNotFound(pu.getId(), Pet.class);
+ p.name(pu.getName());
+ p.price(pu.getPrice());
+ p.species(getSpecies(pu.getSpecies()));
+ p.tags(getTags(pu.getTags()));
+ p.status(pu.getStatus());
+ return p;
+ }
+
+ public Pet update(Pet pet) {
+ petDb.put(pet.getId(), pet);
+ return pet;
+ }
+
public Order create(CreateOrder c) {
Order o = new Order();
o.petId(c.getPetId());
- o.quantity(c.getQuantity());
- o.shipDate(StringUtils.parseISO8601Date(c.getShipDate()));
+ o.shipDate(c.getShipDate());
o.status(OrderStatus.PLACED);
return add(o);
}
- private List<Tag> getTags(List<String> tags) {
- List<Tag> l = new ArrayList<>();
- for (String t : tags)
- l.add(getOrCreateTag(t));
+ private Tag[] getTags(String[] tags) {
+ if (tags == null)
+ return null;
+ Tag[] l = new Tag[tags.length];
+ for (int i = 0; i < tags.length; i++)
+ l[i]= getOrCreateTag(tags[i]);
return l;
}
@@ -220,13 +237,6 @@ public class PetStore {
return add(new Tag().name(name));
}
- public Pet update(Pet value) throws IdNotFound {
- Pet old = petDb.replace(value.getId(), value);
- if (old == null)
- throw new IdNotFound(value.getId(), Pet.class);
- return value;
- }
-
public Order update(Order value) throws IdNotFound {
Order old = orderDb.replace(value.getId(), value);
if (old == null)
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java
index dd490d6..1ee8ba3 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java
@@ -12,19 +12,27 @@
// ***************************************************************************************************************************
package org.apache.juneau.examples.rest.petstore;
+import static org.apache.juneau.dto.html5.HtmlBuilder.*;
import static org.apache.juneau.dto.swagger.ui.SwaggerUI.*;
+import static org.apache.juneau.http.HttpMethodName.*;
import static org.apache.juneau.rest.annotation.HookEvent.*;
import static org.apache.juneau.rest.helper.Ok.*;
import java.util.*;
+import java.util.Map;
+import org.apache.juneau.dto.html5.*;
import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
import org.apache.juneau.microservice.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.annotation.Body;
+import org.apache.juneau.rest.annotation.Header;
import org.apache.juneau.rest.exception.*;
import org.apache.juneau.rest.helper.*;
import org.apache.juneau.rest.widget.*;
+import org.apache.juneau.transforms.*;
import org.apache.juneau.rest.converters.*;
/**
@@ -69,7 +77,7 @@ import org.apache.juneau.rest.converters.*;
// Resolve recursive references when showing schema info in the swagger.
@Property(name=SWAGGERUI_resolveRefsMaxDepth, value="99")
},
- swagger="$F{PetStoreResource.json}",
+ swagger=@ResourceSwagger("$F{PetStoreResource.json}"),
staticFiles={"htdocs:htdocs"}
)
public class PetStoreResource extends BasicRestServletJena {
@@ -103,12 +111,12 @@ public class PetStoreResource extends BasicRestServletJena {
name="GET",
path="/pet",
summary="All pets in the store",
- swagger={
- "tags:['pet'],",
- "parameters:[",
- Queryable.SWAGGER_PARAMS,
- "]"
- },
+ swagger=@MethodSwagger(
+ tags="pet",
+ parameters={
+ Queryable.SWAGGER_PARAMS
+ }
+ ),
bpx="Pet: tags",
htmldoc=@HtmlDoc(
widgets={
@@ -132,10 +140,12 @@ public class PetStoreResource extends BasicRestServletJena {
path="/pet/{petId}",
summary="Find pet by ID",
description="Returns a single pet",
- swagger={
- "tags:[ 'pet' ],",
- "security:[ { api_key:[] } ]"
- }
+ swagger=@MethodSwagger(
+ tags="pet",
+ value={
+ "security:[ { api_key:[] } ]"
+ }
+ )
)
public Pet getPet(
@Path(description="ID of pet to return", example="123") long petId
@@ -148,15 +158,18 @@ public class PetStoreResource extends BasicRestServletJena {
name="POST",
path="/pet",
summary="Add a new pet to the store",
- swagger={
- "tags:['pet'],",
- "security:[ { petstore_auth:['write:pets','read:pets'] } ]"
- }
+ swagger=@MethodSwagger(
+ tags="pet",
+ value={
+ "security:[ { petstore_auth:['write:pets','read:pets'] } ]"
+ }
+ )
)
public Ok addPet(
- @Body(description="Pet object that needs to be added to the store") CreatePet pet
+ @Body(description="Pet object that needs to be added to the store") PetCreate pet
) throws IdConflict, NotAcceptable, UnsupportedMediaType {
+ JsonSerializer.DEFAULT_LAX_READABLE.println(pet);
store.create(pet);
return OK;
}
@@ -165,13 +178,15 @@ public class PetStoreResource extends BasicRestServletJena {
name="PUT",
path="/pet/{petId}",
summary="Update an existing pet",
- swagger={
- "tags:['pet'],",
- "security:[ { petstore_auth: ['write:pets','read:pets'] } ]"
- }
+ swagger=@MethodSwagger(
+ tags="pet",
+ value={
+ "security:[ { petstore_auth: ['write:pets','read:pets'] } ]"
+ }
+ )
)
public Ok updatePet(
- @Body(description="Pet object that needs to be added to the store") Pet pet
+ @Body(description="Pet object that needs to be added to the store") PetUpdate pet
) throws IdNotFound, NotAcceptable, UnsupportedMediaType {
store.update(pet);
@@ -180,13 +195,85 @@ public class PetStoreResource extends BasicRestServletJena {
@RestMethod(
name="GET",
+ path="/pet/{petId}/edit",
+ summary="Pet edit page",
+ swagger=@MethodSwagger(
+ tags="pet",
+ value={
+ "security:[ { petstore_auth:['write:pets','read:pets'] } ]"
+ }
+ )
+ )
+ public Div editPetPage(
+ @Path(description="ID of pet to return", example="123") long petId
+ ) throws IdConflict, NotAcceptable, UnsupportedMediaType {
+
+ Pet pet = getPet(petId);
+
+ return div(
+ form().id("form").action("servlet:/pet/" + petId).method(POST).children(
+ table(
+ tr(
+ th("Id:"),
+ td(input().name("id").type("text").value(petId).readonly(true)),
+ td(new Tooltip("(?)", "The name of the pet.", br(), "e.g. 'Fluffy'"))
+ ),
+ tr(
+ th("Name:"),
+ td(input().name("name").type("text").value(pet.getName())),
+ td(new Tooltip("(?)", "The name of the pet.", br(), "e.g. 'Fluffy'"))
+ ),
+ tr(
+ th("Species:"),
+ td(
+ select().name("species").children(
+ option("cat"), option("dog"), option("bird"), option("fish"), option("mouse"), option("rabbit"), option("snake")
+ ).choose(pet.getSpecies())
+ ),
+ td(new Tooltip("(?)", "The kind of animal."))
+ ),
+ tr(
+ th("Price:"),
+ td(input().name("price").type("number").placeholder("1.0").step("0.01").min(1).max(100).value(pet.getPrice())),
+ td(new Tooltip("(?)", "The price to charge for this pet."))
+ ),
+ tr(
+ th("Tags:"),
+ td(input().name("tags").type("text").value(Tag.asString(pet.getTags()))),
+ td(new Tooltip("(?)", "Arbitrary textual tags (comma-delimited).", br(), "e.g. 'fluffy,friendly'"))
+ ),
+ tr(
+ th("Status:"),
+ td(
+ select().name("status").children(
+ option("AVAILABLE"), option("PENDING"), option("SOLD")
+ ).choose(pet.getStatus())
+ ),
+ td(new Tooltip("(?)", "The current status of the animal."))
+ ),
+ tr(
+ td().colspan(2).style("text-align:right").children(
+ button("reset", "Reset"),
+ button("button","Cancel").onclick("window.location.href='/'"),
+ button("submit", "Submit")
+ )
+ )
+ ).style("white-space:nowrap")
+ )
+ );
+ }
+
+ @RestMethod(
+ name="GET",
path="/pet/findByStatus",
summary="Finds Pets by status",
description="Multiple status values can be provided with comma separated strings.",
- swagger={
- "tags:['pet'],",
- "security:[{ petstore_auth:[ 'write:pets','read:pets' ] } ]"
- }
+ swagger=@MethodSwagger(
+ tags="pet",
+ value={
+ "security:[{ petstore_auth:[ 'write:pets','read:pets' ] } ]"
+ }
+ )
)
public Collection<Pet> findPetsByStatus(
@Query(
@@ -206,10 +293,12 @@ public class PetStoreResource extends BasicRestServletJena {
path="/pet/findByTags",
summary="Finds Pets by tags",
description="Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
- swagger={
- "tags:['pet'],",
- "security:[ { petstore_auth:[ 'write:pets','read:pets' ] } ]"
- }
+ swagger=@MethodSwagger(
+ tags="pet",
+ value={
+ "security:[ { petstore_auth:[ 'write:pets','read:pets' ] } ]"
+ }
+ )
)
@Deprecated
public Collection<Pet> findPetsByTags(
@@ -226,35 +315,15 @@ public class PetStoreResource extends BasicRestServletJena {
}
@RestMethod(
- name="POST",
- path="/pet/{petId}",
- summary="Updates a pet in the store with form data",
- swagger={
- "tags:[ 'pet' ],",
- "security:[ { petstore_auth:[ 'write:pets', 'read:pets' ] } ]"
- }
- )
- public Ok updatePetForm(
- @Path(description="ID of pet that needs to be updated", example="123") long petId,
- @FormData(name="name", description="Updated name of the pet", example="'Scruffy'") String name,
- @FormData(name="status", description="Updated status of the pet", example="'AVAILABLE'") PetStatus status
- ) throws IdNotFound, NotAcceptable, UnsupportedMediaType {
-
- Pet pet = store.getPet(petId);
- pet.name(name);
- pet.status(status);
- store.update(pet);
- return OK;
- }
-
- @RestMethod(
name="DELETE",
path="/pet/{petId}",
summary="Deletes a pet",
- swagger={
- "tags:[ 'pet' ],",
- "security:[ { petstore_auth:[ 'write:pets','read:pets' ] } ]"
- }
+ swagger=@MethodSwagger(
+ tags="pet",
+ value={
+ "security:[ { petstore_auth:[ 'write:pets','read:pets' ] } ]"
+ }
+ )
)
public Ok deletePet(
@Header(name="api_key", example="foobar") String apiKey,
@@ -269,10 +338,12 @@ public class PetStoreResource extends BasicRestServletJena {
name="POST",
path="/pet/{petId}/uploadImage",
summary="Uploads an image",
- swagger={
- "tags:[ 'pet' ],",
- "security:[ { petstore_auth:[ 'write:pets','read:pets' ] } ]"
- }
+ swagger=@MethodSwagger(
+ tags="pet",
+ value={
+ "security:[ { petstore_auth:[ 'write:pets','read:pets' ] } ]"
+ }
+ )
)
public Ok uploadImage(
@Path(description="ID of pet to update", example="123") long petId,
@@ -290,7 +361,10 @@ public class PetStoreResource extends BasicRestServletJena {
@RestMethod(
name="GET",
path="/store",
- summary="Navigation page"
+ summary="Store navigation page",
+ swagger=@MethodSwagger(
+ tags="store"
+ )
)
public ResourceDescription[] getTopStorePage() {
return new ResourceDescription[] {
@@ -303,9 +377,20 @@ public class PetStoreResource extends BasicRestServletJena {
name="GET",
path="/store/order",
summary="Petstore orders",
- swagger={
- "tags:['store']"
- }
+ swagger=@MethodSwagger(
+ tags="store"
+ ),
+ htmldoc=@HtmlDoc(
+ widgets={
+ QueryMenuItem.class,
+ AddOrderMenuItem.class
+ },
+ navlinks={
+ "INHERIT", // Inherit links from class.
+ "[2]:$W{QueryMenuItem}", // Insert QUERY link in position 2.
+ "[3]:$W{AddOrderMenuItem}" // Insert ADD link in position 3.
+ }
+ )
)
public Collection<Order> getOrders() throws NotAcceptable {
return store.getOrders();
@@ -316,9 +401,9 @@ public class PetStoreResource extends BasicRestServletJena {
path="/store/order/{orderId}",
summary="Find purchase order by ID",
description="Returns a purchase order by ID.",
- swagger={
- "tags:[ 'store' ]",
- }
+ swagger=@MethodSwagger(
+ tags="store"
+ )
)
public Order getOrder(
@Path(description="ID of order to fetch", maximum="1000", minimum="101", example="123") long orderId
@@ -333,25 +418,33 @@ public class PetStoreResource extends BasicRestServletJena {
name="POST",
path="/store/order",
summary="Place an order for a pet",
- swagger={
- "tags:[ 'store' ]"
+ swagger=@MethodSwagger(
+ tags="store"
+ ),
+ pojoSwaps={
+ DateSwap.ISO8601D.class
}
)
public Order placeOrder(
- @Body(description="Order placed for purchasing the pet", example="{petId:456,quantity:100}") CreateOrder order
+ @FormData(name="petId", description="Pet ID") long petId,
+ @FormData(name="shipDate", description="Ship date") Date shipDate
) throws IdConflict, NotAcceptable, UnsupportedMediaType {
- return store.create(order);
+ CreateOrder co = new CreateOrder(petId, shipDate);
+ return store.create(co);
}
@RestMethod(
name="DELETE",
path="/store/order/{orderId}",
summary="Delete purchase order by ID",
- description="For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors.",
- swagger={
- "tags:[ 'store' ]"
- }
+ description= {
+ "For valid response try integer IDs with positive integer value.",
+ "Negative or non-integer values will generate API errors."
+ },
+ swagger=@MethodSwagger(
+ tags="store"
+ )
)
public Ok deletePurchaseOrder(
@Path(description="ID of the order that needs to be deleted", minimum="1", example="5") long orderId
@@ -368,13 +461,15 @@ public class PetStoreResource extends BasicRestServletJena {
path="/store/inventory",
summary="Returns pet inventories by status",
description="Returns a map of status codes to quantities",
- swagger={
- "tags:[ 'store' ],",
- "responses:{",
+ swagger=@MethodSwagger(
+ tags="store",
+ responses={
"200:{ 'x-example':{AVAILABLE:123} }",
- "},",
- "security:[ { api_key:[] } ]"
- }
+ },
+ value={
+ "security:[ { api_key:[] } ]"
+ }
+ )
)
public Map<PetStatus,Integer> getStoreInventory() throws NotAcceptable {
return store.getInventory();
@@ -389,9 +484,9 @@ public class PetStoreResource extends BasicRestServletJena {
path="/user",
summary="Petstore users",
bpx="User: email,password,phone",
- swagger={
- "tags:['user']"
- }
+ swagger=@MethodSwagger(
+ tags="user"
+ )
)
public Collection<User> getUsers() throws NotAcceptable {
return store.getUsers();
@@ -401,9 +496,9 @@ public class PetStoreResource extends BasicRestServletJena {
name="GET",
path="/user/{username}",
summary="Get user by user name",
- swagger={
- "tags:[ 'user' ]"
- }
+ swagger=@MethodSwagger(
+ tags="user"
+ )
)
public User getUser(
@Path(description="The name that needs to be fetched. Use user1 for testing.") String username
@@ -417,9 +512,9 @@ public class PetStoreResource extends BasicRestServletJena {
path="/user",
summary="Create user",
description="This can only be done by the logged in user.",
- swagger={
- "tags:[ 'user' ]"
- }
+ swagger=@MethodSwagger(
+ tags="user"
+ )
)
public Ok createUser(
@Body(description="Created user object") User user
@@ -433,9 +528,9 @@ public class PetStoreResource extends BasicRestServletJena {
name="POST",
path="/user/createWithArray",
summary="Creates list of users with given input array",
- swagger={
- "tags:[ 'user' ]"
- }
+ swagger=@MethodSwagger(
+ tags="user"
+ )
)
public Ok createUsers(
@Body(description="List of user objects") User[] users
@@ -451,9 +546,9 @@ public class PetStoreResource extends BasicRestServletJena {
path="/user/{username}",
summary="Update user",
description="This can only be done by the logged in user.",
- swagger={
- "tags:[ 'user' ]"
- }
+ swagger=@MethodSwagger(
+ tags="user"
+ )
)
public Ok updateUser(
@Path(description="Name that need to be updated") String username,
@@ -469,9 +564,9 @@ public class PetStoreResource extends BasicRestServletJena {
path="/user/{username}",
summary="Delete user",
description="This can only be done by the logged in user.",
- swagger={
- "tags:[ 'user' ]"
- }
+ swagger=@MethodSwagger(
+ tags="user"
+ )
)
public Ok deleteUser(
@Path(description="The name that needs to be deleted") String username
@@ -485,17 +580,17 @@ public class PetStoreResource extends BasicRestServletJena {
name="GET",
path="/user/login",
summary="Logs user into the system",
- swagger={
- "tags:[ 'user' ],",
- "responses:{",
+ swagger=@MethodSwagger(
+ tags="user",
+ responses={
"200:{",
"headers:{",
"X-Rate-Limit:{ type:'integer', format:'int32', description:'calls per hour allowed by the user', 'x-example':123},",
"X-Expires-After:{ type:'string', format:'date-time', description:'date in UTC when token expires', 'x-example':'2012-10-21'}",
"}",
- "}",
- "}"
- }
+ "}"
+ }
+ )
)
public Ok login(
@Query(name="username", description="The username for login", required="true", example="myuser") String username,
@@ -518,9 +613,9 @@ public class PetStoreResource extends BasicRestServletJena {
name="GET",
path="/user/logout",
summary="Logs out current logged in user session",
- swagger={
- "tags:[ 'user' ]"
- }
+ swagger=@MethodSwagger(
+ tags="user"
+ )
)
public Ok logout(RestRequest req) throws NotAcceptable {
req.getSession().removeAttribute("login-expires");
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreatePet.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetUpdate.java
similarity index 81%
rename from juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreatePet.java
rename to juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetUpdate.java
index 2e91036..c210fe9 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/CreatePet.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetUpdate.java
@@ -12,24 +12,23 @@
// ***************************************************************************************************************************
package org.apache.juneau.examples.rest.petstore;
-import java.util.*;
-
import org.apache.juneau.annotation.*;
-import org.apache.juneau.utils.*;
/**
* Bean for creating {@link Pet} objects.
*/
-public class CreatePet {
+public class PetUpdate {
+ private final long id;
private final String name;
private final float price;
private final String species;
- private final List<String> tags;
+ private final String[] tags;
private final PetStatus status;
- @BeanConstructor(properties="name,price,species,tags,status")
- public CreatePet(String name, float price, String species, List<String> tags, PetStatus status) {
+ @BeanConstructor(properties="id,name,price,species,tags,status")
+ public PetUpdate(long id, String name, float price, String species, String[] tags, PetStatus status) {
+ this.id = id;
this.name = name;
this.price = price;
this.species = species;
@@ -37,8 +36,12 @@ public class CreatePet {
this.status = status;
}
- public static CreatePet example() {
- return new CreatePet("Doggie", 9.99f, "doc", AList.create("friendly","cute"), PetStatus.AVAILABLE);
+ public static PetUpdate example() {
+ return new PetUpdate(123l, "Doggie", 9.99f, "doc", new String[] {"friendly","cute"}, PetStatus.AVAILABLE);
+ }
+
+ public long getId() {
+ return id;
}
public String getName() {
@@ -53,7 +56,7 @@ public class CreatePet {
return species;
}
- public List<String> getTags() {
+ public String[] getTags() {
return tags;
}
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Species.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Species.java
index 09b5a4c..9fb4331 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Species.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Species.java
@@ -59,4 +59,9 @@ public class Species {
return "background-color:#FDF2E9";
}
}
+
+ @Override /* Object */
+ public String toString() {
+ return name;
+ }
}
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Tag.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Tag.java
index 649c38c..afd8c27 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Tag.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/Tag.java
@@ -12,9 +12,12 @@
// ***************************************************************************************************************************
package org.apache.juneau.examples.rest.petstore;
+import java.util.*;
+
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.http.*;
+import org.apache.juneau.internal.*;
import org.apache.juneau.transform.*;
@Bean(typeName="Tag", fluentSetters=true)
@@ -58,4 +61,13 @@ public class Tag {
return new MediaType[] { MediaType.HTML };
}
}
+
+ public static String asString(List<Tag> tags) {
+ if (tags == null)
+ return "";
+ List<String> l = new ArrayList<>(tags.size());
+ for (Tag t : tags)
+ l.add(t.getName());
+ return StringUtils.join(l, ',');
+ }
}
diff --git a/juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/Orders.json b/juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/Orders.json
index 15e5ab0..b306aa8 100644
--- a/juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/Orders.json
+++ b/juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/Orders.json
@@ -12,7 +12,7 @@
// ***************************************************************************************************************************
[
- {id:101,petId:101,quantity:1,shipDate:'2018-01-01',status:'PLACED'},
- {id:102,petId:102,quantity:5,shipDate:'2018-01-01',status:'APPROVED'},
- {id:103,petId:103,quantity:10,shipDate:'2018-01-01',status:'DELIVERED'}
+ {id:101,petId:101,shipDate:'2018-01-01',status:'PLACED'},
+ {id:102,petId:102,shipDate:'2018-01-01',status:'APPROVED'},
+ {id:103,petId:103,shipDate:'2018-01-01',status:'DELIVERED'}
]
diff --git a/juneau-examples/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java b/juneau-examples/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
index 85097bf..1b0dedf 100644
--- a/juneau-examples/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
+++ b/juneau-examples/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
@@ -39,7 +39,7 @@ public class RootContentTest extends ContentComboTestBase {
new ComboInput("HTML-header", "/", MediaType.HTML,
"<head>",
"<h1>Root resources</h1>",
- "<h2>Example of a router resource page.</h2>",
+ "<h2>Navigation page</h2>",
"<img src='/htdocs/images/juneau.png' style='position:absolute;top:5;right:5;background-color:transparent;height:30px'/>"
)
},
diff --git a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
index 27863c1..5203a2b 100755
--- a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
+++ b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
@@ -50,11 +50,11 @@ public class ConfigResource extends BasicRestServlet {
path="/",
summary="Get config file contents",
description="Show contents of config file as an ObjectMap.",
- swagger={
- "responses:{",
- "200:{ description:'Config file as a map of map of objects.', 'x-example':{'':{defaultKey:'defaultValue'},'Section1':{key1:'val1',key2:123}}}",
- "}",
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200:{ description:'Config file as a map of map of objects.', 'x-example':{'':{defaultKey:'defaultValue'},'Section1':{key1:'val1',key2:123}}}"
+ }
+ )
)
public ObjectMap getConfig() {
return getServletConfig().getConfig().asMap();
@@ -86,11 +86,11 @@ public class ConfigResource extends BasicRestServlet {
path="/{section}",
summary="Get config file section contents",
description="Show contents of config file section as an ObjectMap.",
- swagger={
- "responses:{",
- "200:{ description:'Config file section as a map of objects.', 'x-example':{key1:'val1',key2:123}}",
- "}",
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200:{ description:'Config file section as a map of objects.', 'x-example':{key1:'val1',key2:123}}"
+ }
+ )
)
public ObjectMap getConfigSection(
@Path(name="section", description="Section name in config file.", example="REST") String section
@@ -104,11 +104,11 @@ public class ConfigResource extends BasicRestServlet {
path="/{section}/{key}",
summary="Get config file entry value",
description="Show value of config file entry as a simple string.",
- swagger={
- "responses:{",
- "200:{ description:'Entry value.', 'x-example':'servlet:/htdocs/themes/dark.css'}",
- "}",
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200:{ description:'Entry value.', 'x-example':'servlet:/htdocs/themes/dark.css'}"
+ }
+ )
)
public String getConfigEntry(
@Path(name="section", description="Section name in config file.", example="REST") String section,
@@ -123,11 +123,11 @@ public class ConfigResource extends BasicRestServlet {
path="/",
summary="Update config file contents",
description="Update the contents of the config file from a FORM post.",
- swagger={
- "responses:{",
- "200:{ description:'Config file section as a map of objects.', 'x-example':{key1:'val1',key2:123}}",
- "}",
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200:{ description:'Config file section as a map of objects.', 'x-example':{key1:'val1',key2:123}}"
+ }
+ )
)
public ObjectMap setConfigContentsFormPost(
@FormData(name="contents", description="New contents in INI file format.") String contents
@@ -141,11 +141,11 @@ public class ConfigResource extends BasicRestServlet {
path="/",
summary="Update config file contents",
description="Update the contents of the config file from raw text.",
- swagger={
- "responses:{",
- "200:{ description:'Config file section as a map of objects.', 'x-example':{key1:'val1',key2:123}}",
- "}",
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200:{ description:'Config file section as a map of objects.', 'x-example':{key1:'val1',key2:123}}"
+ }
+ )
)
public ObjectMap setConfigContents(
@Body(description="New contents in INI file format.") Reader contents
@@ -159,11 +159,11 @@ public class ConfigResource extends BasicRestServlet {
path="/{section}",
summary="Update config section contents",
description="Add or overwrite a config file section.",
- swagger={
- "responses:{",
- "200:{ description:'Config file section as a map of objects.', 'x-example':{key1:'val1',key2:123}}",
- "}",
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200:{ description:'Config file section as a map of objects.', 'x-example':{key1:'val1',key2:123}}"
+ }
+ )
)
public ObjectMap setConfigSection(
@Path(name="section", description="Section name in config file.", example="REST") String section,
@@ -182,11 +182,11 @@ public class ConfigResource extends BasicRestServlet {
path="/{section}/{key}",
summary="Update config entry value",
description="Add or overwrite a config file entry.",
- swagger={
- "responses:{",
- "200:{ description:'The updated value.', 'x-example':'servlet:/htdocs/themes/dark.css'}",
- "}",
- }
+ swagger=@MethodSwagger(
+ responses={
+ "200:{ description:'The updated value.', 'x-example':'servlet:/htdocs/themes/dark.css'}"
+ }
+ )
)
public String setConfigValue(
@Path(name="section", description="Section name in config file.", example="REST") String section,
diff --git a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
index eb6a6b7..aa8c40d 100755
--- a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
+++ b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
@@ -144,7 +144,7 @@ public class LogsResource extends BasicRestServlet {
File f = getFile(path);
- Date startDate = parseISO8601Date(start), endDate = parseISO8601Date(end);
+ Date startDate = parseIsoDate(start), endDate = parseIsoDate(end);
if (! highlight) {
Object o = getReader(f, startDate, endDate, thread, loggers, severity);
@@ -194,11 +194,11 @@ public class LogsResource extends BasicRestServlet {
htmldoc=@HtmlDoc(
nav={"<h5>Folder: $RA{fullPath}</h5>"}
),
- swagger={
- "parameters:[",
- Queryable.SWAGGER_PARAMS,
- "]"
- }
+ swagger=@MethodSwagger(
+ parameters={
+ Queryable.SWAGGER_PARAMS
+ }
+ )
)
public LogParser viewParsedEntries(
RestRequest req,
@@ -213,7 +213,7 @@ public class LogsResource extends BasicRestServlet {
File f = getFile(path);
req.setAttribute("fullPath", f.getAbsolutePath());
- Date startDate = parseISO8601Date(start), endDate = parseISO8601Date(end);
+ Date startDate = parseIsoDate(start), endDate = parseIsoDate(end);
return getLogParser(f, startDate, endDate, thread, loggers, severity);
}
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/NlsResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/NlsResource.java
index 279e702..eead39d 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/NlsResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/NlsResource.java
@@ -50,8 +50,8 @@ public class NlsResource extends BasicRestServletGroup {
@RestMethod(
name=POST, path="/{a}",
description="Test1.c",
- swagger= {
- "parameters:[",
+ swagger=@MethodSwagger(
+ parameters={
"{name:'a',in:'path',type:'string',description:'Test1.d'},",
"{name:'b',in:'query',type:'string',description:'Test1.e'},",
"{in:'body',type:'string',description:'Test1.f'},",
@@ -59,12 +59,12 @@ public class NlsResource extends BasicRestServletGroup {
"{name:'a2',in:'path',type:'string',description:'Test1.h'},",
"{name:'b2',in:'query',type:'string',description:'Test1.i'},",
"{name:'D2',in:'header',type:'string',description:'Test1.j'}",
- "],",
- "responses:{",
+ },
+ responses={
"200: {description:'OK'},",
"201: {description:'Test1.l',headers:{bar:{description:'Test1.m',type:'string'}}}",
- "}"
- }
+ }
+ )
)
public String test1(@Path("a") String a, @Query("b") String b, @Body String c, @Header("D") String d,
@Path("e") String e, @Query("f") String f, @Header("g") String g) {
@@ -165,21 +165,21 @@ public class NlsResource extends BasicRestServletGroup {
@RestMethod(
name=POST, path="/{a}",
description="$L{foo}",
- swagger= {
- "parameters:[",
+ swagger=@MethodSwagger(
+ parameters={
"{name:'a',in:'path',description:'$L{foo}'},",
"{name:'b',in:'query',description:'$L{foo}'},",
"{in:'body',description:'$L{foo}'},",
"{name:'D',in:'header',description:'$L{foo}'},",
"{name:'a2',in:'path',description:'$L{foo}'},",
"{name:'b2',in:'query',description:'$L{foo}'},",
- "{name:'D2',in:'header',description:'$L{foo}'}",
- "],",
- "responses:{",
+ "{name:'D2',in:'header',description:'$L{foo}'}"
+ },
+ responses= {
"200: {description:'OK'},",
"201: {description:'$L{foo}',headers:{bar:{description:'$L{foo}',type:'string'}}}",
- "}"
- }
+ }
+ )
)
public String test6(@Path("a") String a, @Query("b") String b, @Body String c, @Header("D") String d,
@Path("e") String e, @Query("f") String f, @Header("g") String g) {
diff --git a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/JacocoDummyTest.java b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/JacocoDummyTest.java
index c1496ce..7761000 100644
--- a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/JacocoDummyTest.java
+++ b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/JacocoDummyTest.java
@@ -14,7 +14,7 @@ package org.apache.juneau.rest.test;
import java.lang.reflect.*;
-import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.util.*;
import org.junit.*;
public class JacocoDummyTest {
diff --git a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestUtilsTest.java b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestUtilsTest.java
index 513e4de..040f61e 100644
--- a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestUtilsTest.java
+++ b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/RestUtilsTest.java
@@ -13,7 +13,7 @@
package org.apache.juneau.rest.test;
import static org.apache.juneau.internal.StringUtils.*;
-import static org.apache.juneau.rest.RestUtils.*;
+import static org.apache.juneau.rest.util.RestUtils.*;
import static org.junit.Assert.*;
import java.util.*;
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
index fc07d68..5077ae3 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
@@ -26,6 +26,7 @@ import javax.servlet.http.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.exception.*;
import org.apache.juneau.rest.helper.*;
+import org.apache.juneau.rest.util.*;
import org.apache.juneau.rest.vars.*;
/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
index 566f366..dee7a7f 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
@@ -33,6 +33,7 @@ import org.apache.juneau.json.*;
import org.apache.juneau.jsonschema.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.util.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.svl.*;
import org.apache.juneau.utils.*;
@@ -146,7 +147,6 @@ public class BasicRestInfoProvider implements RestInfoProvider {
* <br>Never <jk>null</jk>.
* @throws Exception
*/
- @SuppressWarnings("unchecked")
@Override /* RestInfoProvider */
public Swagger getSwagger(RestRequest req) throws Exception {
@@ -182,55 +182,46 @@ public class BasicRestInfoProvider implements RestInfoProvider {
// Combine it with @RestResource(swagger)
for (Map.Entry<Class<?>,RestResource> e : findAnnotationsMapParentFirst(RestResource.class, context.getResource().getClass()).entrySet()) {
- RestResource r = e.getValue();
- if (r.swagger().length > 0) {
- try {
- omSwagger.putAll(parseObjectMap(vr.resolve(join(r.swagger(), '\n').trim()), true));
- } catch (ParseException x) {
- throw new SwaggerException(x, e.getKey(), "Malformed swagger JSON encountered in @RestResource(swagger).");
- }
+ RestResource rr = e.getValue();
+
+ if (! rr.title().isEmpty())
+ omSwagger.getObjectMap("info", true).appendIf(true, true, true, "title", vr.resolve(rr.title()));
+ if (! rr.description().isEmpty())
+ omSwagger.getObjectMap("info", true).appendIf(true, true, true, "description", vr.resolve(rr.description()));
+
+ ResourceSwagger r = rr.swagger();
+
+ omSwagger.putAll(parseMap(join(r.value()), vr, true, false, "@ResourceSwagger(value) on class {0}", c));
+
+ if (r.title().length + r.description().length + r.version().length() + r.contact().length + r.license().length + r.termsOfService().length > 0) {
+ ObjectMap info = omSwagger.getObjectMap("info", true);
+ info.appendIf(true, true, true, "title", vr.resolve(join(r.title())));
+ info.appendIf(true, true, true, "description", vr.resolve(join(r.description())));
+ info.appendIf(true, true, true, "version", vr.resolve(join(r.version())));
+ info.appendIf(true, true, true, "termsOfService", vr.resolve(join(r.termsOfService())));
+ info.appendIf(true, true, true, "contact", parseMap(join(r.contact()), vr, false, true, "@ResourceSwagger(contact) on class {0}", c));
+ info.appendIf(true, true, true, "license", parseMap(join(r.license()), vr, false, true, "@ResourceSwagger(license) on class {0}", c));
}
+
+ omSwagger.appendIf(true, true, true, "externalDocs", parseMap(join(r.externalDocs()), vr, false, true, "@ResourceSwagger(externalDocs) on class {0}", c));
+ omSwagger.appendIf(true, true, true, "tags", parseList(join(r.tags()), vr, false, true, "@ResourceSwagger(tags) on class {0}", c));
}
+
+ omSwagger.appendIf(true, true, true, "externalDocs", parseMap(mb.findFirstString(locale, "externalDocs"), vr, false, true, "Messages/externalDocs on class {0}", c));
- ObjectMap
- info = omSwagger.getObjectMap("info", true),
- externalDocs = omSwagger.getObjectMap("externalDocs", true),
- definitions = omSwagger.getObjectMap("definitions", true);
+ ObjectMap info = omSwagger.getObjectMap("info", true);
+ info.appendIf(true, true, true, "title", vr.resolve(mb.findFirstString(locale, "title")));
+ info.appendIf(true, true, true, "description", vr.resolve(mb.findFirstString(locale, "description")));
+ info.appendIf(true, true, true, "version", vr.resolve(mb.findFirstString(locale, "version")));
+ info.appendIf(true, true, true, "termsOfService", vr.resolve(mb.findFirstString(locale, "termsOfService")));
+ info.appendIf(true, true, true, "contact", parseMap(mb.findFirstString(locale, "contact"), vr, false, true, "Messages/contact on class {0}", c));
+ info.appendIf(true, true, true, "license", parseMap(mb.findFirstString(locale, "license"), vr, false, true, "Messages/license on class {0}", c));
+
ObjectList
produces = omSwagger.getObjectList("produces", true),
consumes = omSwagger.getObjectList("consumes", true);
-
- String s = this.title;
- if (s == null)
- s = mb.findFirstString(locale, "title");
- if (s != null)
- info.put("title", vr.resolve(s));
-
- s = this.description;
- if (s == null)
- s = mb.findFirstString(locale, "description");
- if (s != null)
- info.put("description", vr.resolve(s));
-
- s = mb.findFirstString(locale, "version");
- if (s != null)
- info.put("version", vr.resolve(s));
-
- s = mb.findFirstString(locale, "contact");
- if (s != null)
- info.put("contact", jp.parse(vr.resolve(s), ObjectMap.class));
-
- s = mb.findFirstString(locale, "license");
- if (s != null)
- info.put("license", jp.parse(vr.resolve(s), ObjectMap.class));
-
- s = mb.findFirstString(locale, "termsOfService");
- if (s != null)
- info.put("termsOfService", vr.resolve(s));
-
if (consumes.isEmpty())
consumes.addAll(req.getContext().getConsumes());
-
if (produces.isEmpty())
produces.addAll(req.getContext().getProduces());
@@ -239,17 +230,17 @@ public class BasicRestInfoProvider implements RestInfoProvider {
for (ObjectMap om : omSwagger.getObjectList("tags").elements(ObjectMap.class)) {
String name = om.getString("name");
if (name == null)
- throw new SwaggerException(c, "Tag definition found without name in swagger JSON.");
+ throw new SwaggerException(null, "Tag definition found without name in swagger JSON.");
tagMap.put(name, om);
}
}
- s = mb.findFirstString(locale, "tags");
+ String s = mb.findFirstString(locale, "tags");
if (s != null) {
- for (ObjectMap m : jp.parse(vr.resolve(s), ObjectList.class).elements(ObjectMap.class)) {
+ for (ObjectMap m : parseList(s, vr, true, false, "Messages/tags on class {0}", c).elements(ObjectMap.class)) {
String name = m.getString("name");
if (name == null)
- throw new SwaggerException(c, "Tag definition found without name in resource bundle.");
+ throw new SwaggerException(null, "Tag definition found without name in resource bundle on class {0}", c) ;
if (tagMap.containsKey(name))
tagMap.get(name).putAll(m);
else
@@ -257,11 +248,8 @@ public class BasicRestInfoProvider implements RestInfoProvider {
}
}
- s = mb.findFirstString(locale, "externalDocs");
- if (s != null)
- externalDocs.putAll(jp.parse(vr.resolve(s), ObjectMap.class));
-
// Load our existing bean definitions into our session.
+ ObjectMap definitions = omSwagger.getObjectMap("definitions", true);
for (String defId : definitions.keySet())
js.addBeanDef(defId, definitions.getObjectMap(defId));
@@ -280,61 +268,46 @@ public class BasicRestInfoProvider implements RestInfoProvider {
ObjectMap op = getOperation(omSwagger, sm.getPathPattern(), sm.getHttpMethod().toLowerCase());
// Add @RestMethod(swagger)
- if (rm.swagger().length > 0) {
- try {
- op.putAll(parseObjectMap( vr.resolve(join(rm.swagger(), '\n').trim()), true));
- } catch (ParseException e) {
- throw new SwaggerException(e, m, "Malformed swagger JSON encountered in @RestMethod(swagger).");
- }
- }
+ MethodSwagger ms = rm.swagger();
+
+ op.putAll(parseMap(join(ms.value()), vr, true, false, "@MethodSwagger(value) on class {0} method {1}", c, m));
+ op.appendIf(true, true, true, "summary", vr.resolve(rm.summary()));
+ op.appendIf(true, true, true, "summary", vr.resolve(join(ms.summary())));
+ op.appendIf(true, true, true, "description", vr.resolve(join(rm.description())));
+ op.appendIf(true, true, true, "description", vr.resolve(join(ms.description())));
+ op.appendIf(true, true, true, "deprecated", vr.resolve(ms.deprecated()));
+ op.appendIf(true, true, true, "externalDocs", parseMap(join(ms.externalDocs()), vr, false, true, "@MethodSwagger(externalDocs) on class {0} method {1}", c, m));
+
+ if (ms.parameters().length > 0)
+ op.getObjectList("parameters", true).addAll(parseList(join(ms.parameters()), vr, false, false, "@MethodSwagger(parameters) on class {0} method {1}", c, m));
+ if (ms.responses().length > 0)
+ op.getObjectMap("responses", true).putAll(parseMap(join(ms.responses()), vr, false, false, "@MethodSwagger(responses) on class {0} method {1}", c, m));
+ if (ms.tags().length > 0)
+ op.getObjectList("tags", true).addAll(parseListOrCdl(join(ms.tags()), vr, false, false, "@MethodSwagger(tags) on class {0} method {1}", c, m));
op.putIfNotExists("operationId", mn);
if (m.getAnnotation(Deprecated.class) != null)
op.put("deprecated", true);
-
- s = rm.summary();
- if (s.isEmpty())
- s = mb.findFirstString(locale, mn + ".summary");
- if (s != null)
- op.put("summary", vr.resolve(s));
- s = join(rm.description(), "");
- if (s.isEmpty())
- s = mb.findFirstString(locale, mn + ".description");
- if (s != null)
- op.put("description", vr.resolve(s));
+ op.appendIf(true, true, true, "summary", vr.resolve(mb.findFirstString(locale, mn + ".summary")));
+ op.appendIf(true, true, true, "description", vr.resolve(mb.findFirstString(locale, mn + ".description")));
- Set<String> tags = new LinkedHashSet<>();
- if (op.containsKey("tags"))
- for (String tag : op.getObjectList("tags").elements(String.class))
- tags.add(tag);
-
s = mb.findFirstString(locale, mn + ".tags");
- if (s != null) {
- s = vr.resolve(s);
- if (isObjectList(s, true))
- tags.addAll((List<String>)jp.parse(s, ArrayList.class, String.class));
- else
- tags.addAll(Arrays.asList(StringUtils.split(s)));
- }
+ if (s != null)
+ op.getObjectList("tags", true).addAll(parseListOrCdl(s, vr, false, false, "Messages/tags on class {0} method {1}", c, m));
- for (String tag : tags)
- if (! tagMap.containsKey(tag))
- tagMap.put(tag, new ObjectMap().append("name", tag));
+ if (op.containsKey("tags"))
+ for (String tag : op.getObjectList("tags").elements(String.class))
+ if (! tagMap.containsKey(tag))
+ tagMap.put(tag, new ObjectMap().append("name", tag));
- if (! tags.isEmpty())
- op.put("tags", tags);
-
- s = mb.findFirstString(locale, mn + ".externalDocs");
- if (s != null) {
- ObjectMap eom = jp.parse(vr.resolve(s), ObjectMap.class);
- if (op.containsKey("externalDocs"))
- op.getObjectMap("externalDocs").putAll(eom);
- else
- op.put("externalDocs", eom);
- }
+ op.appendIf(true, true, true, "externalDocs", parseMap(mb.findFirstString(locale, mn + ".description"), vr, false, true, "Messages/externalDocs on class {0} method {1}", c, m));
+ s = mb.findFirstString(locale, mn + ".parameters");
+ if (s != null)
+ op.getObjectList("parameters", true).addAll(parseList(s, vr, false, false, "Messages/parameters on class {0} method {1}", c, m));
+
ObjectMap paramMap = new ObjectMap();
ObjectList ol = op.getObjectList("parameters");
@@ -342,18 +315,6 @@ public class BasicRestInfoProvider implements RestInfoProvider {
for (ObjectMap param : ol.elements(ObjectMap.class))
paramMap.put(param.getString("in") + '.' + param.getString("name"), param);
- s = mb.findFirstString(locale, mn + ".parameters");
- if (s != null) {
- ol = jp.parse(vr.resolve(s), ObjectList.class);
- for (ObjectMap param : ol.elements(ObjectMap.class)) {
- String key = param.getString("in") + '.' + param.getString("name");
- if (paramMap.containsKey(key))
- paramMap.getObjectMap(key).putAll(param);
- else
- paramMap.put(key, param);
- }
- }
-
// Finally, look for parameters defined on method.
for (RestMethodParam mp : context.getRestMethodParams(m)) {
@@ -372,50 +333,29 @@ public class BasicRestInfoProvider implements RestInfoProvider {
param.append("name", mp.name);
ObjectMap pi = mp.getMetaData();
- if (pi.containsKeyNotEmpty("required"))
- param.appendIf(false, true, true, "required", vr.resolve(pi.getString("required")));
- if (pi.containsKeyNotEmpty("description"))
- param.appendIf(false, true, true, "description", vr.resolve(pi.getString("description")));
- if (pi.containsKeyNotEmpty("type"))
- param.appendIf(false, true, true, "type", vr.resolve(pi.getString("type")));
- if (pi.containsKeyNotEmpty("format"))
- param.appendIf(false, true, true, "format", vr.resolve(pi.getString("format")));
- if (pi.containsKeyNotEmpty("pattern"))
- param.appendIf(false, true, true, "pattern", vr.resolve(pi.getString("pattern")));
- if (pi.containsKeyNotEmpty("collectionFormat"))
- param.appendIf(false, true, true, "collectionFormat", vr.resolve(pi.getString("collectionFormat")));
- if (pi.containsKeyNotEmpty("maximum"))
- param.appendIf(false, true, true, "maximum", vr.resolve(pi.getString("maximum")));
- if (pi.containsKeyNotEmpty("minimum"))
- param.appendIf(false, true, true, "minimum", vr.resolve(pi.getString("minimum")));
- if (pi.containsKeyNotEmpty("multipleOf"))
- param.appendIf(false, true, true, "multipleOf", vr.resolve(pi.getString("multipleOf")));
- if (pi.containsKeyNotEmpty("maxLength"))
- param.appendIf(false, true, true, "maxLength", vr.resolve(pi.getString("maxLength")));
- if (pi.containsKeyNotEmpty("minLength"))
- param.appendIf(false, true, true, "minLength", vr.resolve(pi.getString("minLength")));
- if (pi.containsKeyNotEmpty("maxItems"))
- param.appendIf(false, true, true, "maxItems", vr.resolve(pi.getString("maxItems")));
- if (pi.containsKeyNotEmpty("minItems"))
- param.appendIf(false, true, true, "minItems", vr.resolve(pi.getString("minItems")));
- if (pi.containsKeyNotEmpty("allowEmptyVals"))
- param.appendIf(false, true, true, "allowEmptyVals", vr.resolve(pi.getString("allowEmptyVals")));
- if (pi.containsKeyNotEmpty("exclusiveMaximum"))
- param.appendIf(false, true, true, "exclusiveMaximum", vr.resolve(pi.getString("exclusiveMaximum")));
- if (pi.containsKeyNotEmpty("exclusiveMimimum"))
- param.appendIf(false, true, true, "exclusiveMimimum", vr.resolve(pi.getString("exclusiveMimimum")));
- if (pi.containsKeyNotEmpty("uniqueItems"))
- param.appendIf(false, true, true, "uniqueItems", vr.resolve(pi.getString("uniqueItems")));
- if (pi.containsKeyNotEmpty("schema"))
- param.appendIf(false, true, true, "schema", parseObjectMap(vr.resolve(pi.getString("schema")), false));
- if (pi.containsKeyNotEmpty("default"))
- param.appendIf(false, true, true, "default", JsonParser.DEFAULT.parse(vr.resolve(pi.getString("default")), Object.class));
- if (pi.containsKeyNotEmpty("enum"))
- param.appendIf(false, true, true, "enum", parseObjectList(vr.resolve(pi.getString("enum")), false));
+ param.appendIf(false, true, true, "required", vr.resolve(pi.getString("required")));
+ param.appendIf(false, true, true, "description", vr.resolve(pi.getString("description")));
+ param.appendIf(false, true, true, "type", vr.resolve(pi.getString("type")));
+ param.appendIf(false, true, true, "format", vr.resolve(pi.getString("format")));
+ param.appendIf(false, true, true, "pattern", vr.resolve(pi.getString("pattern")));
+ param.appendIf(false, true, true, "collectionFormat", vr.resolve(pi.getString("collectionFormat")));
+ param.appendIf(false, true, true, "maximum", vr.resolve(pi.getString("maximum")));
+ param.appendIf(false, true, true, "minimum", vr.resolve(pi.getString("minimum")));
+ param.appendIf(false, true, true, "multipleOf", vr.resolve(pi.getString("multipleOf")));
+ param.appendIf(false, true, true, "maxLength", vr.resolve(pi.getString("maxLength")));
+ param.appendIf(false, true, true, "minLength", vr.resolve(pi.getString("minLength")));
+ param.appendIf(false, true, true, "maxItems", vr.resolve(pi.getString("maxItems")));
+ param.appendIf(false, true, true, "minItems", vr.resolve(pi.getString("minItems")));
+ param.appendIf(false, true, true, "allowEmptyVals", vr.resolve(pi.getString("allowEmptyVals")));
+ param.appendIf(false, true, true, "exclusiveMaximum", vr.resolve(pi.getString("exclusiveMaximum")));
+ param.appendIf(false, true, true, "exclusiveMimimum", vr.resolve(pi.getString("exclusiveMimimum")));
+ param.appendIf(false, true, true, "uniqueItems", vr.resolve(pi.getString("uniqueItems")));
+ param.appendIf(false, true, true, "schema", parseMap(pi.getString("schema"), vr, false, true, "ParameterInfo/schema on class {0} method {1}", c, m));
+ param.appendIf(false, true, true, "default", JsonParser.DEFAULT.parse(vr.resolve(pi.getString("default")), Object.class));
+ param.appendIf(false, true, true, "enum", parseList(pi.getString("enum"), vr, false, true, "ParameterInfo/enum on class {0} method {1}", c, m));
+ param.appendIf(false, true, true, "x-example", parseAnything(vr.resolve(pi.getString("example"))));
if (pi.containsKeyNotEmpty("items"))
param.appendIf(false, true, true, "items", new ObjectMap(vr.resolve(pi.getString("items"))));
- if (pi.containsKeyNotEmpty("example"))
- param.appendIf(false, true, true, "x-example", parse(vr.resolve(pi.getString("example"))));
if ((in == BODY || in == PATH) && ! param.containsKeyNotEmpty("required"))
param.put("required", true);
@@ -444,18 +384,12 @@ public class BasicRestInfoProvider implements RestInfoProvider {
for (RestMethodThrown rt : context.getRestMethodThrowns(m)) {
int code = rt.getCode();
if (code != 0) {
- ObjectMap om = responses.getObjectMap(String.valueOf(code), true);
-
ObjectMap md = rt.getMetaData();
- if (md.containsKeyNotEmpty("description"))
- om.appendIf(false, true, true, "description", vr.resolve(md.getString("description")));
- if (md.containsKeyNotEmpty("example"))
- om.appendIf(false, true, true, "x-example", parse(vr.resolve(md.getString("example"))));
- if (md.containsKeyNotEmpty("schema"))
- om.appendIf(false, true, true, "schema", parseObjectMap(vr.resolve(md.getString("schema")), false));
- if (md.containsKeyNotEmpty("headers")) {
- om.appendIf(false, true, true, "headers", parseObjectList(vr.resolve(md.getString("headers")), false));
- }
+ ObjectMap om = responses.getObjectMap(String.valueOf(code), true);
+ om.appendIf(false, true, true, "description", vr.resolve(md.getString("description")));
+ om.appendIf(false, true, true, "x-example", parseAnything(vr.resolve(md.getString("example"))));
+ om.appendIf(false, true, true, "schema", parseMap(md.getString("schema"), vr, false, true, "RestMethodThrown/schema on class {0} method {1}", c, m));
+ om.appendIf(false, true, true, "headers", parseList(md.getString("headers"), vr, false, true, "RestMethodThrown/headers on class {0} method {1}", c, m));
}
}
@@ -465,14 +399,10 @@ public class BasicRestInfoProvider implements RestInfoProvider {
ObjectMap rom = responses.getObjectMap(rStatus, true);
ObjectMap rmd = r.getMetaData();
- if (rmd.containsKeyNotEmpty("description"))
- rom.appendIf(false, true, true, "description", vr.resolve(rmd.getString("description")));
- if (rmd.containsKeyNotEmpty("example"))
- rom.appendIf(false, true, true, "x-example", parse(vr.resolve(rmd.getString("example"))));
- if (rmd.containsKeyNotEmpty("schema"))
- rom.appendIf(false, true, true, "schema", parseObjectMap(vr.resolve(rmd.getString("schema")), false));
- if (rmd.containsKeyNotEmpty("headers"))
- rom.appendIf(false, true, true, "headers", parseObjectMap(vr.resolve(rmd.getString("headers")), false));
+ rom.appendIf(false, true, true, "description", vr.resolve(rmd.getString("description")));
+ rom.appendIf(false, true, true, "x-example", parseAnything(vr.resolve(rmd.getString("example"))));
+ rom.appendIf(false, true, true, "schema", parseMap(rmd.getString("schema"), vr, false, true, "RestMethodReturn/schema on class {0} method {1}", c, m));
+ rom.appendIf(false, true, true, "headers", parseMap(rmd.getString("headers"), vr, false, true, "RestMethodReturn/headers on class {0} method {1}", c, m));
rom.put("schema", getSchema(req, rom.getObjectMap("schema", true), js, m.getGenericReturnType()));
addXExamples(req, sm, rom, "ok", js, m.getGenericReturnType());
@@ -508,8 +438,6 @@ public class BasicRestInfoProvider implements RestInfoProvider {
if (definitions.isEmpty())
omSwagger.remove("definitions");
- if (externalDocs.isEmpty())
- omSwagger.remove("externalDocs");
if (tagMap.isEmpty())
omSwagger.remove("tags");
@@ -527,27 +455,65 @@ public class BasicRestInfoProvider implements RestInfoProvider {
return swagger;
}
- private Object parse(String s) throws ParseException {
+ private String join(String...s) {
+ return StringUtils.join(s, '\n');
+ }
+
+ private Object parseAnything(String s) throws ParseException {
+ if (s == null)
+ return null;
char c1 = StringUtils.firstNonWhitespaceChar(s), c2 = StringUtils.lastNonWhitespaceChar(s);
if (c1 == '{' && c2 == '}' || c1 == '[' && c2 == ']' || c1 == '\'' && c2 == '\'')
return JsonParser.DEFAULT.parse(s, Object.class);
return s;
}
- private ObjectMap parseObjectMap(String s, boolean ignoreCommentsAndWhitespace) throws ParseException {
- s = s.trim();
- if ("IGNORE".equalsIgnoreCase(s))
- return new ObjectMap().append("ignore", true);
- if (! isObjectMap(s, ignoreCommentsAndWhitespace))
- s = "{" + s + "}";
- return new ObjectMap(s);
+ private ObjectMap parseMap(String s, VarResolverSession vs, boolean ignoreCommentsAndWhitespace, boolean nullOnEmpty, String location, Object...locationArgs) throws ParseException {
+ try {
+ if (s == null)
+ return null;
+ if (s.isEmpty())
+ return nullOnEmpty ? null : ObjectMap.EMPTY_MAP;
+ s = vs.resolve(s.trim());
+ if ("IGNORE".equalsIgnoreCase(s))
+ return new ObjectMap().append("ignore", true);
+ if (! isObjectMap(s, ignoreCommentsAndWhitespace))
+ s = "{" + s + "}";
+ return new ObjectMap(s);
+ } catch (ParseException e) {
+ throw new SwaggerException(e, "Malformed swagger JSON object encountered in " + location + ".", locationArgs);
+ }
}
- private ObjectList parseObjectList(String s, boolean ignoreCommentsAndWhitespace) throws ParseException {
- if (! isObjectList(s, ignoreCommentsAndWhitespace))
- s = "[" + s + "]";
- return new ObjectList(s);
+ private ObjectList parseList(String s, VarResolverSession vs, boolean ignoreCommentsAndWhitespace, boolean nullOnEmpty, String location, Object...locationArgs) throws ParseException {
+ try {
+ if (s == null)
+ return null;
+ if (s.isEmpty())
+ return nullOnEmpty ? null : ObjectList.EMPTY_LIST;
+ s = vs.resolve(s.trim());
+ if (! isObjectList(s, ignoreCommentsAndWhitespace))
+ s = "[" + s + "]";
+ return new ObjectList(s);
+ } catch (ParseException e) {
+ throw new SwaggerException(e, "Malformed swagger JSON array encountered in "+location+".", locationArgs);
+ }
}
+
+ private ObjectList parseListOrCdl(String s, VarResolverSession vs, boolean ignoreCommentsAndWhitespace, boolean nullOnEmpty, String location, Object...locationArgs) throws ParseException {
+ try {
+ if (s == null)
+ return null;
+ if (s.isEmpty())
+ return nullOnEmpty ? null : ObjectList.EMPTY_LIST;
+ s = vs.resolve(s.trim());
+ if (! isObjectList(s, ignoreCommentsAndWhitespace))
+ return new ObjectList(Arrays.asList(StringUtils.split(s, ',')));
+ return new ObjectList(s);
+ } catch (ParseException e) {
+ throw new SwaggerException(e, "Malformed swagger JSON array encountered in "+location+".", locationArgs);
+ }
+ }
private ObjectMap getSchema(RestRequest req, ObjectMap schema, JsonSchemaSerializerSession js, Type type) throws Exception {
BeanSession bs = req.getBeanSession();
@@ -651,16 +617,8 @@ public class BasicRestInfoProvider implements RestInfoProvider {
private static class SwaggerException extends ParseException {
private static final long serialVersionUID = 1L;
- SwaggerException(Class<?> c, String message, Object...args) {
- this(null, c, message, args);
- }
- SwaggerException(Exception e, Class<?> c, String message, Object...args) {
- super("Swagger exception on class " + c.getName() + ". " + message, args);
- initCause(e);
- }
- SwaggerException(Exception e, Method m, String message, Object...args) {
- super("Swagger exception on class " + m.getDeclaringClass().getName() + " method "+m.getName()+". " + message, args);
- initCause(e);
+ SwaggerException(Exception e, String location, Object...locationArgs) {
+ super(e, "Swagger exception: at " + format(location, locationArgs));
}
}
@@ -778,7 +736,7 @@ public class BasicRestInfoProvider implements RestInfoProvider {
public String getMethodDescription(Method method, RestRequest req) throws Exception {
VarResolverSession vr = req.getVarResolverSession();
- String s = join(method.getAnnotation(RestMethod.class).description(), "");
+ String s = join(method.getAnnotation(RestMethod.class).description());
if (s.isEmpty()) {
Operation o = getSwaggerOperation(method, req);
if (o != null)
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServletGroup.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServletGroup.java
index 7e30ff7..7b38b53 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServletGroup.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServletGroup.java
@@ -43,7 +43,7 @@ public abstract class BasicRestServletGroup extends BasicRestServlet {
* @return The bean containing links to the child resources.
* @throws Exception
*/
- @RestMethod(name=GET, path="/", description="Child resources")
+ @RestMethod(name=GET, path="/", summary="Navigation page")
public ChildResourceDescriptions getChildren(RestRequest req) throws Exception {
return new ChildResourceDescriptions(getContext(), req);
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
index 22e91fe..e97a615 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
@@ -27,6 +27,7 @@ import org.apache.juneau.http.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.rest.exception.*;
+import org.apache.juneau.rest.util.*;
/**
* Contains the body of the HTTP request.
@@ -461,114 +462,4 @@ public class RequestBody {
public int getContentLength() {
return contentLength == 0 ? req.getRawContentLength() : contentLength;
}
-
- /**
- * ServletInputStream wrapper around a normal input stream.
- */
- static final class BoundedServletInputStream extends ServletInputStream {
-
- private final InputStream is;
- private final ServletInputStream sis;
- private long remain;
-
- BoundedServletInputStream(InputStream is, long max) {
- this.is = is;
- this.sis = null;
- this.remain = max;
- }
-
- BoundedServletInputStream(ServletInputStream sis, long max) {
- this.sis = sis;
- this.is = sis;
- this.remain = max;
- }
-
- BoundedServletInputStream(byte[] b) {
- this(new ByteArrayInputStream(b), Long.MAX_VALUE);
- }
-
- @Override /* InputStream */
- public final int read() throws IOException {
- decrement();
- return is.read();
- }
-
- @Override /* InputStream */
- public int read(byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-
- @Override /* InputStream */
- public int read(final byte[] b, final int off, final int len) throws IOException {
- long numBytes = Math.min(len, remain);
- int r = is.read(b, off, (int) numBytes);
- if (r == -1)
- return -1;
- decrement(numBytes);
- return r;
- }
-
- @Override /* InputStream */
- public long skip(final long n) throws IOException {
- long toSkip = Math.min(n, remain);
- long r = is.skip(toSkip);
- decrement(r);
- return r;
- }
-
- @Override /* InputStream */
- public int available() throws IOException {
- if (remain <= 0)
- return 0;
- return is.available();
- }
-
- @Override /* InputStream */
- public synchronized void reset() throws IOException {
- is.reset();
- }
-
- @Override /* InputStream */
- public synchronized void mark(int limit) {
- is.mark(limit);
- }
-
- @Override /* InputStream */
- public boolean markSupported() {
- return is.markSupported();
- }
-
- @Override /* InputStream */
- public final void close() throws IOException {
- is.close();
- }
-
- @Override /* ServletInputStream */
- public boolean isFinished() {
- return sis == null ? false : sis.isFinished();
- }
-
- @Override /* ServletInputStream */
- public boolean isReady() {
- return sis == null ? true : sis.isReady();
- }
-
- @Override /* ServletInputStream */
- public void setReadListener(ReadListener arg0) {
- if (sis != null)
- sis.setReadListener(arg0);
- }
-
- private void decrement() throws IOException {
- remain--;
- if (remain < 0)
- throw new IOException("Input limit exceeded. See @RestResource.maxInput().");
- }
-
- private void decrement(long count) throws IOException {
- remain -= count;
- if (remain < 0)
- throw new IOException("Input limit exceeded. See @RestResource.maxInput().");
- }
- }
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 41ea56b..9730376 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -3159,7 +3159,7 @@ public final class RestContext extends BeanContext {
if (r instanceof RestServlet)
((RestServlet)r).innerInit(childBuilder);
childBuilder.servletContext(servletContext);
- RestContext rc2 = new RestContext(childBuilder);
+ RestContext rc2 = childBuilder.build();
if (r instanceof RestServlet)
((RestServlet)r).setContext(rc2);
path = childBuilder.path;
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
index 1d2b66c..4e2dfab 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
@@ -36,6 +36,7 @@ import org.apache.juneau.internal.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.response.*;
+import org.apache.juneau.rest.util.*;
import org.apache.juneau.rest.vars.*;
import org.apache.juneau.rest.widget.*;
import org.apache.juneau.serializer.*;
@@ -170,10 +171,12 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
vr = varResolverBuilder.build();
// Add the servlet init parameters to our properties.
- for (Enumeration<String> ep = servletConfig.getInitParameterNames(); ep.hasMoreElements();) {
- String p = ep.nextElement();
- String initParam = servletConfig.getInitParameter(p);
- set(vr.resolve(p), vr.resolve(initParam));
+ if (servletConfig != null) {
+ for (Enumeration<String> ep = servletConfig.getInitParameterNames(); ep.hasMoreElements();) {
+ String p = ep.nextElement();
+ String initParam = servletConfig.getInitParameter(p);
+ set(vr.resolve(p), vr.resolve(initParam));
+ }
}
// Load stuff from parent-to-child order.
@@ -262,6 +265,17 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
}
}
+ @Override /* BeanContextBuilder */
+ public RestContext build() {
+ try {
+ return new RestContext(this);
+ } catch (RestException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private static String[] resolveVars(VarResolver vr, String[] in) {
String[] out = new String[in.length];
for (int i = 0; i < in.length; i++)
@@ -272,7 +286,7 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
/*
* Calls all @RestHook(INIT) methods on the specified resource object.
*/
- void init(Object resource) throws ServletException {
+ RestContextBuilder init(Object resource) throws ServletException {
this.resource = resource;
// Once we have the resource object, we can construct the Widgets.
@@ -311,6 +325,7 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
throw new RestServletException("Exception thrown from @RestHook(INIT) method {0}.", m).initCause(e);
}
}
+ return this;
}
RestContextBuilder servletContext(ServletContext servletContext) {
@@ -2343,10 +2358,4 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
public String getServletName() {
return inner.getServletName();
}
-
- @Override /* BeanContextBuilder */
- public BeanContext build() {
- // We don't actually generate bean context objects from this class yet.
- return null;
- }
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
index 4fea1a6..a183542 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
@@ -34,6 +34,7 @@ import org.apache.juneau.internal.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.exception.*;
+import org.apache.juneau.rest.util.*;
import org.apache.juneau.rest.widget.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.svl.*;
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
index ca8e06b..85cbfca 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -39,6 +39,7 @@ import org.apache.juneau.parser.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.exception.*;
import org.apache.juneau.rest.helper.*;
+import org.apache.juneau.rest.util.*;
import org.apache.juneau.rest.widget.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.svl.*;
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
index 03af644..e24cafa 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
@@ -27,6 +27,7 @@ import org.apache.juneau.http.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.exception.*;
+import org.apache.juneau.rest.util.*;
import org.apache.juneau.serializer.*;
/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
index 67333c8..e436452 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestServlet.java
@@ -51,7 +51,7 @@ public abstract class RestServlet extends HttpServlet {
super.init(servletConfig);
if (! isInitialized) {
builder.servletContext(this.getServletContext());
- context = new RestContext(builder);
+ context = builder.build();
isInitialized = true;
}
context.postInit();
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java
new file mode 100644
index 0000000..496a5c0
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/MethodSwagger.java
@@ -0,0 +1,245 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.rest.annotation;
+
+/**
+ * Extended annotation for {@link RestMethod#swagger() RestMethod.swagger()}.
+ *
+ * <h5 class='section'>See Also:</h5>
+ * <ul>
+ * <li class='link'><a class="doclink" href="../../../../../overview-summary.html#juneau-rest-server.OptionsPages">Overview > juneau-rest-server > OPTIONS Pages</a>
+ * </ul>
+ */
+public @interface MethodSwagger {
+
+
+ /**
+ * Swagger JSON.
+ *
+ * <p>
+ * Used for free-form Swagger documentation of a REST resource.
+ *
+ *
+ swagger={
+ "tags:[ 'store' ],",
+ "responses:{",
+ "200:{ 'x-example':{AVAILABLE:123} }",
+ "},",
+ "security:[ { api_key:[] } ]"
+ }
+ )
+ swagger={
+ "tags:[ 'store' ],",
+ "responses:{",
+ "200:{ 'x-example':{AVAILABLE:123} }",
+ "},",
+ "security:[ { api_key:[] } ]"
+ }
+ swagger= {
+ "parameters:[",
+ "{name:'a',in:'path',type:'string',description:'Test1.d'},",
+ "{name:'b',in:'query',type:'string',description:'Test1.e'},",
+ "{in:'body',type:'string',description:'Test1.f'},",
+ "{name:'D',in:'header',type:'string',description:'Test1.g'},",
+ "{name:'a2',in:'path',type:'string',description:'Test1.h'},",
+ "{name:'b2',in:'query',type:'string',description:'Test1.i'},",
+ "{name:'D2',in:'header',type:'string',description:'Test1.j'}",
+ "],",
+ "responses:{",
+ "200: {description:'OK'},",
+ "201: {description:'Test1.l',headers:{bar:{description:'Test1.m',type:'string'}}}",
+ "}"
+ }
+ swagger=@MethodSwagger(
+ parameters={
+ "{name:'a',in:'path',type:'string',description:'Test1.d'},",
+ "{name:'b',in:'query',type:'string',description:'Test1.e'},",
+ "{in:'body',type:'string',description:'Test1.f'},",
+ "{name:'D',in:'header',type:'string',description:'Test1.g'},",
+ "{name:'a2',in:'path',type:'string',description:'Test1.h'},",
+ "{name:'b2',in:'query',type:'string',description:'Test1.i'},",
+ "{name:'D2',in:'header',type:'string',description:'Test1.j'}",
+ },
+ responses={
+ "200: {description:'OK'},",
+ "201: {description:'Test1.l',headers:{bar:{description:'Test1.m',type:'string'}}}",
+ }
+ )
+ *
+ *
+ */
+ String[] value() default {};
+
+ String[] summary() default {};
+
+ String[] description() default {};
+
+ /**
+ * Optional deprecated flag for the exposed API.
+ *
+ * <p>
+ * Used to populate the Swagger deprecated field.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ * swagger=<ja>@MethodSwagger</ja>(
+ * deprecated=<jk>true</jk>
+ * )
+ * )
+ * </p>
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * Corresponds to the swagger field <code>/paths/{path}/{method}/deprecated</code>.
+ * </ul>
+ */
+ String deprecated() default "";
+
+ /**
+ * Optional external documentation information for the exposed API.
+ *
+ * <p>
+ * Used to populate the Swagger external documentation field.
+ *
+ * <p>
+ * A simplified JSON string with the following fields:
+ * <p class='bcode'>
+ * {
+ * description: string,
+ * url: string
+ * }
+ * </p>
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ * swagger=<ja>@MethodSwagger</ja>(
+ * <js>"{url:'http://juneau.apache.org'}"</js>
+ * )
+ * )
+ * </p>
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Corresponds to the swagger field <code>/paths/{path}/{method}/externalDocs</code>.
+ * </ul>
+ */
+ String[] externalDocs() default {};
+
+ /**
+ * Optional parameter descriptions.
+ *
+ * <p>
+ * This annotation is provided for documentation purposes and is used to populate the method <js>"parameters"</js>
+ * column on the Swagger page.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ * name=<jsf>POST</jsf>, path=<js>"/{a}"</js>,
+ * description=<js>"This is my method."</js>,
+ * swagger=<ja>@MethodSwagger</ja>(
+ * parameters={
+ * <ja>@Parameter</ja>(in=<js>"path"</js>, name=<js>"a"</js>, description=<js>"The 'a' attribute"</js>),
+ * <ja>@Parameter</ja>(in=<js>"query"</js>, name=<js>"b"</js>, description=<js>"The 'b' parameter"</js>, required=<jk>true</jk>),
+ * <ja>@Parameter</ja>(in=<js>"body"</js>, description=<js>"The HTTP content"</js>),
+ * <ja>@Parameter</ja>(in=<js>"header"</js>, name=<js>"D"</js>, description=<js>"The 'D' header"</js>),
+ * }
+ * )
+ * )
+ * </p>
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Corresponds to the swagger field <code>/paths/{path}/{method}/parameters</code>.
+ * </ul>
+ */
+ String[] parameters() default {};
+
+ /**
+ * Optional output description.
+ *
+ * <p>
+ * This annotation is provided for documentation purposes and is used to populate the method <js>"responses"</js>
+ * column on the Swagger page.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ * name=<jsf>GET</jsf>, path=<js>"/"</js>,
+ * swagger=<ja>@MethodSwagger</ja>(
+ * responses={
+ * <ja>@Response</ja>(200),
+ * <ja>@Response</ja>(
+ * value=302,
+ * description=<js>"Thing wasn't found here"</js>,
+ * headers={
+ * <ja>@Parameter</ja>(name=<js>"Location"</js>, description=<js>"The place to find the thing"</js>)
+ * }
+ * )
+ * }
+ * )
+ * )
+ * </p>
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Corresponds to the swagger field <code>/paths/{path}/{method}/responses</code>.
+ * </ul>
+ */
+ String[] responses() default {};
+
+ /**
+ * Optional tagging information for the exposed API.
+ *
+ * <p>
+ * Used to populate the Swagger tags field.
+ *
+ * <p>
+ * A comma-delimited list of tags for API documentation control.
+ * <br>Tags can be used for logical grouping of operations by resources or any other qualifier.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestMethod</ja>(
+ * swagger=<ja>@MethodSwagger</ja>(
+ * tags=<js>"foo,bar"</js>
+ * )
+ * )
+ * </p>
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
+ * (e.g. <js>"$L{my.localized.variable}"</js>).
+ * <li>
+ * Corresponds to the swagger field <code>/paths/{path}/{method}/tags</code>.
+ * </ul>
+ */
+ String[] tags() default "";
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResourceSwagger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResourceSwagger.java
new file mode 100644
index 0000000..c13cdac
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResourceSwagger.java
@@ -0,0 +1,356 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.rest.annotation;
+
+import org.apache.juneau.config.vars.*;
+import org.apache.juneau.rest.vars.*;
+import org.apache.juneau.svl.vars.*;
+
+/**
+ * Extended annotation for {@link RestResource#swagger() @RestResource.swagger()}.
+ *
+ * <h5 class='section'>See Also:</h5>
+ * <ul>
+ * <li class='link'><a class="doclink" href="../../../../../overview-summary.html#juneau-rest-server.OptionsPages">Overview > juneau-rest-server > OPTIONS pages</a>
+ * </ul>
+ */
+public @interface ResourceSwagger {
+
+ String[] value() default {};
+
+ String[] title() default {};
+
+ String[] description() default {};
+
+ /**
+ * Optional contact information for the exposed API.
+ *
+ * <p>
+ * It is used to populate the Swagger contact field and to display on HTML pages.
+ *
+ * <p>
+ * A simplified JSON string with the following fields:
+ * <p class='bcode'>
+ * {
+ * name: string,
+ * url: string,
+ * email: string
+ * }
+ * </p>
+ *
+ * <p>
+ * The default value pulls the description from the <code>contact</code> entry in the servlet resource bundle.
+ * (e.g. <js>"contact = {name:'John Smith',email:'john.smith@foo.bar'}"</js> or
+ * <js>"MyServlet.contact = {name:'John Smith',email:'john.smith@foo.bar'}"</js>).
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestResource</ja>(
+ * swagger=<ja>@MethodSwagger</ja>(
+ * contact=<js>"{name:'John Smith',email:'john.smith@foo.bar'}"</js>
+ * )
+ * )
+ * </p>
+ swagger={
+ "info: {",
+ "contact:{name:'Juneau Developer',email:'dev@juneau.apache.org'},",
+ "license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},",
+ "version:'2.0',",
+ "termsOfService:'You are on your own.'",
+ "},",
+ "externalDocs:{description:'Apache Juneau',url:'http://juneau.apache.org'}"
+ }
+ swagger=@ResourceSwagger(
+ contact="name:'Juneau Developer',email:'dev@juneau.apache.org'",
+ license="name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'",
+ version="2.0",
+ termsOfService="You are on your own.",
+ externalDocs="description:'Apache Juneau',url:'http://juneau.apache.org'}"
+ )
+ swagger=@ResourceSwagger("$F{PetStoreResource.json}"),
+ *
+ * <p>
+ * Value can contain any of the following variables:
+ * {@link ConfigVar $C}
+ * {@link CoalesceVar $CO}
+ * {@link EnvVariablesVar $E}
+ * {@link FileVar $F}
+ * {@link ServletInitParamVar $I},
+ * {@link IfVar $IF}
+ * {@link LocalizationVar $L}
+ * {@link RequestAttributeVar $RA}
+ * {@link RequestFormDataVar $RF}
+ * {@link RequestHeaderVar $RH}
+ * {@link RequestPathVar $RP}
+ * {@link RequestQueryVar $RQ}
+ * {@link RequestVar $R}
+ * {@link SystemPropertiesVar $S}
+ * {@link SerializedRequestAttrVar $SA}
+ * {@link SwitchVar $SW}
+ * {@link UrlVar $U}
+ * {@link UrlEncodeVar $UE}
+ * {@link WidgetVar $W}
+ *
+ * <p>
+ * Corresponds to the swagger field <code>/info/contact</code>.
+ */
+ String[] contact() default {};
+
+ /**
+ * Optional external documentation information for the exposed API.
+ *
+ * <p>
+ * It is used to populate the Swagger external documentation field and to display on HTML pages.
+ *
+ * <p>
+ * A simplified JSON string with the following fields:
+ * <p class='bcode'>
+ * {
+ * description: string,
+ * url: string
+ * }
+ * </p>
+ *
+ * <p>
+ * The default value pulls the description from the <code>externalDocs</code> entry in the servlet resource bundle.
+ * (e.g. <js>"externalDocs = {url:'http://juneau.apache.org'}"</js> or
+ * <js>"MyServlet.externalDocs = {url:'http://juneau.apache.org'}"</js>).
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestResource</ja>(
+ * swagger=<ja>@MethodSwagger</ja>(
+ * externalDocs=<js>"{url:'http://juneau.apache.org'}"</js>
+ * )
+ * )
+ * </p>
+ *
+ * <p>
+ * Value can contain any of the following variables:
+ * {@link ConfigVar $C}
+ * {@link CoalesceVar $CO}
+ * {@link EnvVariablesVar $E}
+ * {@link FileVar $F}
+ * {@link ServletInitParamVar $I},
+ * {@link IfVar $IF}
+ * {@link LocalizationVar $L}
+ * {@link RequestAttributeVar $RA}
+ * {@link RequestFormDataVar $RF}
+ * {@link RequestHeaderVar $RH}
+ * {@link RequestPathVar $RP}
+ * {@link RequestQueryVar $RQ}
+ * {@link RequestVar $R}
+ * {@link SystemPropertiesVar $S}
+ * {@link SerializedRequestAttrVar $SA}
+ * {@link SwitchVar $SW}
+ * {@link UrlVar $U}
+ * {@link UrlEncodeVar $UE}
+ * {@link WidgetVar $W}
+ *
+ * <p>
+ * Corresponds to the swagger field <code>/tags</code>.
+ */
+ String[] externalDocs() default {};
+
+ /**
+ * Optional license information for the exposed API.
+ *
+ * <p>
+ * It is used to populate the Swagger license field and to display on HTML pages.
+ *
+ * <p>
+ * A simplified JSON string with the following fields:
+ * <p class='bcode'>
+ * {
+ * name: string,
+ * url: string
+ * }
+ * </p>
+ *
+ * <p>
+ * The default value pulls the description from the <code>license</code> entry in the servlet resource bundle.
+ * (e.g. <js>"license = {name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js> or
+ * <js>"MyServlet.license = {name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js>).
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestResource</ja>(
+ * swagger=<ja>@MethodSwagger</ja>(
+ * license=<js>"{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js>
+ * )
+ * )
+ * </p>
+ *
+ * <p>
+ * Value can contain any of the following variables:
+ * {@link ConfigVar $C}
+ * {@link CoalesceVar $CO}
+ * {@link EnvVariablesVar $E}
+ * {@link FileVar $F}
+ * {@link ServletInitParamVar $I},
+ * {@link IfVar $IF}
+ * {@link LocalizationVar $L}
+ * {@link RequestAttributeVar $RA}
+ * {@link RequestFormDataVar $RF}
+ * {@link RequestHeaderVar $RH}
+ * {@link RequestPathVar $RP}
+ * {@link RequestQueryVar $RQ}
+ * {@link RequestVar $R}
+ * {@link SystemPropertiesVar $S}
+ * {@link SerializedRequestAttrVar $SA}
+ * {@link SwitchVar $SW}
+ * {@link UrlVar $U}
+ * {@link UrlEncodeVar $UE}
+ * {@link WidgetVar $W}
+ *
+ * <p>
+ * Corresponds to the swagger field <code>/info/license</code>.
+ */
+ String[] license() default {};
+
+ /**
+ * Optional tagging information for the exposed API.
+ *
+ * <p>
+ * It is used to populate the Swagger tags field and to display on HTML pages.
+ *
+ * <p>
+ * A simplified JSON string with the following fields:
+ * <p class='bcode'>
+ * [
+ * {
+ * name: string,
+ * description: string,
+ * externalDocs: {
+ * description: string,
+ * url: string
+ * }
+ * }
+ * ]
+ * </p>
+ *
+ * <p>
+ * The default value pulls the description from the <code>tags</code> entry in the servlet resource bundle.
+ * (e.g. <js>"tags = [{name:'Foo',description:'Foobar'}]"</js> or
+ * <js>"MyServlet.tags = [{name:'Foo',description:'Foobar'}]"</js>).
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <ja>@RestResource</ja>(
+ * swagger=<ja>@MethodSwagger</ja>(
+ * tags=<js>"[{name:'Foo',description:'Foobar'}]"</js>
+ * )
+ * )
+ * </p>
+ *
+ * <p>
+ * Value can contain any of the following variables:
+ * {@link ConfigVar $C}
+ * {@link CoalesceVar $CO}
+ * {@link EnvVariablesVar $E}
+ * {@link FileVar $F}
+ * {@link ServletInitParamVar $I},
+ * {@link IfVar $IF}
+ * {@link LocalizationVar $L}
+ * {@link RequestAttributeVar $RA}
+ * {@link RequestFormDataVar $RF}
+ * {@link RequestHeaderVar $RH}
+ * {@link RequestPathVar $RP}
+ * {@link RequestQueryVar $RQ}
+ * {@link RequestVar $R}
+ * {@link SystemPropertiesVar $S}
+ * {@link SerializedRequestAttrVar $SA}
+ * {@link SwitchVar $SW}
+ * {@link UrlVar $U}
+ * {@link UrlEncodeVar $UE}
+ * {@link WidgetVar $W}
+ *
+ * <p>
+ * Corresponds to the swagger field <code>/tags</code>.
+ */
+ String[] tags() default {};
+
+ /**
+ * Optional servlet terms-of-service for this API.
+ *
+ * <p>
+ * It is used to populate the Swagger terms-of-service field.
+ *
+ * <p>
+ * The default value pulls the description from the <code>termsOfService</code> entry in the servlet resource bundle.
+ * (e.g. <js>"termsOfService = foo"</js> or <js>"MyServlet.termsOfService = foo"</js>).
+ *
+ * <p>
+ * Value can contain any of the following variables:
+ * {@link ConfigVar $C}
+ * {@link CoalesceVar $CO}
+ * {@link EnvVariablesVar $E}
+ * {@link FileVar $F}
+ * {@link ServletInitParamVar $I},
+ * {@link IfVar $IF}
+ * {@link LocalizationVar $L}
+ * {@link RequestAttributeVar $RA}
+ * {@link RequestFormDataVar $RF}
+ * {@link RequestHeaderVar $RH}
+ * {@link RequestPathVar $RP}
+ * {@link RequestQueryVar $RQ}
+ * {@link RequestVar $R}
+ * {@link SystemPropertiesVar $S}
+ * {@link SerializedRequestAttrVar $SA}
+ * {@link SwitchVar $SW}
+ * {@link UrlVar $U}
+ * {@link UrlEncodeVar $UE}
+ * {@link WidgetVar $W}
+ *
+ * <p>
+ * Corresponds to the swagger field <code>/info/termsOfService</code>.
+ */
+ String[] termsOfService() default {};
+
+ /**
+ * Provides the version of the application API (not to be confused with the specification version).
+ *
+ * <p>
+ * It is used to populate the Swagger version field and to display on HTML pages.
+ *
+ * <p>
+ * The default value pulls the description from the <code>version</code> entry in the servlet resource bundle.
+ * (e.g. <js>"version = 2.0"</js> or <js>"MyServlet.version = 2.0"</js>).
+ *
+ * <p>
+ * Value can contain any of the following variables:
+ * {@link ConfigVar $C}
+ * {@link CoalesceVar $CO}
+ * {@link EnvVariablesVar $E}
+ * {@link FileVar $F}
+ * {@link ServletInitParamVar $I},
+ * {@link IfVar $IF}
+ * {@link LocalizationVar $L}
+ * {@link RequestAttributeVar $RA}
+ * {@link RequestFormDataVar $RF}
+ * {@link RequestHeaderVar $RH}
+ * {@link RequestPathVar $RP}
+ * {@link RequestQueryVar $RQ}
+ * {@link RequestVar $R}
+ * {@link SystemPropertiesVar $S}
+ * {@link SerializedRequestAttrVar $SA}
+ * {@link SwitchVar $SW}
+ * {@link UrlVar $U}
+ * {@link UrlEncodeVar $UE}
+ * {@link WidgetVar $W}
+ *
+ * <p>
+ * Corresponds to the swagger field <code>/info/version</code>.
+ */
+ String version() default "";
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
index 6d34b0c..cae82b4 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethod.java
@@ -766,11 +766,12 @@ public @interface RestMethod {
* }
* )
* </p>
+ * {@link TODO}
*
* <h5 class='section'>See Also:</h5>
* <ul>
* <li class='jm'>{@link RestInfoProvider#getSwagger(RestRequest)}
* </ul>
*/
- String[] swagger() default {};
+ MethodSwagger swagger() default @MethodSwagger;
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
index c2b3470..1263201 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
@@ -859,13 +859,14 @@ public @interface RestResource {
* }
* )
* </p>
+ * {@link TODO}
*
* <h5 class='section'>See Also:</h5>
* <ul>
* <li class='jm'>{@link RestInfoProvider#getSwagger(RestRequest)}
* </ul>
*/
- String[] swagger() default {};
+ ResourceSwagger swagger() default @ResourceSwagger;
/**
* Optional servlet title.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
index df36c7e..7c86e38 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
@@ -165,8 +165,8 @@ public abstract class RemoteableServlet extends BasicRestServlet {
"<h5>Method: $RP{javaMethod}</h5>"
}
),
- swagger= {
- "parameters: [",
+ swagger=@MethodSwagger(
+ parameters= {
"{",
"in: 'body',",
"description: 'Serialized array of Java objects',",
@@ -176,12 +176,12 @@ public abstract class RemoteableServlet extends BasicRestServlet {
"x-examples: {",
"'application/json+lax': '[\\'foo\\', 123, true]'",
"}",
- "}",
- "],",
- "responses:{",
+ "}"
+ },
+ responses= {
"200:{ description:'The return object serialized', schema:{type:'any'},'x-example':{foo:123} }",
- "}"
- }
+ }
+ )
)
public Object invoke(
Reader r,
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
index 0a5245c..9cad6ea 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
@@ -19,6 +19,7 @@ import org.apache.juneau.http.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.exception.*;
+import org.apache.juneau.rest.util.*;
import org.apache.juneau.serializer.*;
/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/BoundedServletInputStream.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/BoundedServletInputStream.java
new file mode 100644
index 0000000..0792fe4
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/BoundedServletInputStream.java
@@ -0,0 +1,144 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.rest.util;
+
+import java.io.*;
+
+import javax.servlet.*;
+
+/**
+ * ServletInputStream wrapper around a normal input stream with support for limiting input.
+ */
+public final class BoundedServletInputStream extends ServletInputStream {
+
+ private final InputStream is;
+ private final ServletInputStream sis;
+ private long remain;
+
+ /**
+ * Wraps the specified input stream.
+ *
+ * @param is The input stream to wrap.
+ * @param max The maximum number of bytes to read from the stream.
+ */
+ public BoundedServletInputStream(InputStream is, long max) {
+ this.is = is;
+ this.sis = null;
+ this.remain = max;
+ }
+
+ /**
+ * Wraps the specified input stream.
+ *
+ * @param sis The input stream to wrap.
+ * @param max The maximum number of bytes to read from the stream.
+ */
+ public BoundedServletInputStream(ServletInputStream sis, long max) {
+ this.sis = sis;
+ this.is = sis;
+ this.remain = max;
+ }
+
+ /**
+ * Wraps the specified byte array.
+ *
+ * @param b The byte contents of the stream.
+ */
+ public BoundedServletInputStream(byte[] b) {
+ this(new ByteArrayInputStream(b), Long.MAX_VALUE);
+ }
+
+ @Override /* InputStream */
+ public final int read() throws IOException {
+ decrement();
+ return is.read();
+ }
+
+ @Override /* InputStream */
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ @Override /* InputStream */
+ public int read(final byte[] b, final int off, final int len) throws IOException {
+ long numBytes = Math.min(len, remain);
+ int r = is.read(b, off, (int) numBytes);
+ if (r == -1)
+ return -1;
+ decrement(numBytes);
+ return r;
+ }
+
+ @Override /* InputStream */
+ public long skip(final long n) throws IOException {
+ long toSkip = Math.min(n, remain);
+ long r = is.skip(toSkip);
+ decrement(r);
+ return r;
+ }
+
+ @Override /* InputStream */
+ public int available() throws IOException {
+ if (remain <= 0)
+ return 0;
+ return is.available();
+ }
+
+ @Override /* InputStream */
+ public synchronized void reset() throws IOException {
+ is.reset();
+ }
+
+ @Override /* InputStream */
+ public synchronized void mark(int limit) {
+ is.mark(limit);
+ }
+
+ @Override /* InputStream */
+ public boolean markSupported() {
+ return is.markSupported();
+ }
+
+ @Override /* InputStream */
+ public final void close() throws IOException {
+ is.close();
+ }
+
+ @Override /* ServletInputStream */
+ public boolean isFinished() {
+ return sis == null ? false : sis.isFinished();
+ }
+
+ @Override /* ServletInputStream */
+ public boolean isReady() {
+ return sis == null ? true : sis.isReady();
+ }
+
+ @Override /* ServletInputStream */
+ public void setReadListener(ReadListener arg0) {
+ if (sis != null)
+ sis.setReadListener(arg0);
+ }
+
+ private void decrement() throws IOException {
+ remain--;
+ if (remain < 0)
+ throw new IOException("Input limit exceeded. See @RestResource.maxInput().");
+ }
+
+ private void decrement(long count) throws IOException {
+ remain -= count;
+ if (remain < 0)
+ throw new IOException("Input limit exceeded. See @RestResource.maxInput().");
+ }
+}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/FinishablePrintWriter.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/FinishablePrintWriter.java
similarity index 87%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/FinishablePrintWriter.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/FinishablePrintWriter.java
index 4af84f4..6d317c5 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/FinishablePrintWriter.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/FinishablePrintWriter.java
@@ -10,7 +10,7 @@
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
// * specific language governing permissions and limitations under the License. *
// ***************************************************************************************************************************
-package org.apache.juneau.rest;
+package org.apache.juneau.rest.util;
import java.io.*;
@@ -23,7 +23,14 @@ public class FinishablePrintWriter extends PrintWriter implements Finishable {
final Finishable f;
- FinishablePrintWriter(OutputStream out, String characterEncoding) throws IOException {
+ /**
+ * Constructor.
+ *
+ * @param out The wrapped output stream.
+ * @param characterEncoding The character encoding of the output stream.
+ * @throws IOException
+ */
+ public FinishablePrintWriter(OutputStream out, String characterEncoding) throws IOException {
super(new OutputStreamWriter(out, characterEncoding));
f = (out instanceof Finishable ? (Finishable)out : null);
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/FinishableServletOutputStream.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/FinishableServletOutputStream.java
similarity index 94%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/FinishableServletOutputStream.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/FinishableServletOutputStream.java
index 87e2044..d1417ee 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/FinishableServletOutputStream.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/FinishableServletOutputStream.java
@@ -10,7 +10,7 @@
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
// * specific language governing permissions and limitations under the License. *
// ***************************************************************************************************************************
-package org.apache.juneau.rest;
+package org.apache.juneau.rest.util;
import java.io.*;
@@ -27,7 +27,12 @@ public class FinishableServletOutputStream extends ServletOutputStream implement
final ServletOutputStream sos;
final Finishable f;
- FinishableServletOutputStream(OutputStream os) {
+ /**
+ * Constructor.
+ *
+ * @param os The wrapped output stream.
+ */
+ public FinishableServletOutputStream(OutputStream os) {
this.os = os;
this.sos = (os instanceof ServletOutputStream ? (ServletOutputStream)os : null);
this.f = (os instanceof Finishable ? (Finishable)os : null);
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockHttpServletRequest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockHttpServletRequest.java
new file mode 100644
index 0000000..40c9dec
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockHttpServletRequest.java
@@ -0,0 +1,799 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.rest.util;
+
+import java.io.*;
+import java.security.*;
+import java.util.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * An implementation of {@link HttpServletRequest} for testing purposes.
+ */
+public class MockHttpServletRequest implements HttpServletRequest {
+
+ private String method = "GET";
+ private Map<String,String[]> parameterMap = new LinkedHashMap<>();
+ private Map<String,String[]> headerMap = new LinkedHashMap<>();
+ private Map<String,Object> attributeMap = new LinkedHashMap<>();
+ private String characterEncoding = "UTF-8";
+ private byte[] body;
+ private String protocol = "HTTP/1.1";
+ private String scheme = "http";
+ private String serverName = "localhost";
+ private int serverPort = 8080;
+ private String remoteAddr = "";
+ private String remoteHost = "";
+ private Locale locale = Locale.ENGLISH;
+ private String realPath;
+ private int remotePort;
+ private String localName;
+ private String localAddr;
+ private int localPort;
+ private RequestDispatcher requestDispatcher;
+ private ServletContext servletContext;
+ private DispatcherType dispatcherType;
+ private String authType;
+ private Cookie[] cookies;
+ private String pathInfo;
+ private String pathTranslated;
+ private String contextPath;
+ private String queryString;
+ private String remoteUser;
+ private Principal userPrincipal;
+ private String requestedSessionId;
+ private String requestURI;
+ private String servletPath;
+ private HttpSession httpSession;
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The method name for this request.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest method(String value) {
+ this.method = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param name Query parameter name.
+ * @param value Query parameter values.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest param(String name, String[] value) {
+ this.parameterMap.put(name, value);
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param name Query parameter name.
+ * @param value Query parameter value.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest param(String name, String value) {
+ this.parameterMap.put(name, new String[] {value});
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param name Header name.
+ * @param value Header value.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest header(String name, String value) {
+ this.headerMap.put(name, new String[] {value});
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param name Request attribute name.
+ * @param value Request attribute value.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest attribute(String name, Object value) {
+ this.attributeMap.put(name, value);
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The body of the request.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest body(Object value) {
+ try {
+ if (value instanceof byte[])
+ this.body = (byte[])value;
+ if (value instanceof Reader)
+ this.body = IOUtils.read((Reader)value).getBytes();
+ if (value instanceof InputStream)
+ this.body = IOUtils.readBytes((InputStream)value, 1024);
+ if (value instanceof CharSequence)
+ this.body = ((CharSequence)value).toString().getBytes();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The character encoding.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest characterEncoding(String value) {
+ this.characterEncoding = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The protocol.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest protocol(String value) {
+ this.protocol = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The scheme.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest scheme(String value) {
+ this.scheme = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The server name.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest serverName(String value) {
+ this.serverName = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The server port.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest serverPort(int value) {
+ this.serverPort = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The remote address.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest remoteAddr(String value) {
+ this.remoteAddr = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The remote port.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest remoteHost(String value) {
+ this.remoteHost = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The locale.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest locale(Locale value) {
+ this.locale = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The real path.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest realPath(String value) {
+ this.realPath = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The remote port.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest remotePort(int value) {
+ this.remotePort = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The local name.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest localName(String value) {
+ this.localName = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The local address.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest localAddr(String value) {
+ this.localAddr = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The local port.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest localPort(int value) {
+ this.localPort = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The request dispatcher.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest requestDispatcher(RequestDispatcher value) {
+ this.requestDispatcher = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The servlet context.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest servletContext(ServletContext value) {
+ this.servletContext = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The dispatcher type.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest dispatcherType(DispatcherType value) {
+ this.dispatcherType = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The auth type.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest authType(String value) {
+ this.authType = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The cookies.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest cookies(Cookie[] value) {
+ this.cookies = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The path info.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest pathInfo(String value) {
+ this.pathInfo = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The path translated.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest pathTranslated(String value) {
+ this.pathTranslated = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The context path.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest contextPath(String value) {
+ this.contextPath = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The query string.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest queryString(String value) {
+ this.queryString = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The remote user.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest remoteUser(String value) {
+ this.remoteUser = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The user principal.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest userPrincipal(Principal value) {
+ this.userPrincipal = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The requested session ID.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest requestedSessionId(String value) {
+ this.requestedSessionId = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The request URI.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest requestURI(String value) {
+ this.requestURI = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The servlet path.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest servletPath(String value) {
+ this.servletPath = value;
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param value The HTTP session.
+ * @return This object (for method chaining).
+ */
+ public MockHttpServletRequest httpSession(HttpSession value) {
+ this.httpSession = value;
+ return this;
+ }
+
+ @Override /* HttpServletRequest */
+ public Object getAttribute(String name) {
+ return attributeMap.get(name);
+ }
+
+ @Override /* HttpServletRequest */
+ public Enumeration<String> getAttributeNames() {
+ return Collections.enumeration(attributeMap.keySet());
+ }
+
+ @Override /* HttpServletRequest */
+ public String getCharacterEncoding() {
+ return characterEncoding;
+ }
+
+ @Override /* HttpServletRequest */
+ public void setCharacterEncoding(String characterEncoding) throws UnsupportedEncodingException {
+ this.characterEncoding = characterEncoding;
+ }
+
+ @Override /* HttpServletRequest */
+ public int getContentLength() {
+ return body == null ? 0 : body.length;
+ }
+
+ @Override /* HttpServletRequest */
+ public long getContentLengthLong() {
+ return body == null ? 0 : body.length;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getContentType() {
+ return getHeader("Content-Type");
+ }
+
+ @Override /* HttpServletRequest */
+ public ServletInputStream getInputStream() throws IOException {
+ return new BoundedServletInputStream(new ByteArrayInputStream(body), Integer.MAX_VALUE);
+ }
+
+ @Override /* HttpServletRequest */
+ public String getParameter(String name) {
+ String[] s = parameterMap.get(name);
+ return s == null || s.length == 0 ? null : s[0];
+ }
+
+ @Override /* HttpServletRequest */
+ public Enumeration<String> getParameterNames() {
+ return Collections.enumeration(new ArrayList<>(parameterMap.keySet()));
+ }
+
+ @Override /* HttpServletRequest */
+ public String[] getParameterValues(String name) {
+ return parameterMap.get(name);
+ }
+
+ @Override /* HttpServletRequest */
+ public Map<String,String[]> getParameterMap() {
+ return parameterMap;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getProtocol() {
+ return protocol;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getScheme() {
+ return scheme;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getServerName() {
+ return serverName;
+ }
+
+ @Override /* HttpServletRequest */
+ public int getServerPort() {
+ return serverPort;
+ }
+
+ @Override /* HttpServletRequest */
+ public BufferedReader getReader() throws IOException {
+ return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(body), characterEncoding));
+ }
+
+ @Override /* HttpServletRequest */
+ public String getRemoteAddr() {
+ return remoteAddr;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getRemoteHost() {
+ return remoteHost;
+ }
+
+ @Override /* HttpServletRequest */
+ public void setAttribute(String name, Object o) {
+ this.attributeMap.put(name, o);
+ }
+
+ @Override /* HttpServletRequest */
+ public void removeAttribute(String name) {
+ this.attributeMap.remove(name);
+ }
+
+ @Override /* HttpServletRequest */
+ public Locale getLocale() {
+ return locale;
+ }
+
+ @Override /* HttpServletRequest */
+ public Enumeration<Locale> getLocales() {
+ return Collections.enumeration(Arrays.asList(locale));
+ }
+
+ @Override /* HttpServletRequest */
+ public boolean isSecure() {
+ return false;
+ }
+
+ @Override /* HttpServletRequest */
+ public RequestDispatcher getRequestDispatcher(String path) {
+ return requestDispatcher;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getRealPath(String path) {
+ return realPath;
+ }
+
+ @Override /* HttpServletRequest */
+ public int getRemotePort() {
+ return remotePort;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getLocalName() {
+ return localName;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getLocalAddr() {
+ return localAddr;
+ }
+
+ @Override /* HttpServletRequest */
+ public int getLocalPort() {
+ return localPort;
+ }
+
+ @Override /* HttpServletRequest */
+ public ServletContext getServletContext() {
+ return servletContext;
+ }
+
+ @Override /* HttpServletRequest */
+ public AsyncContext startAsync() throws IllegalStateException {
+ return null;
+ }
+
+ @Override /* HttpServletRequest */
+ public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
+ return null;
+ }
+
+ @Override /* HttpServletRequest */
+ public boolean isAsyncStarted() {
+ return false;
+ }
+
+ @Override /* HttpServletRequest */
+ public boolean isAsyncSupported() {
+ return false;
+ }
+
+ @Override /* HttpServletRequest */
+ public AsyncContext getAsyncContext() {
+ return null;
+ }
+
+ @Override /* HttpServletRequest */
+ public DispatcherType getDispatcherType() {
+ return dispatcherType;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getAuthType() {
+ return authType;
+ }
+
+ @Override /* HttpServletRequest */
+ public Cookie[] getCookies() {
+ return cookies;
+ }
+
+ @Override /* HttpServletRequest */
+ public long getDateHeader(String name) {
+ String s = getHeader(name);
+ return s == null ? 0 : org.apache.juneau.http.Date.forString(s).asDate().getTime();
+ }
+
+ @Override /* HttpServletRequest */
+ public String getHeader(String name) {
+ String[] s = headerMap.get(name);
+ return s == null || s.length == 0 ? null : s[0];
+ }
+
+ @Override /* HttpServletRequest */
+ public Enumeration<String> getHeaders(String name) {
+ String[] s = headerMap.get(name);
+ return Collections.enumeration(Arrays.asList(s == null ? new String[0] : s));
+ }
+
+ @Override /* HttpServletRequest */
+ public Enumeration<String> getHeaderNames() {
+ return Collections.enumeration(headerMap.keySet());
+ }
+
+ @Override /* HttpServletRequest */
+ public int getIntHeader(String name) {
+ String s = getHeader(name);
+ return s == null || s.isEmpty() ? 0 : Integer.parseInt(s);
+ }
+
+ @Override /* HttpServletRequest */
+ public String getMethod() {
+ return method;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getPathInfo() {
+ return pathInfo;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getPathTranslated() {
+ return pathTranslated;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getQueryString() {
+ return queryString;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getRemoteUser() {
+ return remoteUser;
+ }
+
+ @Override /* HttpServletRequest */
+ public boolean isUserInRole(String role) {
+ return false;
+ }
+
+ @Override /* HttpServletRequest */
+ public Principal getUserPrincipal() {
+ return userPrincipal;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getRequestedSessionId() {
+ return requestedSessionId;
+ }
+
+ @Override /* HttpServletRequest */
+ public String getRequestURI() {
+ return requestURI;
+ }
+
+ @Override /* HttpServletRequest */
+ public StringBuffer getRequestURL() {
+ return new StringBuffer(requestURI);
+ }
+
+ @Override /* HttpServletRequest */
+ public String getServletPath() {
+ return servletPath;
+ }
+
+ @Override /* HttpServletRequest */
+ public HttpSession getSession(boolean create) {
+ return httpSession;
+ }
+
+ @Override /* HttpServletRequest */
+ public HttpSession getSession() {
+ return httpSession;
+ }
+
+ @Override /* HttpServletRequest */
+ public String changeSessionId() {
+ return null;
+ }
+
+ @Override /* HttpServletRequest */
+ public boolean isRequestedSessionIdValid() {
+ return false;
+ }
+
+ @Override /* HttpServletRequest */
+ public boolean isRequestedSessionIdFromCookie() {
+ return false;
+ }
+
+ @Override /* HttpServletRequest */
+ public boolean isRequestedSessionIdFromURL() {
+ return false;
+ }
+
+ @Override /* HttpServletRequest */
+ public boolean isRequestedSessionIdFromUrl() {
+ return false;
+ }
+
+ @Override /* HttpServletRequest */
+ public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
+ return false;
+ }
+
+ @Override /* HttpServletRequest */
+ public void login(String username, String password) throws ServletException {
+ }
+
+ @Override /* HttpServletRequest */
+ public void logout() throws ServletException {
+ }
+
+ @Override /* HttpServletRequest */
+ public Collection<Part> getParts() throws IOException, ServletException {
+ return null;
+ }
+
+ @Override /* HttpServletRequest */
+ public Part getPart(String name) throws IOException, ServletException {
+ return null;
+ }
+
+ @Override /* HttpServletRequest */
+ public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
+ return null;
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockHttpServletResponse.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockHttpServletResponse.java
new file mode 100644
index 0000000..5e5fc60
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockHttpServletResponse.java
@@ -0,0 +1,240 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.rest.util;
+
+import java.io.*;
+import java.util.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.apache.juneau.internal.*;
+
+/**
+ * An implementation of {@link HttpServletResponse} for testing purposes.
+ */
+public class MockHttpServletResponse implements HttpServletResponse {
+
+ private String characterEncoding = "UTF-8";
+ private ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ private long contentLength = 0;
+ private int bufferSize = 0;
+ private Locale locale;
+ private int sc;
+ private String msg;
+ private Map<String,String[]> headerMap = new LinkedHashMap<>();
+
+ /**
+ * Returns the content length.
+ *
+ * @return The content length.
+ */
+ public long getContentLength() {
+ return contentLength;
+ }
+
+ /**
+ * Returns the response message.
+ *
+ * @return The response message.
+ */
+ public String getMessage() {
+ return msg;
+ }
+
+ @Override /* HttpServletResponse */
+ public String getCharacterEncoding() {
+ return characterEncoding ;
+ }
+
+ @Override /* HttpServletResponse */
+ public String getContentType() {
+ return getHeader("Content-Type");
+ }
+
+ @Override /* HttpServletResponse */
+ public ServletOutputStream getOutputStream() throws IOException {
+ return new FinishableServletOutputStream(baos);
+ }
+
+ @Override /* HttpServletResponse */
+ public PrintWriter getWriter() throws IOException {
+ return new PrintWriter(new OutputStreamWriter(getOutputStream(), characterEncoding));
+ }
+
+ @Override /* HttpServletResponse */
+ public void setCharacterEncoding(String charset) {
+ this.characterEncoding = charset;
+ }
+
+ @Override /* HttpServletResponse */
+ public void setContentLength(int len) {
+ this.contentLength = len;
+ }
+
+ @Override /* HttpServletResponse */
+ public void setContentLengthLong(long len) {
+ this.contentLength = len;
+ }
+
+ @Override /* HttpServletResponse */
+ public void setContentType(String type) {
+ setHeader("Content-Type", type);
+ }
+
+ @Override /* HttpServletResponse */
+ public void setBufferSize(int size) {
+ this.bufferSize = size;
+ }
+
+ @Override /* HttpServletResponse */
+ public int getBufferSize() {
+ return bufferSize;
+ }
+
+ @Override /* HttpServletResponse */
+ public void flushBuffer() throws IOException {
+ }
+
+ @Override /* HttpServletResponse */
+ public void resetBuffer() {
+ }
+
+ @Override /* HttpServletResponse */
+ public boolean isCommitted() {
+ return false;
+ }
+
+ @Override /* HttpServletResponse */
+ public void reset() {
+ }
+
+ @Override /* HttpServletResponse */
+ public void setLocale(Locale loc) {
+ this.locale = loc;
+ }
+
+ @Override /* HttpServletResponse */
+ public Locale getLocale() {
+ return locale;
+ }
+
+ @Override /* HttpServletResponse */
+ public void addCookie(Cookie cookie) {
+ }
+
+ @Override /* HttpServletResponse */
+ public boolean containsHeader(String name) {
+ return getHeader(name) != null;
+ }
+
+ @Override /* HttpServletResponse */
+ public String encodeURL(String url) {
+ return null;
+ }
+
+ @Override /* HttpServletResponse */
+ public String encodeRedirectURL(String url) {
+ return null;
+ }
+
+ @Override /* HttpServletResponse */
+ public String encodeUrl(String url) {
+ return null;
+ }
+
+ @Override /* HttpServletResponse */
+ public String encodeRedirectUrl(String url) {
+ return null;
+ }
+
+ @Override /* HttpServletResponse */
+ public void sendError(int sc, String msg) throws IOException {
+ this.sc = sc;
+ this.msg = msg;
+ }
+
+ @Override /* HttpServletResponse */
+ public void sendError(int sc) throws IOException {
+ this.sc = sc;
+ }
+
+ @Override /* HttpServletResponse */
+ public void sendRedirect(String location) throws IOException {
+ this.sc = 302;
+ headerMap.put("Location", new String[] {location});
+ }
+
+ @Override /* HttpServletResponse */
+ public void setDateHeader(String name, long date) {
+ headerMap.put(name, new String[] {DateUtils.formatDate(new Date(date), DateUtils.PATTERN_RFC1123)});
+ }
+
+ @Override /* HttpServletResponse */
+ public void addDateHeader(String name, long date) {
+ headerMap.put(name, new String[] {DateUtils.formatDate(new Date(date), DateUtils.PATTERN_RFC1123)});
+ }
+
+ @Override /* HttpServletResponse */
+ public void setHeader(String name, String value) {
+ headerMap.put(name, new String[] {value});
+ }
+
+ @Override /* HttpServletResponse */
+ public void addHeader(String name, String value) {
+ headerMap.put(name, new String[] {value});
+ }
+
+ @Override /* HttpServletResponse */
+ public void setIntHeader(String name, int value) {
+ headerMap.put(name, new String[] {String.valueOf(value)});
+ }
+
+ @Override /* HttpServletResponse */
+ public void addIntHeader(String name, int value) {
+ headerMap.put(name, new String[] {String.valueOf(value)});
+ }
+
+ @Override /* HttpServletResponse */
+ public void setStatus(int sc) {
+ this.sc = sc;
+ }
+
+ @Override /* HttpServletResponse */
+ public void setStatus(int sc, String sm) {
+ this.sc = sc;
+ this.msg = sm;
+ }
+
+ @Override /* HttpServletResponse */
+ public int getStatus() {
+ return sc;
+ }
+
+ @Override /* HttpServletResponse */
+ public String getHeader(String name) {
+ String[] s = headerMap.get(name);
+ return s == null || s.length == 0 ? null : s[0];
+ }
+
+ @Override /* HttpServletResponse */
+ public Collection<String> getHeaders(String name) {
+ String[] s = headerMap.get(name);
+ return s == null ? Collections.EMPTY_LIST : Arrays.asList(s);
+ }
+
+ @Override /* HttpServletResponse */
+ public Collection<String> getHeaderNames() {
+ return headerMap.keySet();
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestUtils.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/RestUtils.java
similarity index 94%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestUtils.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/RestUtils.java
index e3ee38c..14653c2 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestUtils.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/RestUtils.java
@@ -10,7 +10,7 @@
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
// * specific language governing permissions and limitations under the License. *
// ***************************************************************************************************************************
-package org.apache.juneau.rest;
+package org.apache.juneau.rest.util;
import static org.apache.juneau.internal.ArrayUtils.*;
import static org.apache.juneau.internal.StringUtils.*;
@@ -163,7 +163,13 @@ public final class RestUtils {
}
}
- static String[] parseHeader(String s) {
+ /**
+ * Parses HTTP header.
+ *
+ * @param s The string to parse.
+ * @return The parsed string.
+ */
+ public static String[] parseHeader(String s) {
int i = s.indexOf(':');
if (i == -1)
return null;
@@ -174,8 +180,11 @@ public final class RestUtils {
/**
* Parses key/value pairs separated by either : or =
+ *
+ * @param s The string to parse.
+ * @return The parsed string.
*/
- static String[] parseKeyValuePair(String s) {
+ public static String[] parseKeyValuePair(String s) {
int i = -1;
for (int j = 0; j < s.length() && i < 0; j++) {
char c = s.charAt(j);
--
To stop receiving notification emails like this one, please contact
jamesbognar@apache.org.