http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java ---------------------------------------------------------------------- diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java index 52af23f..7bc9449 100644 --- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java +++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java @@ -12,6 +12,8 @@ // *************************************************************************************************************************** package org.apache.juneau.rest.client; +import static org.apache.juneau.internal.StringUtils.*; + import java.io.*; import java.lang.reflect.*; import java.net.*; @@ -23,6 +25,7 @@ import java.util.regex.*; import org.apache.http.*; import org.apache.http.client.*; import org.apache.http.client.config.*; +import org.apache.http.client.entity.*; import org.apache.http.client.methods.*; import org.apache.http.client.utils.*; import org.apache.http.impl.client.*; @@ -78,9 +81,11 @@ public final class RestCall { private boolean isClosed = false; private boolean isFailed = false; private Object input; + private boolean hasInput; // input() was called, even if it's setting 'null'. private Serializer serializer; private Parser parser; private URIBuilder uriBuilder; + private NameValuePairs formData; /** * Constructs a REST call with the specified method name. @@ -164,57 +169,84 @@ public final class RestCall { } /** - * Adds a parameter to the URI query. + * Adds a query parameter to the URI query. * * @param name The parameter name. + * Can be null/blank if the value is a {@link Map} or {@link String}. * @param value The parameter value converted to a string using UON notation. + * Can also be a {@link Map} or {@link String} if the name is null/blank. + * If a {@link String} and the name is null/blank, then calls {@link URIBuilder#setCustomQuery(String)}. + * @param skipIfEmpty Don't add the pair if the value is empty. * @return This object (for method chaining). - * @throws RestCallException */ - public RestCall param(String name, Object value) throws RestCallException { - uriBuilder.addParameter(name, client.getUrlEncodingSerializer().serializeUrlPart(value)); + @SuppressWarnings("unchecked") + public RestCall query(String name, Object value, boolean skipIfEmpty) { + if (! isEmpty(name)) { + if (! (isEmpty(value) && skipIfEmpty)) + uriBuilder.addParameter(name, client.getUrlEncodingSerializer().serializePart(value, false, null)); + } else { + if (value instanceof String) { + String s = value.toString(); + if (! isEmpty(s)) + uriBuilder.setCustomQuery(s); + } else if (value instanceof Map) { + for (Map.Entry<String,Object> p : ((Map<String,Object>) value).entrySet()) + query(p.getKey(), p.getValue(), skipIfEmpty); + } else { + throw new RuntimeException("Invalid name passed to query(name,value,skipIfEmpty)."); + } + } return this; } /** - * Adds parameters to the URI query. + * Adds a query parameter to the URI query. + * + * @param name The parameter name. + * @param value The parameter value converted to a string using UON notation. + * @return This object (for method chaining). + * @throws RestCallException + */ + public RestCall query(String name, Object value) throws RestCallException { + return query(name, value, false); + } + + /** + * Adds query parameters to the URI query. * * @param params The parameters. Values are converted to a string using UON notation. * @return This object (for method chaining). * @throws RestCallException */ - public RestCall params(Map<String,Object> params) throws RestCallException { - for (Map.Entry<String,Object> p : params.entrySet()) - uriBuilder.addParameter(p.getKey(), client.getUrlEncodingSerializer().serializeUrlPart(p.getValue())); - return this; + public RestCall query(Map<String,Object> params) throws RestCallException { + return query(null, params); } /** - * Adds a parameter to the URI query if the parameter value is not <jk>null</jk>. + * Adds a query parameter to the URI query if the parameter value is not <jk>null</jk> or an empty string. + * <p> + * NE = "not empty" * * @param name The parameter name. * @param value The parameter value converted to a string using UON notation. * @return This object (for method chaining). * @throws RestCallException */ - public RestCall paramIfNN(String name, Object value) throws RestCallException { - if (value != null) - uriBuilder.addParameter(name, client.getUrlEncodingSerializer().serializeUrlPart(value)); - return this; + public RestCall queryIfNE(String name, Object value) throws RestCallException { + return query(name, value, true); } /** - * Adds a parameter to the URI query if the parameter value is not <jk>null</jk> or an empty string. + * Adds query parameters to the URI for any parameters that aren't null/empty. + * <p> + * NE = "not empty" * - * @param name The parameter name. - * @param value The parameter value converted to a string using UON notation. + * @param params The parameters. Values are converted to a string using UON notation. * @return This object (for method chaining). * @throws RestCallException */ - public RestCall paramIfNE(String name, Object value) throws RestCallException { - if (! StringUtils.isEmpty(value)) - uriBuilder.addParameter(name, client.getUrlEncodingSerializer().serializeUrlPart(value)); - return this; + public RestCall queryIfNE(Map<String,Object> params) throws RestCallException { + return query(null, params, true); } /** @@ -229,6 +261,99 @@ public final class RestCall { } /** + * Adds a form data pair to this request to perform a URL-encoded form post. + * + * @param name The parameter name. + * Can be null/blank if the value is a {@link Map} or {@link NameValuePairs}. + * @param value The parameter value converted to a string using UON notation. + * Can also be a {@link Map} or {@link NameValuePairs}. + * @param skipIfEmpty Don't add the pair if the value is empty. + * @return This object (for method chaining). + */ + @SuppressWarnings("unchecked") + public RestCall formData(String name, Object value, boolean skipIfEmpty) { + if (formData == null) + formData = new NameValuePairs(); + if (! isEmpty(name)) { + if (! (isEmpty(value) && skipIfEmpty)) + formData.add(new SerializedNameValuePair(name, value, client.getUrlEncodingSerializer())); + } else { + if (value instanceof NameValuePairs) { + formData.addAll((NameValuePairs)value); + } else if (value instanceof Map) { + for (Map.Entry<String,Object> p : ((Map<String,Object>) value).entrySet()) + formData(p.getKey(), p.getValue(), skipIfEmpty); + } else { + throw new RuntimeException("Invalid name passed to formData(name,value,skipIfEmpty)."); + } + } + return this; + } + + /** + * Adds a form data pair to this request to perform a URL-encoded form post. + * + * @param name The parameter name. + * Can be null/blank if the value is a {@link Map} or {@link NameValuePairs}. + * @param value The parameter value converted to a string using UON notation. + * Can also be a {@link Map} or {@link NameValuePairs}. + * @return This object (for method chaining). + * @throws RestCallException If name was null/blank and value wasn't a {@link Map} or {@link NameValuePairs}. + */ + public RestCall formData(String name, Object value) throws RestCallException { + return formData(name, value, false); + } + + /** + * Adds form data pairs to this request to perform a URL-encoded form post. + * + * @param nameValuePairs The name-value pairs of the request. + * @return This object (for method chaining). + * @throws RestCallException + */ + public RestCall formData(NameValuePairs nameValuePairs) throws RestCallException { + return formData(null, nameValuePairs); + } + + /** + * Adds form data pairs to this request to perform a URL-encoded form post. + * + * @param params The parameters. Values are converted to a string using UON notation. + * @return This object (for method chaining). + * @throws RestCallException If name was null/blank and value wasn't a {@link Map} or {@link NameValuePairs}. + */ + public RestCall formData(Map<String,Object> params) throws RestCallException { + return formData(null, params); + } + + /** + * Adds a form data pair to the request if the parameter value is not <jk>null</jk> or an empty string. + * <p> + * NE = "not empty" + * + * @param name The parameter name. + * @param value The parameter value converted to a string using UON notation. + * @return This object (for method chaining). + * @throws RestCallException + */ + public RestCall formDataIfNE(String name, Object value) throws RestCallException { + return formData(name, value, true); + } + + /** + * Adds form data parameters to the request for any parameters that aren't null/empty. + * <p> + * NE = "not empty" + * + * @param params The parameters. Values are converted to a string using UON notation. + * @return This object (for method chaining). + * @throws RestCallException + */ + public RestCall formDataIfNE(Map<String,Object> params) throws RestCallException { + return formData(null, params, true); + } + + /** * Sets the URI user info. * * @param userInfo The new URI user info. @@ -261,12 +386,14 @@ public final class RestCall { * <li>{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource. * <li>{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the {@link RestClient}. * <li>{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient. + * <li>{@link NameValuePairs} - Converted to a URL-encoded FORM post. * </ul> * @return This object (for method chaining). * @throws RestCallException If a retry was attempted, but the entity was not repeatable. */ public RestCall input(final Object input) throws RestCallException { this.input = input; + this.hasInput = true; return this; } @@ -302,19 +429,79 @@ public final class RestCall { //-------------------------------------------------------------------------------- /** - * Convenience method for setting a header value on the request. - * <p> - * Equivalent to calling <code>restCall.getRequest().setHeader(name, value.toString())</code>. + * Sets a header on the request. * * @param name The header name. + * The name can be null/empty if the value is a {@link Map}. * @param value The header value. + * @param skipIfEmpty Don't add the header if the name is null/empty. * @return This object (for method chaining). */ - public RestCall header(String name, Object value) { - request.setHeader(name, value.toString()); + @SuppressWarnings("unchecked") + public RestCall header(String name, Object value, boolean skipIfEmpty) { + if (! isEmpty(name)) { + if (! (isEmpty(value) && skipIfEmpty)) + request.setHeader(name, client.getUrlEncodingSerializer().serializePart(value, false, true)); + } else { + if (value instanceof Map) { + for (Map.Entry<String,Object> p : ((Map<String,Object>) value).entrySet()) + header(p.getKey(), p.getValue(), skipIfEmpty); + } else { + throw new RuntimeException("Invalid name passed to formData(name,value,skipIfEmpty)."); + } + } return this; } + + /** + * Sets a header on the request. + * + * @param name The header name. + * The name can be null/empty if the value is a {@link Map}. + * @param value The header value. + * @return This object (for method chaining). + */ + public RestCall header(String name, Object value) { + return header(name, value, false); + } + + /** + * Sets headers on the request. + * + * @param values The header values. + * @return This object (for method chaining). + */ + public RestCall headers(Map<String,Object> values) { + return header(null, values, false); + } + + /** + * Sets a header on the request if the value is not null/empty. + * <p> + * NE = "not empty" + * + * @param name The header name. + * The name can be null/empty if the value is a {@link Map}. + * @param value The header value. + * @return This object (for method chaining). + */ + public RestCall headerIfNE(String name, Object value) { + return header(name, value, true); + } + + /** + * Sets headers on the request if the values are not null/empty. + * <p> + * NE = "not empty" + * + * @param values The header values. + * @return This object (for method chaining). + */ + public RestCall headersIfNE(Map<String,Object> values) { + return header(null, values, true); + } + /** * Sets the value for the <code>Accept</code> request header. * <p> @@ -1082,13 +1269,28 @@ public final class RestCall { request.setURI(uriBuilder.build()); - if (input != null) { + if (hasInput || formData != null) { + + if (hasInput && formData != null) + throw new RestCallException("Both input and form data found on same request."); + if (! (request instanceof HttpEntityEnclosingRequestBase)) throw new RestCallException(0, "Method does not support content entity.", request.getMethod(), request.getURI(), null); - HttpEntity entity = (input instanceof HttpEntity) ? (HttpEntity)input : new RestRequestEntity(input, getSerializer()); - ((HttpEntityEnclosingRequestBase)request).setEntity(entity); + + HttpEntity entity = null; + if (formData != null) + entity = new UrlEncodedFormEntity(formData); + else if (input instanceof NameValuePairs) + entity = new UrlEncodedFormEntity((NameValuePairs)input); + else if (input instanceof HttpEntity) + entity = (HttpEntity)input; + else + entity = new RestRequestEntity(input, getSerializer()); + if (retries > 1 && ! entity.isRepeatable()) throw new RestCallException("Rest call set to retryable, but entity is not repeatable."); + + ((HttpEntityEnclosingRequestBase)request).setEntity(entity); } int sc = 0; @@ -1104,7 +1306,7 @@ public final class RestCall { if (response != null) EntityUtils.consumeQuietly(response.getEntity()); } - if (! retryOn.onCode(sc)) + if (! retryOn.onResponse(response)) retries = 0; if (retries > 0) { for (RestCallInterceptor rci : interceptors) @@ -1360,6 +1562,16 @@ public final class RestCall { * <jc>// Parse into a map of object keys/values.</jc> * Map m = restClient.doGet(url).getResponse(TreeMap.<jk>class</jk>); * </p> + * <p> + * <h5 class='section'>Notes:</h5> + * <ul> + * <li>You can also specify any of the following types: + * <ul> + * <li>{@link HttpResponse} - Returns the raw <code>HttpResponse</code> returned by the inner <code>HttpClient</code>. + * <li>{@link Reader} - Returns access to the raw reader of the response. + * <li>{@link InputStream} - Returns access to the raw input stream of the response. + * </ul> + * </ul> * * @param <T> The class type of the object being created. * See {@link #getResponse(Type, Type...)} for details. @@ -1427,6 +1639,12 @@ public final class RestCall { * <h5 class='section'>Notes:</h5> * <ul> * <li>Use the {@link #getResponse(Class)} method instead if you don't need a parameterized map/collection. + * <li>You can also specify any of the following types: + * <ul> + * <li>{@link HttpResponse} - Returns the raw <code>HttpResponse</code> returned by the inner <code>HttpClient</code>. + * <li>{@link Reader} - Returns access to the raw reader of the response. + * <li>{@link InputStream} - Returns access to the raw input stream of the response. + * </ul> * </ul> * * @param <T> The class type of the object to create. @@ -1500,8 +1718,15 @@ public final class RestCall { return getResponsePojoRest(ObjectMap.class); } + @SuppressWarnings("unchecked") <T> T getResponse(ClassMeta<T> type) throws IOException, ParseException { try { + if (type.getInnerClass().equals(HttpResponse.class)) + return (T)response; + if (type.getInnerClass().equals(Reader.class)) + return (T)getReader(); + if (type.getInnerClass().equals(InputStream.class)) + return (T)getInputStream(); Parser p = getParser(); T o = null; if (! p.isReaderParser()) {
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java ---------------------------------------------------------------------- diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java index df91067..e5f9a32 100644 --- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java +++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java @@ -12,6 +12,8 @@ // *************************************************************************************************************************** package org.apache.juneau.rest.client; +import static org.apache.juneau.internal.StringUtils.*; + import java.io.*; import java.lang.reflect.*; import java.lang.reflect.Proxy; @@ -29,6 +31,7 @@ import org.apache.juneau.*; import org.apache.juneau.internal.*; import org.apache.juneau.json.*; import org.apache.juneau.parser.*; +import org.apache.juneau.remoteable.*; import org.apache.juneau.serializer.*; import org.apache.juneau.urlencoding.*; @@ -55,7 +58,6 @@ public class RestClient extends CoreObject { private final CloseableHttpClient httpClient; private final boolean keepHttpClientOpen; private final UrlEncodingSerializer urlEncodingSerializer; // Used for form posts only. - private final String remoteableServletUri; private final String rootUrl; private volatile boolean isClosed = false; private final StackTraceElement[] creationStack; @@ -84,7 +86,6 @@ public class RestClient extends CoreObject { UrlEncodingSerializer urlEncodingSerializer, Map<String,String> headers, List<RestCallInterceptor> interceptors, - String remoteableServletUri, String rootUri, RetryOn retryOn, int retries, @@ -102,7 +103,6 @@ public class RestClient extends CoreObject { Map<String,String> h2 = new ConcurrentHashMap<String,String>(headers); this.headers = Collections.unmodifiableMap(h2); - this.remoteableServletUri = remoteableServletUri; this.rootUrl = rootUri; this.retryOn = retryOn; this.retries = retries; @@ -220,6 +220,21 @@ public class RestClient extends CoreObject { } /** + * Same as {@link #doPost(Object, Object)} but don't specify the input yet. + * <p> + * You must call either {@link RestCall#input(Object)} or {@link RestCall#formData(String, Object)} + * to set the contents on the result object. + * + * @param url The URL of the remote REST resource. Can be any of the following: {@link String}, {@link URI}, {@link URL}. + * @return A {@link RestCall} object that can be further tailored before executing the request + * and getting the response as a parsed object. + * @throws RestCallException + */ + public RestCall doPost(Object url) throws RestCallException { + return doCall("POST", url, true); + } + + /** * Perform a <code>DELETE</code> request against the specified URL. * * @param url The URL of the remote REST resource. Can be any of the following: {@link String}, {@link URI}, {@link URL}. @@ -337,6 +352,7 @@ public class RestClient extends CoreObject { * <li>{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource. * <li>{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the {@link RestClient}. * <li>{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient. + * <li>{@link NameValuePairs} - Converted to a URL-encoded FORM post. * </ul> * This parameter is IGNORED if {@link HttpMethod#hasContent()} is <jk>false</jk>. * @return A {@link RestCall} object that can be further tailored before executing the request @@ -405,64 +421,144 @@ public class RestClient extends CoreObject { } /** - * Create a new proxy interface for the specified remoteable service interface. + * Create a new proxy interface against a REST interface. + * <p> + * The URL to the REST interface is based on the following values: + * <ul> + * <li>The {@link Remoteable#path() @Remoteable.path()} annotation on the interface (<code>remoteable-path</code>). + * <li>The {@link RestClientBuilder#rootUrl(Object) rootUrl} on the client (<code>root-url</code>). + * <li>The fully-qualified class name of the interface (<code>class-name</code>). + * </ul> + * <p> + * The URL calculation is as follows: + * <ul> + * <li><code>remoteable-path</code> - If remoteable path is absolute. + * <li><code>root-url/remoteable-path</code> - If remoteable path is relative and root-url has been specified. + * <li><code>root-url/class-name</code> - If remoteable path is not specified. + * </ul> + * <p> + * If the information is not available to resolve to an absolute URL, a {@link RemoteableMetadataException} is thrown. + * <p> + * Examples: + * <p class='bcode'> + * <jk>package</jk> org.apache.foo; + * + * <ja>@Remoteable</ja>(path=<js>"http://hostname/resturl/myinterface1"</js>) + * <jk>public interface</jk> MyInterface1 { ... } + * + * <ja>@Remoteable</ja>(path=<js>"/myinterface2"</js>) + * <jk>public interface</jk> MyInterface2 { ... } + * + * <jk>public interface</jk> MyInterface3 { ... } + * + * <jc>// Resolves to "http://localhost/resturl/myinterface1"</jc> + * MyInterface1 i1 = <jk>new</jk> RestClientBuilder() + * .build() + * .getRemoteableProxy(MyInterface1.<jk>class</jk>); + * + * <jc>// Resolves to "http://hostname/resturl/myinterface2"</jc> + * MyInterface2 i2 = <jk>new</jk> RestClientBuilder() + * .rootUrl(<js>"http://hostname/resturl"</js>) + * .build() + * .getRemoteableProxy(MyInterface2.<jk>class</jk>); + * + * <jc>// Resolves to "http://hostname/resturl/org.apache.foo.MyInterface3"</jc> + * MyInterface3 i3 = <jk>new</jk> RestClientBuilder() + * .rootUrl(<js>"http://hostname/resturl"</js>) + * .build() + * .getRemoteableProxy(MyInterface3.<jk>class</jk>); + * </p> * * @param interfaceClass The interface to create a proxy for. * @return The new proxy interface. - * @throws RuntimeException If the Remotable service URI has not been specified on this - * client by calling {@link RestClientBuilder#remoteableServletUri(String)}. + * @throws RemoteableMetadataException If the REST URI cannot be determined based on the information given. */ public <T> T getRemoteableProxy(final Class<T> interfaceClass) { - if (remoteableServletUri == null) - throw new RuntimeException("Remoteable service URI has not been specified."); - return getRemoteableProxy(interfaceClass, remoteableServletUri + '/' + interfaceClass.getName()); + return getRemoteableProxy(interfaceClass, null); } /** - * Create a new proxy interface for the specified REST PROXY interface. + * Same as {@link #getRemoteableProxy(Class)} except explicitly specifies the URL of the REST interface. * * @param interfaceClass The interface to create a proxy for. - * @param proxyUrl The URL of the REST method annotated with <code><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</code>. + * @param restUrl The URL of the REST interface. * @return The new proxy interface. */ - public <T> T getRemoteableProxy(final Class<T> interfaceClass, final Object proxyUrl) { - return getRemoteableProxy(interfaceClass, proxyUrl, serializer, parser); + public <T> T getRemoteableProxy(final Class<T> interfaceClass, final Object restUrl) { + return getRemoteableProxy(interfaceClass, restUrl, serializer, parser); } /** * Same as {@link #getRemoteableProxy(Class, Object)} but allows you to override the serializer and parser used. * * @param interfaceClass The interface to create a proxy for. - * @param proxyUrl The URL of the REST method annotated with <code><ja>@RestMethod</ja>(name=<js>"PROXY"</js>)</code>. + * @param restUrl The URL of the REST interface. * @param serializer The serializer used to serialize POJOs to the body of the HTTP request. * @param parser The parser used to parse POJOs from the body of the HTTP response. * @return The new proxy interface. */ @SuppressWarnings({ "unchecked", "hiding" }) - public <T> T getRemoteableProxy(final Class<T> interfaceClass, final Object proxyUrl, final Serializer serializer, final Parser parser) { + public <T> T getRemoteableProxy(final Class<T> interfaceClass, Object restUrl, final Serializer serializer, final Parser parser) { + + if (restUrl == null) { + Remoteable r = ReflectionUtils.getAnnotation(Remoteable.class, interfaceClass); + + String path = r == null ? "" : trimSlashes(r.path()); + if (path.indexOf("://") == -1) { + if (path.isEmpty()) + path = interfaceClass.getName(); + if (rootUrl == null) + throw new RemoteableMetadataException(interfaceClass, "Root URI has not been specified. Cannot construct absolute path to remoteable proxy."); + path = trimSlashes(rootUrl) + '/' + path; + } + restUrl = path; + } + + final String restUrl2 = restUrl.toString(); + try { return (T)Proxy.newProxyInstance( interfaceClass.getClassLoader(), new Class[] { interfaceClass }, new InvocationHandler() { - final Map<Method,String> uriCache = new ConcurrentHashMap<Method,String>(); - final String uri = toURI(proxyUrl).toString(); + final RemoteableMeta rm = new RemoteableMeta(interfaceClass, restUrl2); @Override /* InvocationHandler */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + RemoteableMethodMeta rmm = rm.getMethodMeta(method); - // Constructing this string each time can be time consuming, so cache it. - String u = uriCache.get(method); - if (u == null) { - try { - u = uri + '/' + URLEncoder.encode(ClassUtils.getMethodSignature(method), "utf-8"); - } catch (UnsupportedEncodingException e) {} - uriCache.put(method, u); - } + if (rmm == null) + throw new RuntimeException("Method is not exposed as a remoteable method."); try { - return doPost(u, args).serializer(serializer).parser(parser).getResponse(method.getGenericReturnType()); + String url = rmm.getUrl(); + String httpMethod = rmm.getHttpMethod(); + RestCall rc = (httpMethod.equals("POST") ? doPost(url) : doGet(url)); + rc.serializer(serializer).parser(parser); + + for (RemoteMethodArg a : rmm.getQueryArgs()) + rc.query(a.name, args[a.index], a.skipIfNE); + + for (RemoteMethodArg a : rmm.getFormDataArgs()) + rc.formData(a.name, args[a.index], a.skipIfNE); + + for (RemoteMethodArg a : rmm.getHeaderArgs()) + rc.header(a.name, args[a.index], a.skipIfNE); + + if (rmm.getBodyArg() != null) + rc.input(args[rmm.getBodyArg()]); + + if (rmm.getOtherArgs().length > 0) { + Object[] otherArgs = new Object[rmm.getOtherArgs().length]; + int i = 0; + for (Integer otherArg : rmm.getOtherArgs()) + otherArgs[i++] = args[otherArg]; + rc.input(otherArgs); + } + + return rc.getResponse(method.getGenericReturnType()); + } catch (RestCallException e) { // Try to throw original exception if possible. e.throwServerException(interfaceClass.getClassLoader()); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java ---------------------------------------------------------------------- diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java index faea9f8..e3ffcc8 100644 --- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java +++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java @@ -67,7 +67,6 @@ public class RestClientBuilder extends CoreObjectBuilder { private List<RestCallInterceptor> interceptors = new ArrayList<RestCallInterceptor>(); - private String remoteableServletUri; private String rootUrl; private SSLOpts sslOpts; private boolean pooled; @@ -140,7 +139,7 @@ public class RestClientBuilder extends CoreObjectBuilder { UrlEncodingSerializer us = new SerializerBuilder(propertyStore).build(UrlEncodingSerializer.class); - return new RestClient(propertyStore, httpClient, keepHttpClientOpen, s, p, us, headers, interceptors, remoteableServletUri, rootUrl, retryOn, retries, retryInterval, debug, executorService, executorServiceShutdownOnClose); + return new RestClient(propertyStore, httpClient, keepHttpClientOpen, s, p, us, headers, interceptors, rootUrl, retryOn, retries, retryInterval, debug, executorService, executorServiceShutdownOnClose); } catch (Exception e) { throw new RuntimeException(e); } @@ -231,18 +230,6 @@ public class RestClientBuilder extends CoreObjectBuilder { } /** - * Sets the URI of the remoteable services REST servlet for invoking remoteable services. - * - * @param remoteableServletUri The URI of the REST resource implementing a remoteable services servlet. - * (typically an instance of <code>RemoteableServlet</code>). - * @return This object (for method chaining). - */ - public RestClientBuilder remoteableServletUri(String remoteableServletUri) { - this.remoteableServletUri = remoteableServletUri; - return this; - } - - /** * Set a root URL for this client. * <p> * When set, URL strings passed in through the various rest call methods (e.g. {@link RestClient#doGet(Object)} @@ -1064,6 +1051,31 @@ public class RestClientBuilder extends CoreObjectBuilder { return header("No-Trace", true); } + /** + * Sets the {@link UrlEncodingSerializerContext#URLENC_paramFormat} property on the URL-encoding serializers in this group. + * <p> + * This overrides the behavior of the URL-encoding serializer to quote and escape characters + * in query names and values that may be confused for UON notation (e.g. <js>"'(foo=123)'"</js>, <js>"'@(1,2,3)'"</js>). + * <p> + * + * @param value The new value for this property. + * @return This object (for method chaining). + * @see UrlEncodingSerializerContext#URLENC_paramFormat + */ + public RestClientBuilder paramFormat(String value) { + super.property(UrlEncodingSerializerContext.URLENC_paramFormat, value); + return this; + } + + /** + * Shortcut for calling <code>paramFormat(<js>"PLAINTEXT"</js>)</code>. + * + * @return This object (for method chaining). + */ + public RestClientBuilder plainTextParams() { + super.property(UrlEncodingSerializerContext.URLENC_paramFormat, "PLAINTEXT"); + return this; + } @Override /* CoreObjectBuilder */ public RestClientBuilder beansRequireDefaultConstructor(boolean value) { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java ---------------------------------------------------------------------- diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java index 712c043..96c10e6 100644 --- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java +++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java @@ -54,11 +54,13 @@ public final class RestRequestEntity extends BasicHttpEntity { } else if (! serializer.isWriterSerializer()) { OutputStreamSerializer s2 = (OutputStreamSerializer)serializer; s2.serialize(output, os); + os.flush(); os.close(); } else { Writer w = new OutputStreamWriter(os, IOUtils.UTF8); WriterSerializer s2 = (WriterSerializer)serializer; s2.serialize(output, w); + w.flush(); w.close(); } } catch (SerializeException e) { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java ---------------------------------------------------------------------- diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java index 6a1c542..6d225b0 100644 --- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java +++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java @@ -12,10 +12,16 @@ // *************************************************************************************************************************** package org.apache.juneau.rest.client; +import org.apache.http.*; + /** * Used to determine whether a request should be retried based on the HTTP response code. + * <p> + * Subclasses should override either the {@link #onCode(int)} method (if you only care about + * the HTTP status code) or {@link #onResponse(HttpResponse)} (if you want full access to + * the HTTP response object. */ -public interface RetryOn { +public abstract class RetryOn { /** * Default RetryOn that returns <jk>true</jk> of any HTTP response >= 400 is received. @@ -40,8 +46,20 @@ public interface RetryOn { /** * Subclasses should override this method to determine whether the HTTP response is retryable. * - * @param httpResponseCode The HTTP response code. + * @param response The HTTP response object. May be <jk>null</jk> if a connection could not be made. + * @return <jk>true</jk> if the specified response code is retryable. + */ + protected boolean onResponse(HttpResponse response) { + return onCode(response == null || response.getStatusLine() == null ? -1 : response.getStatusLine().getStatusCode()); + } + + /** + * Subclasses should override this method to determine whether the HTTP response is retryable. + * + * @param httpResponseCode The HTTP response code. <code>-1</code> if a connection could not be made. * @return <jk>true</jk> if the specified response code is retryable. */ - boolean onCode(int httpResponseCode); + protected boolean onCode(int httpResponseCode) { + return false; + } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java ---------------------------------------------------------------------- diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java index f90c393..11382a6 100644 --- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java +++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java @@ -12,13 +12,7 @@ // *************************************************************************************************************************** package org.apache.juneau.rest.client; -import static org.apache.juneau.uon.UonSerializerContext.*; - -import java.io.*; - import org.apache.http.*; -import org.apache.juneau.*; -import org.apache.juneau.uon.*; import org.apache.juneau.urlencoding.*; /** @@ -38,9 +32,6 @@ public final class SerializedNameValuePair implements NameValuePair { private Object value; private UrlEncodingSerializer serializer; - // We must be sure to disable character encoding since it's done in the http client layer. - private static final ObjectMap op = new ObjectMap().append(UON_encodeChars, false); - /** * Constructor. * @@ -56,29 +47,11 @@ public final class SerializedNameValuePair implements NameValuePair { @Override /* NameValuePair */ public String getName() { - if (name != null && name.length() > 0) { - char c = name.charAt(0); - if (c == '$' || c == '(') { - try { - UonSerializerSession s = serializer.createSession(new StringWriter(), op, null, null, null, MediaType.UON); - serializer.serialize(s, name); - return s.getWriter().toString(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - return name; + return serializer.serializePart(name, false, null); } @Override /* NameValuePair */ public String getValue() { - try { - UonSerializerSession s = serializer.createSession(new StringWriter(), op, null, null, null, MediaType.UON); - serializer.serialize(s, value); - return s.getWriter().toString(); - } catch (Exception e) { - throw new RuntimeException(e); - } + return serializer.serializePart(value, false, null); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html ---------------------------------------------------------------------- diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html index 5bc9368..0f685ef 100644 --- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html +++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html @@ -821,8 +821,6 @@ </p> <p> Proxy interfaces are retrieved using the {@link org.apache.juneau.rest.client.RestClient#getRemoteableProxy(Class)} method. - The {@link org.apache.juneau.rest.client.RestClientBuilder#remoteableServletUri(String)} method is used to specify the location - of the remoteable services servlet running on the server. The remoteable servlet is a specialized subclass of {@link org.apache.juneau.rest.RestServlet} that provides a full-blown REST interface for calling interfaces remotely. </p> @@ -840,7 +838,7 @@ <p class='bcode'> <jc>// Create a RestClient using JSON for serialization, and point to the server-side remoteable servlet.</jc> RestClient client = <jk>new</jk> RestClientBuilder() - .remoteableServletUri(<js>"https://localhost:9080/juneau/sample/remoteable"</js>) + .rootUrl(<js>"https://localhost:9080/juneau/sample/remoteable"</js>) .build(); <jc>// Create a proxy interface.</jc> http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/FormDataResource.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/FormDataResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/FormDataResource.java new file mode 100644 index 0000000..3bced3f --- /dev/null +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/FormDataResource.java @@ -0,0 +1,37 @@ +// *************************************************************************************************************************** +// * 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.test; + +import java.io.*; + +import org.apache.juneau.internal.*; +import org.apache.juneau.rest.*; +import org.apache.juneau.rest.annotation.*; + +/** + * JUnit automated testcase resource. + */ +@RestResource( + path="/testFormData" +) +public class FormDataResource extends RestServletDefault { + private static final long serialVersionUID = 1L; + + //==================================================================================================== + // Basic tests + //==================================================================================================== + @RestMethod(name="POST", path="/*") + public Reader test(RestRequest req) throws IOException { + return new StringReader("Content-Type=["+req.getContentType()+"], contents=["+IOUtils.read(req.getReader())+"]"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxy.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxy.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxy.java index 9f8da38..b2af7a6 100644 --- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxy.java +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxy.java @@ -14,15 +14,13 @@ package org.apache.juneau.rest.test; import java.util.*; -import org.apache.juneau.*; -import org.apache.juneau.annotation.*; -import org.apache.juneau.parser.*; -import org.apache.juneau.serializer.*; -import org.apache.juneau.transform.*; +import org.apache.juneau.remoteable.*; +import org.apache.juneau.rest.test.pojos.*; /** * Interface proxy exposed in InterfaceProxyResource and tested in InterfaceProxyTest. */ +@Remoteable public interface InterfaceProxy { public static final String SWAP = "swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/"; @@ -50,14 +48,14 @@ public interface InterfaceProxy { List<String> returnStringList(); // Beans - Bean returnBean(); - Bean[][][] returnBean3dArray(); - List<Bean> returnBeanList(); - List<Bean[][][]> returnBean1d3dList(); - Map<String,Bean> returnBeanMap(); - Map<String,List<Bean>> returnBeanListMap(); - Map<String,List<Bean[][][]>> returnBean1d3dListMap(); - Map<Integer,List<Bean>> returnBeanListMapIntegerKeys(); + ABean returnBean(); + ABean[][][] returnBean3dArray(); + List<ABean> returnBeanList(); + List<ABean[][][]> returnBean1d3dList(); + Map<String,ABean> returnBeanMap(); + Map<String,List<ABean>> returnBeanListMap(); + Map<String,List<ABean[][][]>> returnBean1d3dListMap(); + Map<Integer,List<ABean>> returnBeanListMapIntegerKeys(); // Typed beans TypedBean returnTypedBean(); @@ -121,14 +119,14 @@ public interface InterfaceProxy { void setStringList(List<String> x); // Beans - void setBean(Bean x); - void setBean3dArray(Bean[][][] x); - void setBeanList(List<Bean> x); - void setBean1d3dList(List<Bean[][][]> x); - void setBeanMap(Map<String,Bean> x); - void setBeanListMap(Map<String,List<Bean>> x); - void setBean1d3dListMap(Map<String,List<Bean[][][]>> x); - void setBeanListMapIntegerKeys(Map<Integer,List<Bean>> x); + void setBean(ABean x); + void setBean3dArray(ABean[][][] x); + void setBeanList(List<ABean> x); + void setBean1d3dList(List<ABean[][][]> x); + void setBeanMap(Map<String,ABean> x); + void setBeanListMap(Map<String,List<ABean>> x); + void setBean1d3dListMap(Map<String,List<ABean[][][]>> x); + void setBeanListMapIntegerKeys(Map<Integer,List<ABean>> x); // Typed beans void setTypedBean(TypedBean x); @@ -171,7 +169,7 @@ public interface InterfaceProxy { void setMultiParamsFloat(float x1, float[][][] x2, float[][][] x2n, List<float[][][]> x3, List<float[][][]> x3n); void setMultiParamsFloatObject(Float x1, Float x1n, Float[][][] x2, Float[][][] x2n, List<Float[][][]> x3, List<Float[][][]> x3n); void setMultiParamsString(String x1, String[][][] x2, String[][][] x2n, List<String[][][]> x3, List<String[][][]> x3n); - void setMultiParamsBean(Bean x1, Bean[][][] x2, Bean[][][] x2n, List<Bean[][][]> x3, List<Bean[][][]> x3n, Map<String,Bean> x4, Map<String,Bean> x4n, Map<String,List<Bean[][][]>> x5, Map<String,List<Bean[][][]>> x5n); + void setMultiParamsBean(ABean x1, ABean[][][] x2, ABean[][][] x2n, List<ABean[][][]> x3, List<ABean[][][]> x3n, Map<String,ABean> x4, Map<String,ABean> x4n, Map<String,List<ABean[][][]>> x5, Map<String,List<ABean[][][]>> x5n); void setMultiParamsSwappedPojo(SwappedPojo x1, SwappedPojo[][][] x2, SwappedPojo[][][] x2n, List<SwappedPojo[][][]> x3, List<SwappedPojo[][][]> x3n, Map<SwappedPojo,SwappedPojo> x4, Map<SwappedPojo,SwappedPojo> x4n, Map<SwappedPojo,List<SwappedPojo[][][]>> x5, Map<SwappedPojo,List<SwappedPojo[][][]>> x5n); void setMultiParamsImplicitSwappedPojo(ImplicitSwappedPojo x1, ImplicitSwappedPojo[][][] x2, ImplicitSwappedPojo[][][] x2n, List<ImplicitSwappedPojo[][][]> x3, List<ImplicitSwappedPojo[][][]> x3n, Map<ImplicitSwappedPojo,ImplicitSwappedPojo> x4, Map<ImplicitSwappedPojo,ImplicitSwappedPojo> x4n, Map<ImplicitSwappedPojo,List<ImplicitSwappedPojo[][][]>> x5, Map<ImplicitSwappedPojo,List<ImplicitSwappedPojo[][][]>> x5n); void setMultiParamsEnum(TestEnum x1, TestEnum[][][] x2, TestEnum[][][] x2n, List<TestEnum[][][]> x3, List<TestEnum[][][]> x3n, Map<TestEnum,TestEnum> x4, Map<TestEnum,TestEnum> x4n, Map<TestEnum,List<TestEnum[][][]>> x5, Map<TestEnum,List<TestEnum[][][]>> x5n); @@ -180,17 +178,6 @@ public interface InterfaceProxy { // Helper classes //-------------------------------------------------------------------------------- - public static class Bean { - public int a; - public String b; - - Bean init() { - this.a = 1; - this.b = "foo"; - return this; - } - } - @SuppressWarnings("serial") public static class InterfaceProxyException1 extends Throwable { public InterfaceProxyException1(String msg) { @@ -201,59 +188,4 @@ public interface InterfaceProxy { @SuppressWarnings("serial") public static class InterfaceProxyException2 extends Throwable { } - - @Pojo(swap=SwappedPojoSwap.class) - public static class SwappedPojo { - public boolean wasUnswapped; - } - - public static class SwappedPojoSwap extends PojoSwap<SwappedPojo,String> { - @Override - public String swap(BeanSession session, SwappedPojo c) throws SerializeException { - return SWAP; - } - - @Override - public SwappedPojo unswap(BeanSession session, String f, ClassMeta<?> hint) throws ParseException { - SwappedPojo c = new SwappedPojo(); - if (f.equals(SWAP)) - c.wasUnswapped = true; - return c; - } - } - - @BeanIgnore - public static class ImplicitSwappedPojo { - public boolean wasUnswapped; - @Override - public String toString() { - return SWAP; - } - public ImplicitSwappedPojo() { - } - public ImplicitSwappedPojo(String fromString) { - if (fromString.equals(SWAP)) - wasUnswapped = true; - } - } - - public static enum TestEnum { - ONE,TWO,THREE - } - - @org.apache.juneau.annotation.Bean(beanDictionary={TypedBeanImpl.class}) - public static interface TypedBean { - } - - @org.apache.juneau.annotation.Bean(typeName="TypedBeanImpl", sort=true) - public static class TypedBeanImpl implements TypedBean { - public int a; - public String b; - - public TypedBeanImpl init() { - this.a = 1; - this.b = "foo"; - return this; - } - } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxyResource.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxyResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxyResource.java index a5ade59..7b63d6f 100644 --- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxyResource.java +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InterfaceProxyResource.java @@ -13,6 +13,7 @@ package org.apache.juneau.rest.test; import static java.util.Arrays.*; +import static org.apache.juneau.rest.test.TestUtils.*; import static org.junit.Assert.*; import java.util.*; @@ -20,6 +21,7 @@ import java.util.*; import org.apache.juneau.json.*; import org.apache.juneau.rest.annotation.*; import org.apache.juneau.rest.jena.*; +import org.apache.juneau.rest.test.pojos.*; import org.apache.juneau.utils.*; import org.junit.*; @@ -43,53 +45,66 @@ public class InterfaceProxyResource extends RestServletJenaDefault { //-------------------------------------------------------------------------------- // Various primitives + @Override public void returnVoid() { } + @Override public Integer returnInteger() { return 1; } + @Override public int returnInt() { return 1; } + @Override public boolean returnBoolean() { return true; } + @Override public float returnFloat() { return 1f; } + @Override public Float returnFloatObject() { return 1f; } + @Override public String returnString() { return "foobar"; } + @Override public String returnNullString() { return null; } + @Override public int[][][] returnInt3dArray() { return new int[][][]{{{1,2},null},null}; } + @Override public Integer[][][] returnInteger3dArray() { return new Integer[][][]{{{1,null},null},null}; } + @Override public String[][][] returnString3dArray() { return new String[][][]{{{"foo","bar",null},null},null}; } + @Override public List<Integer> returnIntegerList() { return asList(new Integer[]{1,null}); } + @Override public List<List<List<Integer>>> returnInteger3dList() { return new AList<List<List<Integer>>>() @@ -102,136 +117,167 @@ public class InterfaceProxyResource extends RestServletJenaDefault { ) .append(null); } + @Override public List<Integer[][][]> returnInteger1d3dList() { return new AList<Integer[][][]>().append(new Integer[][][]{{{1,null},null},null}).append(null); } + @Override public List<int[][][]> returnInt1d3dList() { return new AList<int[][][]>().append(new int[][][]{{{1,2},null},null}).append(null); } + @Override public List<String> returnStringList() { return asList(new String[]{"foo","bar",null}); } // Beans + @Override - public Bean returnBean() { - return new Bean().init(); + public ABean returnBean() { + return new ABean().init(); } + @Override - public Bean[][][] returnBean3dArray() { - return new Bean[][][]{{{new Bean().init(),null},null},null}; + public ABean[][][] returnBean3dArray() { + return new ABean[][][]{{{new ABean().init(),null},null},null}; } + @Override - public List<Bean> returnBeanList() { - return asList(new Bean().init()); + public List<ABean> returnBeanList() { + return asList(new ABean().init()); } + @Override - public List<Bean[][][]> returnBean1d3dList() { - return new AList<Bean[][][]>().append(new Bean[][][]{{{new Bean().init(),null},null},null}).append(null); + public List<ABean[][][]> returnBean1d3dList() { + return new AList<ABean[][][]>().append(new ABean[][][]{{{new ABean().init(),null},null},null}).append(null); } + @Override - public Map<String,Bean> returnBeanMap() { - return new AMap<String,Bean>().append("foo",new Bean().init()); + public Map<String,ABean> returnBeanMap() { + return new AMap<String,ABean>().append("foo",new ABean().init()); } + @Override - public Map<String,List<Bean>> returnBeanListMap() { - return new AMap<String,List<Bean>>().append("foo",asList(new Bean().init())); + public Map<String,List<ABean>> returnBeanListMap() { + return new AMap<String,List<ABean>>().append("foo",asList(new ABean().init())); } + @Override - public Map<String,List<Bean[][][]>> returnBean1d3dListMap() { - return new AMap<String,List<Bean[][][]>>().append("foo", new AList<Bean[][][]>().append(new Bean[][][]{{{new Bean().init(),null},null},null}).append(null)); + public Map<String,List<ABean[][][]>> returnBean1d3dListMap() { + return new AMap<String,List<ABean[][][]>>().append("foo", new AList<ABean[][][]>().append(new ABean[][][]{{{new ABean().init(),null},null},null}).append(null)); } + @Override - public Map<Integer,List<Bean>> returnBeanListMapIntegerKeys() { - return new AMap<Integer,List<Bean>>().append(1,asList(new Bean().init())); + public Map<Integer,List<ABean>> returnBeanListMapIntegerKeys() { + return new AMap<Integer,List<ABean>>().append(1,asList(new ABean().init())); } // Typed beans + @Override public TypedBean returnTypedBean() { return new TypedBeanImpl().init(); } + @Override public TypedBean[][][] returnTypedBean3dArray() { return new TypedBean[][][]{{{new TypedBeanImpl().init(),null},null},null}; } + @Override public List<TypedBean> returnTypedBeanList() { return asList((TypedBean)new TypedBeanImpl().init()); } + @Override public List<TypedBean[][][]> returnTypedBean1d3dList() { return new AList<TypedBean[][][]>().append(new TypedBean[][][]{{{new TypedBeanImpl().init(),null},null},null}).append(null); } + @Override public Map<String,TypedBean> returnTypedBeanMap() { return new AMap<String,TypedBean>().append("foo",new TypedBeanImpl().init()); } + @Override public Map<String,List<TypedBean>> returnTypedBeanListMap() { return new AMap<String,List<TypedBean>>().append("foo",asList((TypedBean)new TypedBeanImpl().init())); } + @Override public Map<String,List<TypedBean[][][]>> returnTypedBean1d3dListMap() { return new AMap<String,List<TypedBean[][][]>>().append("foo", new AList<TypedBean[][][]>().append(new TypedBean[][][]{{{new TypedBeanImpl().init(),null},null},null}).append(null)); } + @Override public Map<Integer,List<TypedBean>> returnTypedBeanListMapIntegerKeys() { return new AMap<Integer,List<TypedBean>>().append(1,asList((TypedBean)new TypedBeanImpl().init())); } // Swapped POJOs + @Override public SwappedPojo returnSwappedPojo() { return new SwappedPojo(); } + @Override public SwappedPojo[][][] returnSwappedPojo3dArray() { return new SwappedPojo[][][]{{{new SwappedPojo(),null},null},null}; } + @Override public Map<SwappedPojo,SwappedPojo> returnSwappedPojoMap() { return new AMap<SwappedPojo,SwappedPojo>().append(new SwappedPojo(), new SwappedPojo()); } + @Override public Map<SwappedPojo,SwappedPojo[][][]> returnSwappedPojo3dMap() { return new AMap<SwappedPojo,SwappedPojo[][][]>().append(new SwappedPojo(), new SwappedPojo[][][]{{{new SwappedPojo(),null},null},null}); } // Implicit swapped POJOs + @Override public ImplicitSwappedPojo returnImplicitSwappedPojo() { return new ImplicitSwappedPojo(); } + @Override public ImplicitSwappedPojo[][][] returnImplicitSwappedPojo3dArray() { return new ImplicitSwappedPojo[][][]{{{new ImplicitSwappedPojo(),null},null},null}; } + @Override public Map<ImplicitSwappedPojo,ImplicitSwappedPojo> returnImplicitSwappedPojoMap() { return new AMap<ImplicitSwappedPojo,ImplicitSwappedPojo>().append(new ImplicitSwappedPojo(), new ImplicitSwappedPojo()); } + @Override public Map<ImplicitSwappedPojo,ImplicitSwappedPojo[][][]> returnImplicitSwappedPojo3dMap() { return new AMap<ImplicitSwappedPojo,ImplicitSwappedPojo[][][]>().append(new ImplicitSwappedPojo(), new ImplicitSwappedPojo[][][]{{{new ImplicitSwappedPojo(),null},null},null}); } // Enums + @Override public TestEnum returnEnum() { return TestEnum.TWO; } + @Override public TestEnum[][][] returnEnum3d() { return new TestEnum[][][]{{{TestEnum.TWO,null},null},null}; } + @Override public List<TestEnum> returnEnumList() { return new AList<TestEnum>().append(TestEnum.TWO).append(null); } + @Override public List<List<List<TestEnum>>> returnEnum3dList() { return new AList<List<List<TestEnum>>>() @@ -244,18 +290,22 @@ public class InterfaceProxyResource extends RestServletJenaDefault { .append(null) ); } + @Override public List<TestEnum[][][]> returnEnum1d3dList() { return new AList<TestEnum[][][]>().append(new TestEnum[][][]{{{TestEnum.TWO,null},null},null}).append(null); } + @Override public Map<TestEnum,TestEnum> returnEnumMap() { return new AMap<TestEnum,TestEnum>().append(TestEnum.ONE,TestEnum.TWO); } + @Override public Map<TestEnum,TestEnum[][][]> returnEnum3dArrayMap() { return new AMap<TestEnum,TestEnum[][][]>().append(TestEnum.ONE, new TestEnum[][][]{{{TestEnum.TWO,null},null},null}); } + @Override public Map<TestEnum,List<TestEnum[][][]>> returnEnum1d3dListMap() { return new AMap<TestEnum,List<TestEnum[][][]>>().append(TestEnum.ONE, new AList<TestEnum[][][]>().append(new TestEnum[][][]{{{TestEnum.TWO,null},null},null}).append(null)); @@ -269,6 +319,7 @@ public class InterfaceProxyResource extends RestServletJenaDefault { public void throwException1() throws InterfaceProxy.InterfaceProxyException1 { throw new InterfaceProxy.InterfaceProxyException1("foo"); } + @Override public void throwException2() throws InterfaceProxy.InterfaceProxyException2 { throw new InterfaceProxy.InterfaceProxyException2(); @@ -279,162 +330,197 @@ public class InterfaceProxyResource extends RestServletJenaDefault { //-------------------------------------------------------------------------------- // Various primitives + @Override public void setNothing() { } + @Override public void setInt(int x) { assertEquals(1, x); } + @Override public void setInteger(Integer x) { assertEquals((Integer)1, x); } + @Override public void setBoolean(boolean x) { assertTrue(x); } + @Override public void setFloat(float x) { assertTrue(1f == x); } + @Override public void setFloatObject(Float x) { assertTrue(1f == x); } + @Override public void setString(String x) { assertEquals("foo", x); } + @Override public void setNullString(String x) { assertNull(x); } + @Override public void setInt3dArray(int[][][] x) { assertObjectEquals("[[[1,2],null],null]", x); } + @Override public void setInteger3dArray(Integer[][][] x) { assertObjectEquals("[[[1,null],null],null]", x); } + @Override public void setString3dArray(String[][][] x) { assertObjectEquals("[[['foo',null],null],null]", x); } + @Override public void setIntegerList(List<Integer> x) { assertObjectEquals("[1,null]", x); - assertEquals(Integer.class, x.get(0).getClass()); + assertClass(Integer.class, x.get(0)); } + @Override public void setInteger3dList(List<List<List<Integer>>> x) { assertObjectEquals("[[[1,null],null],null]", x); - assertEquals(Integer.class, x.get(0).get(0).get(0).getClass()); + assertClass(Integer.class, x.get(0).get(0).get(0)); } + @Override public void setInteger1d3dList(List<Integer[][][]> x) { assertObjectEquals("[[[[1,null],null],null],null]", x); - assertEquals(Integer[][][].class, x.get(0).getClass()); - assertEquals(Integer.class, x.get(0)[0][0][0].getClass()); + assertClass(Integer[][][].class, x.get(0)); + assertClass(Integer.class, x.get(0)[0][0][0]); } + @Override public void setInt1d3dList(List<int[][][]> x) { assertObjectEquals("[[[[1,2],null],null],null]", x); - assertEquals(int[][][].class, x.get(0).getClass()); + assertClass(int[][][].class, x.get(0)); } + @Override public void setStringList(List<String> x) { assertObjectEquals("['foo','bar',null]", x); } // Beans + @Override - public void setBean(Bean x) { + public void setBean(ABean x) { assertObjectEquals("{a:1,b:'foo'}", x); } + @Override - public void setBean3dArray(Bean[][][] x) { + public void setBean3dArray(ABean[][][] x) { assertObjectEquals("[[[{a:1,b:'foo'},null],null],null]", x); } + @Override - public void setBeanList(List<Bean> x) { + public void setBeanList(List<ABean> x) { assertObjectEquals("[{a:1,b:'foo'}]", x); } + @Override - public void setBean1d3dList(List<Bean[][][]> x) { + public void setBean1d3dList(List<ABean[][][]> x) { assertObjectEquals("[[[[{a:1,b:'foo'},null],null],null],null]", x); } + @Override - public void setBeanMap(Map<String,Bean> x) { + public void setBeanMap(Map<String,ABean> x) { assertObjectEquals("{foo:{a:1,b:'foo'}}", x); } + @Override - public void setBeanListMap(Map<String,List<Bean>> x) { + public void setBeanListMap(Map<String,List<ABean>> x) { assertObjectEquals("{foo:[{a:1,b:'foo'}]}", x); } + @Override - public void setBean1d3dListMap(Map<String,List<Bean[][][]>> x) { + public void setBean1d3dListMap(Map<String,List<ABean[][][]>> x) { assertObjectEquals("{foo:[[[[{a:1,b:'foo'},null],null],null],null]}", x); } + @Override - public void setBeanListMapIntegerKeys(Map<Integer,List<Bean>> x) { + public void setBeanListMapIntegerKeys(Map<Integer,List<ABean>> x) { assertObjectEquals("{'1':[{a:1,b:'foo'}]}", x); // Note: JsonSerializer serializes key as string. - assertEquals(Integer.class, x.keySet().iterator().next().getClass()); + assertClass(Integer.class, x.keySet().iterator().next()); } // Typed beans + @Override public void setTypedBean(TypedBean x) { assertObjectEquals("{_type:'TypedBeanImpl',a:1,b:'foo'}", x); - assertEquals(TypedBeanImpl.class, x.getClass()); + assertClass(TypedBeanImpl.class, x); } + @Override public void setTypedBean3dArray(TypedBean[][][] x) { assertObjectEquals("[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null]", x); - assertEquals(TypedBeanImpl.class, x[0][0][0].getClass()); + assertClass(TypedBeanImpl.class, x[0][0][0]); } + @Override public void setTypedBeanList(List<TypedBean> x) { assertObjectEquals("[{_type:'TypedBeanImpl',a:1,b:'foo'}]", x); - assertEquals(TypedBeanImpl.class, x.get(0).getClass()); + assertClass(TypedBeanImpl.class, x.get(0)); } + @Override public void setTypedBean1d3dList(List<TypedBean[][][]> x) { assertObjectEquals("[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]", x); - assertEquals(TypedBeanImpl.class, x.get(0)[0][0][0].getClass()); + assertClass(TypedBeanImpl.class, x.get(0)[0][0][0]); } + @Override public void setTypedBeanMap(Map<String,TypedBean> x) { assertObjectEquals("{foo:{_type:'TypedBeanImpl',a:1,b:'foo'}}", x); - assertEquals(TypedBeanImpl.class, x.get("foo").getClass()); + assertClass(TypedBeanImpl.class, x.get("foo")); } + @Override public void setTypedBeanListMap(Map<String,List<TypedBean>> x) { assertObjectEquals("{foo:[{_type:'TypedBeanImpl',a:1,b:'foo'}]}", x); - assertEquals(TypedBeanImpl.class, x.get("foo").get(0).getClass()); + assertClass(TypedBeanImpl.class, x.get("foo").get(0)); } + @Override public void setTypedBean1d3dListMap(Map<String,List<TypedBean[][][]>> x) { assertObjectEquals("{foo:[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]}", x); - assertEquals(TypedBeanImpl.class, x.get("foo").get(0)[0][0][0].getClass()); + assertClass(TypedBeanImpl.class, x.get("foo").get(0)[0][0][0]); } + @Override public void setTypedBeanListMapIntegerKeys(Map<Integer,List<TypedBean>> x) { assertObjectEquals("{'1':[{_type:'TypedBeanImpl',a:1,b:'foo'}]}", x); // Note: JsonSerializer serializes key as string. - assertEquals(TypedBeanImpl.class, x.get(1).get(0).getClass()); + assertClass(TypedBeanImpl.class, x.get(1).get(0)); } // Swapped POJOs + @Override public void setSwappedPojo(SwappedPojo x) { assertTrue(x.wasUnswapped); } + @Override public void setSwappedPojo3dArray(SwappedPojo[][][] x) { assertObjectEquals("[[['"+SWAP+"',null],null],null]", x); assertTrue(x[0][0][0].wasUnswapped); } + @Override public void setSwappedPojoMap(Map<SwappedPojo,SwappedPojo> x) { assertObjectEquals("{'"+SWAP+"':'"+SWAP+"'}", x); @@ -442,6 +528,7 @@ public class InterfaceProxyResource extends RestServletJenaDefault { assertTrue(e.getKey().wasUnswapped); assertTrue(e.getValue().wasUnswapped); } + @Override public void setSwappedPojo3dMap(Map<SwappedPojo,SwappedPojo[][][]> x) { assertObjectEquals("{'"+SWAP+"':[[['"+SWAP+"',null],null],null]}", x); @@ -451,15 +538,18 @@ public class InterfaceProxyResource extends RestServletJenaDefault { } // Implicit swapped POJOs + @Override public void setImplicitSwappedPojo(ImplicitSwappedPojo x) { assertTrue(x.wasUnswapped); } + @Override public void setImplicitSwappedPojo3dArray(ImplicitSwappedPojo[][][] x) { assertObjectEquals("[[['"+SWAP+"',null],null],null]", x); assertTrue(x[0][0][0].wasUnswapped); } + @Override public void setImplicitSwappedPojoMap(Map<ImplicitSwappedPojo,ImplicitSwappedPojo> x) { assertObjectEquals("{'"+SWAP+"':'"+SWAP+"'}", x); @@ -467,6 +557,7 @@ public class InterfaceProxyResource extends RestServletJenaDefault { assertTrue(e.getKey().wasUnswapped); assertTrue(e.getValue().wasUnswapped); } + @Override public void setImplicitSwappedPojo3dMap(Map<ImplicitSwappedPojo,ImplicitSwappedPojo[][][]> x) { assertObjectEquals("{'"+SWAP+"':[[['"+SWAP+"',null],null],null]}", x); @@ -476,49 +567,57 @@ public class InterfaceProxyResource extends RestServletJenaDefault { } // Enums + @Override public void setEnum(TestEnum x) { assertEquals(TestEnum.TWO, x); } + @Override public void setEnum3d(TestEnum[][][] x) { assertObjectEquals("[[['TWO',null],null],null]", x); } + @Override public void setEnumList(List<TestEnum> x) { assertObjectEquals("['TWO',null]", x); - assertEquals(TestEnum.class, x.get(0).getClass()); + assertClass(TestEnum.class, x.get(0)); } + @Override public void setEnum3dList(List<List<List<TestEnum>>> x) { assertObjectEquals("[[['TWO',null],null,null]]", x); - assertEquals(TestEnum.class, x.get(0).get(0).get(0).getClass()); + assertClass(TestEnum.class, x.get(0).get(0).get(0)); } + @Override public void setEnum1d3dList(List<TestEnum[][][]> x) { assertObjectEquals("[[[['TWO',null],null],null],null]", x); - assertEquals(TestEnum[][][].class, x.get(0).getClass()); + assertClass(TestEnum[][][].class, x.get(0)); } + @Override public void setEnumMap(Map<TestEnum,TestEnum> x) { assertObjectEquals("{ONE:'TWO'}", x); Map.Entry<TestEnum,TestEnum> e = x.entrySet().iterator().next(); - assertEquals(TestEnum.class, e.getKey().getClass()); - assertEquals(TestEnum.class, e.getValue().getClass()); + assertClass(TestEnum.class, e.getKey()); + assertClass(TestEnum.class, e.getValue()); } + @Override public void setEnum3dArrayMap(Map<TestEnum,TestEnum[][][]> x) { assertObjectEquals("{ONE:[[['TWO',null],null],null]}", x); Map.Entry<TestEnum,TestEnum[][][]> e = x.entrySet().iterator().next(); - assertEquals(TestEnum.class, e.getKey().getClass()); - assertEquals(TestEnum[][][].class, e.getValue().getClass()); + assertClass(TestEnum.class, e.getKey()); + assertClass(TestEnum[][][].class, e.getValue()); } + @Override public void setEnum1d3dListMap(Map<TestEnum,List<TestEnum[][][]>> x) { assertObjectEquals("{ONE:[[[['TWO',null],null],null],null]}", x); Map.Entry<TestEnum,List<TestEnum[][][]>> e = x.entrySet().iterator().next(); - assertEquals(TestEnum.class, e.getKey().getClass()); - assertEquals(TestEnum[][][].class, e.getValue().get(0).getClass()); + assertClass(TestEnum.class, e.getKey()); + assertClass(TestEnum[][][].class, e.getValue().get(0)); } //-------------------------------------------------------------------------------- @@ -531,91 +630,99 @@ public class InterfaceProxyResource extends RestServletJenaDefault { assertObjectEquals("[[[1,2],null],null]", x2); assertNull(x2n); assertObjectEquals("[[[[1,2],null],null],null]", x3); - assertEquals(int[][][].class, x3.get(0).getClass()); + assertClass(int[][][].class, x3.get(0)); assertNull(x3n); } + @Override public void setMultiParamsInteger(Integer x1, Integer x1n, Integer[][][] x2, Integer[][][] x2n, List<Integer[][][]> x3, List<Integer[][][]> x3n) { assertObjectEquals("1", x1); assertObjectEquals("[[[1,null],null],null]", x2); assertNull(x2n); assertObjectEquals("[[[[1,null],null],null],null]", x3); - assertEquals(Integer[][][].class, x3.get(0).getClass()); + assertClass(Integer[][][].class, x3.get(0)); assertNull(x3n); } + @Override public void setMultiParamsFloat(float x1, float[][][] x2, float[][][] x2n, List<float[][][]> x3, List<float[][][]> x3n) { assertObjectEquals("1.0", x1); assertObjectEquals("[[[1.0,2.0],null],null]", x2); assertNull(x2n); assertObjectEquals("[[[[1.0,2.0],null],null],null]", x3); - assertEquals(float[][][].class, x3.get(0).getClass()); + assertClass(float[][][].class, x3.get(0)); assertNull(x3n); } + @Override public void setMultiParamsFloatObject(Float x1, Float x1n, Float[][][] x2, Float[][][] x2n, List<Float[][][]> x3, List<Float[][][]> x3n) { assertObjectEquals("1.0", x1); assertObjectEquals("[[[1.0,null],null],null]", x2); assertNull(x2n); assertObjectEquals("[[[[1.0,null],null],null],null]", x3); - assertEquals(Float[][][].class, x3.get(0).getClass()); + assertClass(Float[][][].class, x3.get(0)); assertNull(x3n); } + @Override public void setMultiParamsString(String x1, String[][][] x2, String[][][] x2n, List<String[][][]> x3, List<String[][][]> x3n) { assertObjectEquals("'foo'", x1); assertObjectEquals("[[['foo',null],null],null]", x2); assertNull(x2n); assertObjectEquals("[[[['foo',null],null],null],null]", x3); - assertEquals(String[][][].class, x3.get(0).getClass()); + assertClass(String[][][].class, x3.get(0)); assertNull(x3n); } + @Override - public void setMultiParamsBean(Bean x1, Bean[][][] x2, Bean[][][] x2n, List<Bean[][][]> x3, List<Bean[][][]> x3n, Map<String,Bean> x4, Map<String,Bean> x4n, Map<String,List<Bean[][][]>> x5, Map<String,List<Bean[][][]>> x5n) { + public void setMultiParamsBean(ABean x1, ABean[][][] x2, ABean[][][] x2n, List<ABean[][][]> x3, List<ABean[][][]> x3n, Map<String,ABean> x4, Map<String,ABean> x4n, Map<String,List<ABean[][][]>> x5, Map<String,List<ABean[][][]>> x5n) { assertObjectEquals("{a:1,b:'foo'}", x1); assertObjectEquals("[[[{a:1,b:'foo'},null],null],null]", x2); assertNull(x2n); assertObjectEquals("[[[[{a:1,b:'foo'},null],null],null],null]", x3); - assertEquals(Bean[][][].class, x3.get(0).getClass()); + assertClass(ABean[][][].class, x3.get(0)); assertNull(x3n); assertObjectEquals("{foo:{a:1,b:'foo'}}", x4); assertNull(x4n); assertObjectEquals("{foo:[[[[{a:1,b:'foo'},null],null],null],null]}", x5); assertNull(x5n); } + @Override public void setMultiParamsSwappedPojo(SwappedPojo x1, SwappedPojo[][][] x2, SwappedPojo[][][] x2n, List<SwappedPojo[][][]> x3, List<SwappedPojo[][][]> x3n, Map<SwappedPojo,SwappedPojo> x4, Map<SwappedPojo,SwappedPojo> x4n, Map<SwappedPojo,List<SwappedPojo[][][]>> x5, Map<SwappedPojo,List<SwappedPojo[][][]>> x5n) { assertObjectEquals("'"+SWAP+"'", x1); assertObjectEquals("[[['"+SWAP+"',null],null],null]", x2); assertNull(x2n); assertObjectEquals("[[[['"+SWAP+"',null],null],null],null]", x3); - assertEquals(SwappedPojo[][][].class, x3.get(0).getClass()); + assertClass(SwappedPojo[][][].class, x3.get(0)); assertNull(x3n); assertObjectEquals("{'"+SWAP+"':'"+SWAP+"'}", x4); assertNull(x4n); assertObjectEquals("{'"+SWAP+"':[[[['"+SWAP+"',null],null],null],null]}", x5); assertNull(x5n); } + @Override public void setMultiParamsImplicitSwappedPojo(ImplicitSwappedPojo x1, ImplicitSwappedPojo[][][] x2, ImplicitSwappedPojo[][][] x2n, List<ImplicitSwappedPojo[][][]> x3, List<ImplicitSwappedPojo[][][]> x3n, Map<ImplicitSwappedPojo,ImplicitSwappedPojo> x4, Map<ImplicitSwappedPojo,ImplicitSwappedPojo> x4n, Map<ImplicitSwappedPojo,List<ImplicitSwappedPojo[][][]>> x5, Map<ImplicitSwappedPojo,List<ImplicitSwappedPojo[][][]>> x5n) { assertObjectEquals("'"+SWAP+"'", x1); assertObjectEquals("[[['"+SWAP+"',null],null],null]", x2); assertNull(x2n); assertObjectEquals("[[[['"+SWAP+"',null],null],null],null]", x3); - assertEquals(ImplicitSwappedPojo[][][].class, x3.get(0).getClass()); + assertClass(ImplicitSwappedPojo[][][].class, x3.get(0)); assertNull(x3n); assertObjectEquals("{'"+SWAP+"':'"+SWAP+"'}", x4); assertNull(x4n); assertObjectEquals("{'"+SWAP+"':[[[['"+SWAP+"',null],null],null],null]}", x5); assertNull(x5n); } + @Override public void setMultiParamsEnum(TestEnum x1, TestEnum[][][] x2, TestEnum[][][] x2n, List<TestEnum[][][]> x3, List<TestEnum[][][]> x3n, Map<TestEnum,TestEnum> x4, Map<TestEnum,TestEnum> x4n, Map<TestEnum,List<TestEnum[][][]>> x5, Map<TestEnum,List<TestEnum[][][]>> x5n) { assertObjectEquals("'TWO'", x1); assertObjectEquals("[[['TWO',null],null],null]", x2); assertNull(x2n); assertObjectEquals("[[[['TWO',null],null],null],null]", x3); - assertEquals(TestEnum[][][].class, x3.get(0).getClass()); + assertClass(TestEnum[][][].class, x3.get(0)); assertNull(x3n); assertObjectEquals("{ONE:'TWO'}", x4); assertNull(x4n); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java index fabb545..34a18eb 100644 --- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java @@ -31,6 +31,7 @@ import org.apache.juneau.rest.labels.*; DefaultContentTypesResource.class, ErrorConditionsResource.class, TransformsResource.class, + FormDataResource.class, GroupsResource.class, GzipResource.TestGzipOff.class, GzipResource.TestGzipOn.class, @@ -60,6 +61,7 @@ import org.apache.juneau.rest.labels.*; RestClient2Resource.class, SerializersResource.class, StaticFilesResource.class, + ThirdPartyProxyResource.class, UrisResource.class, UrlContentResource.class, ShutdownResource.class http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7139635d/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/TestUtils.java ---------------------------------------------------------------------- diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/TestUtils.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/TestUtils.java new file mode 100644 index 0000000..102c17e --- /dev/null +++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/TestUtils.java @@ -0,0 +1,79 @@ +// *************************************************************************************************************************** +// * 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.test; + +import java.text.*; + +import org.apache.juneau.json.*; +import org.apache.juneau.rest.client.*; +import org.apache.juneau.serializer.*; +import org.apache.juneau.transforms.*; +import org.junit.Assert; + +import junit.framework.*; + +public class TestUtils { + + private static JsonSerializer js2 = new JsonSerializerBuilder() + .simple() + .pojoSwaps(IteratorSwap.class, EnumerationSwap.class) + .build(); + + /** + * Assert that the object equals the specified string after running it through JsonSerializer.DEFAULT_LAX.toString(). + */ + public static void assertObjectEquals(String s, Object o) { + assertObjectEquals(s, o, js2); + } + + /** + * Assert that the object is an instance of the specified class. + */ + public static void assertClass(Class<?> c, Object o) { + Assert.assertEquals(c, o == null ? null : o.getClass()); + } + + /** + * Assert that the object equals the specified string after running it through ws.toString(). + */ + public static void assertObjectEquals(String s, Object o, WriterSerializer ws) { + Assert.assertEquals(s, ws.toString(o)); + } + + public static void checkErrorResponse(boolean debug, RestCallException e, int status, String...contains) throws AssertionFailedError { + String r = e.getResponseMessage(); + if (debug) { + System.err.println(r); // NOT DEBUG + e.printStackTrace(); + } + if (status != e.getResponseCode()) { + dumpResponse(r, "Response status code was not correct. Expected: ''{0}''. Actual: ''{1}''", status, e.getResponseCode()); + throw new AssertionFailedError(MessageFormat.format("Response status code was not correct. Expected: ''{0}''. Actual: ''{1}''", status, e.getResponseCode())); + } + for (String s : contains) { + if (r == null || ! r.contains(s)) { + if (! debug) + dumpResponse(r, "Response did not have the following expected text: ''{0}''", s); + throw new AssertionFailedError(MessageFormat.format("Response did not have the following expected text: ''{0}''", s)); + } + } + } + + private static void dumpResponse(String r, String msg, Object...args) { + System.err.println("*** Failure ****************************************************************************************"); // NOT DEBUG + System.err.println(MessageFormat.format(msg, args)); + System.err.println("*** Response-Start *********************************************************************************"); // NOT DEBUG + System.err.println(r); // NOT DEBUG + System.err.println("*** Response-End ***********************************************************************************"); // NOT DEBUG + } +}
