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 2017/09/08 23:25:37 UTC
svn commit: r21540 [21/27] - in /release/incubator/juneau:
juneau-rest-client/ juneau-rest-client/.settings/ juneau-rest-client/bin/
juneau-rest-client/src/ juneau-rest-client/src/main/
juneau-rest-client/src/main/java/ juneau-rest-client/src/main/java...
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/package.html
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServiceProperties.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServiceProperties.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServiceProperties.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,44 @@
+// ***************************************************************************************************************************
+// * 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.remoteable;
+
+import org.apache.juneau.remoteable.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * Configurable properties for the {@link RemoteableServlet} class.
+ *
+ * <p>
+ * Properties can be set on the {@link RestServlet} class using the {@link RestResource#properties} or
+ * {@link RestMethod#properties} annotations.
+ *
+ * <p>
+ * These properties can also be passed in as servlet init parameters.
+ *
+ * <p>
+ * These properties are only valid at the class level, not the method level.
+ * Setting them on {@link RestMethod#properties()} has no effect.
+ */
+public final class RemoteableServiceProperties {
+
+ /**
+ * Only expose interfaces and methods annotated with {@link Remoteable @Remoteable} ({@link Boolean},
+ * default=<jk>false</jk>).
+ *
+ * <p>
+ * When enabled, the {@link RemoteableServlet} class will only work with annotated remoteable interfaces and methods.
+ * Otherwise, all public methods can be executed through the service.
+ */
+ public static final String REMOTEABLE_includeOnlyRemotableMethods = "RemoteableService.includeOnlyRemoteableMethods";
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServiceProperties.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,155 @@
+// ***************************************************************************************************************************
+// * 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.remoteable;
+
+import static javax.servlet.http.HttpServletResponse.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.dto.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * Abstract class for defining Remoteable services.
+ *
+ * <p>
+ * Remoteable services are POJOs whose methods can be invoked remotely through proxy interfaces.
+ *
+ * <p>
+ * To implement a remoteable service, developers must simply subclass from this class and implement the
+ * {@link #getServiceMap()} method that maps java interfaces to POJO instances.
+ *
+ * See <a class='doclink' href='package-summary.html#TOC'>org.apache.juneau.rest.remoteable</a> for details.
+ */
+@SuppressWarnings("serial")
+public abstract class RemoteableServlet extends RestServletDefault {
+
+ private final Map<String,Class<?>> classNameMap = new ConcurrentHashMap<String,Class<?>>();
+
+ //--------------------------------------------------------------------------------
+ // Abstract methods
+ //--------------------------------------------------------------------------------
+
+ /**
+ * Returns the list of interfaces to their implementation objects.
+ *
+ * <p>
+ * This class is called often and not cached, so any caching should occur in the subclass if necessary.
+ *
+ * @return The service map.
+ * @throws Exception
+ */
+ protected abstract Map<Class<?>,Object> getServiceMap() throws Exception;
+
+ //--------------------------------------------------------------------------------
+ // REST methods
+ //--------------------------------------------------------------------------------
+
+ /**
+ * [GET /] - Get the list of all remote interfaces.
+ *
+ * @param req The HTTP servlet request.
+ * @return The list of links to the remote interfaces.
+ * @throws Exception
+ */
+ @RestMethod(name="GET", path="/")
+ public List<Link> getInterfaces(RestRequest req) throws Exception {
+ List<Link> l = new LinkedList<Link>();
+ boolean useAll = ! useOnlyAnnotated();
+ for (Class<?> c : getServiceMap().keySet()) {
+ if (useAll || getContext().getBeanContext().getClassMeta(c).isRemoteable())
+ l.add(new Link(c.getName(), "{0}/{1}", req.getRequestURI(), c.getName()));
+ }
+ return l;
+ }
+
+ /**
+ * [GET /{javaInterface] - Get the list of all remoteable methods on the specified interface name.
+ *
+ * @param javaInterface The Java interface name.
+ * @return The methods defined on the interface.
+ * @throws Exception
+ */
+ @RestMethod(name="GET", path="/{javaInterface}")
+ public Collection<String> listMethods(@Path String javaInterface) throws Exception {
+ return getMethods(javaInterface).keySet();
+ }
+
+ /**
+ * [POST /{javaInterface}/{javaMethod}] - Invoke the specified service method.
+ *
+ * @param req The HTTP request.
+ * @param javaInterface The Java interface name.
+ * @param javaMethod The Java method name or signature.
+ * @return The results from invoking the specified Java method.
+ * @throws Exception
+ */
+ @RestMethod(name="POST", path="/{javaInterface}/{javaMethod}")
+ public Object invoke(RestRequest req, @Path String javaInterface, @Path String javaMethod) throws Exception {
+
+ // Find the parser.
+ ReaderParser p = req.getBody().getReaderParser();
+ if (p == null)
+ throw new RestException(SC_UNSUPPORTED_MEDIA_TYPE, "Could not find parser for media type ''{0}''", req.getHeaders().getContentType());
+ Class<?> c = getInterfaceClass(javaInterface);
+
+ // Find the service.
+ Object service = getServiceMap().get(c);
+ if (service == null)
+ throw new RestException(SC_NOT_FOUND, "Service not found");
+
+ // Find the method.
+ java.lang.reflect.Method m = getMethods(javaInterface).get(javaMethod);
+ if (m == null)
+ throw new RestException(SC_NOT_FOUND, "Method not found");
+
+ // Parse the args and invoke the method.
+ Object[] params = p.parseArgs(req.getReader(), m.getGenericParameterTypes());
+ return m.invoke(service, params);
+ }
+
+
+ //--------------------------------------------------------------------------------
+ // Other methods
+ //--------------------------------------------------------------------------------
+
+ private boolean useOnlyAnnotated() {
+ return getProperties().getBoolean(RemoteableServiceProperties.REMOTEABLE_includeOnlyRemotableMethods, false);
+ }
+
+ private Map<String,java.lang.reflect.Method> getMethods(String javaInterface) throws Exception {
+ Class<?> c = getInterfaceClass(javaInterface);
+ ClassMeta<?> cm = getContext().getBeanContext().getClassMeta(c);
+ return (useOnlyAnnotated() ? cm.getRemoteableMethods() : cm.getPublicMethods());
+ }
+
+ /**
+ * Return the <code>Class</code> given it's name if it exists in the services map.
+ */
+ private Class<?> getInterfaceClass(String javaInterface) throws Exception {
+ Class<?> c = classNameMap.get(javaInterface);
+ if (c == null) {
+ for (Class<?> c2 : getServiceMap().keySet())
+ if (c2.getName().equals(javaInterface)) {
+ classNameMap.put(javaInterface, c2);
+ return c2;
+ }
+ throw new RestException(SC_NOT_FOUND, "Interface class not found");
+ }
+ return c;
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/RemoteableServlet.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/1.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/1.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/2.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/2.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/3.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/3.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/4.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/4.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/5.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/5.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/6.png
==============================================================================
Binary file - no diff available.
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/doc-files/6.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/package.html
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/package.html (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/package.html Fri Sep 8 23:25:34 2017
@@ -0,0 +1,366 @@
+<!DOCTYPE HTML>
+<!--
+/***************************************************************************************************************************
+ * 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.
+ *
+ ***************************************************************************************************************************/
+ -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <style type="text/css">
+ /* For viewing in Page Designer */
+ @IMPORT url("../../../../../javadoc.css");
+
+ /* For viewing in REST interface */
+ @IMPORT url("../htdocs/javadoc.css");
+ body {
+ margin: 20px;
+ }
+ </style>
+ <script>
+ /* Replace all @code and @link tags. */
+ window.onload = function() {
+ document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+ document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>');
+ }
+ </script>
+</head>
+<body>
+<p>Remoteable service API</p>
+
+<script>
+ function toggle(x) {
+ var div = x.nextSibling;
+ while (div != null && div.nodeType != 1)
+ div = div.nextSibling;
+ if (div != null) {
+ var d = div.style.display;
+ if (d == 'block' || d == '') {
+ div.style.display = 'none';
+ x.className += " closed";
+ } else {
+ div.style.display = 'block';
+ x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' );
+ }
+ }
+ }
+</script>
+
+<p>
+ Defines an API for remote proxy interfaces (e.g. Remoteable Services).
+</p>
+
+<a id='TOC'></a><h5 class='toc'>Table of Contents</h5>
+<ol class='toc'>
+ <li><p><a class='doclink' href='#Intro'>Remoteable Services</a></p>
+ <li><p><a class='doclink' href='#Client'>Client Side</a></p>
+ <li><p><a class='doclink' href='#Server'>Server Side</a></p>
+ <li><p><a class='doclink' href='#RemoteableAnnotation'>@Remoteable Annotation</a></p>
+</ol>
+
+<!-- ======================================================================================================== -->
+<a id="Intro"></a>
+<h2 class='topic' onclick='toggle(this)'>1 - Remoteable Services</h2>
+<div class='topic'>
+ <p>
+ The Remoteable Service API allows for client side code to use interface proxies for calling methods on POJOs on
+ the server side.
+ </p>
+ <p>
+ Proxy interfaces are retrieved using the {@link org.apache.juneau.rest.client.RestClient#getRemoteableProxy(Class)}
+ method.
+ The remoteable servlet is a specialized subclass of {@link org.apache.juneau.rest.RestServlet} that provides a
+ full-blown REST interface for calling remoteable services (e.g. POJOs) remotely.
+ </p>
+ <p>
+ The following simplified example shows how a method on a POJO on a server can be called through an interface
+ on a client...
+ </p>
+ <p class='bcode'>
+ <jk>public interface</jk> IAddressBook {
+ Person createPerson(CreatePerson cp) <jk>throws</jk> Exception;
+ Person findPerson(<jk>int</jk> id);
+ Address findAddress(<jk>int</jk> id);
+ Person findPersonWithAddress(<jk>int</jk> id);
+ }
+ </p>
+ <p>
+ The client side code for invoking this method is shown below...
+ </p>
+ <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()
+ .rootUrl(<js>"https://localhost:9080/juneau/sample/remoteable"</js>)
+ .build();
+
+ <jc>// Create a proxy interface.</jc>
+ IAddressBook ab = client.getRemoteableProxy(IAddressBook.<jk>class</jk>);
+
+ <jc>// Invoke a method on the server side and get the returned result.</jc>
+ Person p = ab.createPerson(
+ <jk>new</jk> CreatePerson(<js>"Test Person"</js>,
+ AddressBook.<jsm>toCalendar</jsm>(<js>"Aug 1, 1999"</js>),
+ <jk>new</jk> CreateAddress(<js>"Test street"</js>, <js>"Test city"</js>, <js>"Test state"</js>, 12345, <jk>true</jk>))
+ );
+ </p>
+ <p>
+ The requirements for a method to be callable through the remoteable service are:
+ </p>
+ <ul class='spaced-list'>
+ <li>
+ The method must be public.
+ <li>
+ The parameter and return types must be <a href='../../../../../overview-summary.html#Core.PojoCategories'>serializable and parsable</a>.
+ </ul>
+</div>
+
+<!-- ======================================================================================================== -->
+<a id="Client"></a>
+<h2 class='topic' onclick='toggle(this)'>2 - Client Side</h2>
+<div class='topic'>
+ <p>
+ Remoteable interface proxies are retrieved through the existing {@link org.apache.juneau.rest.client.RestClient}
+ class.
+ </p>
+ <p>
+ It may seem that the client-side code would need to be complex.
+ In reality, it builds upon existing serializing, parsing, and REST capabilities in Juneau resulting in very
+ little additional code.
+ The entire code for the <code>RestClient.getRemoteableProxy(Class)</code> method is shown below:
+ </p>
+ <p class='bcode'>
+ <jk>public</jk> <T> T getRemoteableProxy(<jk>final</jk> Class<T> interfaceClass) {
+ <jk>return</jk> (T)Proxy.newProxyInstance(
+ interfaceClass.getClassLoader(),
+ <jk>new</jk> Class[] { interfaceClass },
+ <jk>new</jk> InvocationHandler() {
+ <ja>@Override</ja>
+ <jk>public</jk> Object invoke(Object proxy, Method method, Object[] args) {
+ <jk>try</jk> {
+ String uri = <jf>remoteableServletUri</jf> + '/' + interfaceClass.getName() + '/' + ClassUtils.<jsm>getMethodSignature</jsm>(method);
+ <jk>return</jk> doPost(uri, args).getResponse(method.getReturnType());
+ } <jk>catch</jk> (Exception e) {
+ <jk>throw new</jk> RuntimeException(e);
+ }
+ }
+ });
+ }
+ </p>
+ <p>
+ Since we build upon the existing <code>RestClient</code> API, we inherit all of it's features.
+ For example, convenience methods for setting POJO filters and properties to customize the behavior of the
+ serializers and parsers, and the ability to provide your own customized Apache <code>HttpClient</code> for
+ handling various scenarios involving authentication and Internet proxies.
+ </p>
+</div>
+
+<!-- ======================================================================================================== -->
+<a id="Server"></a>
+<h2 class='topic' onclick='toggle(this)'>3 - Server Side</h2>
+<div class='topic'>
+ <p>
+ The server side is only slightly more complex, but boasts useful debugging and discovery capabilities.
+ </p>
+ <p>
+ The {@link org.apache.juneau.rest.remoteable.RemoteableServlet} class is an implementation of
+ {@link org.apache.juneau.rest.RestServlet} that provides a REST interface for invoking calls on POJOs.
+ The <code>RemoteableServlet</code> class is abstract and must implement a single method for providing the set
+ of POJOs to expose as remote interfaces.
+ </p>
+ <p>
+ The samples bundle includes a sample implementation of a remoteable service that can be used to interact with
+ the address book POJO also included in the bundle.
+ The method that must be implemented is {@link org.apache.juneau.rest.remoteable.RemoteableServlet#getServiceMap()}
+ that simply returns a mapping of Java interfaces (or classes) to POJO instances.
+ </p>
+ <p class='bcode'>
+ <ja>@RestResource</ja>(
+ path=<js>"/remoteable"</js>
+ )
+ <jk>public class</jk> SampleRemoteableServlet <jk>extends</jk> RemoteableServlet {
+
+ <jc>// The POJO being manipulated (i.e. the remoteable service)</jc>
+ AddressBook <jf>addressBook</jf> = <jk>new</jk> AddressBook();
+
+ <ja>@Override</ja> <jc>/* RemoteableServlet */</jc>
+ <jk>protected</jk> Map<Class<?>,Object> getServiceMap() <jk>throws</jk> Exception {
+ Map<Class<?>,Object> m = <jk>new</jk> LinkedHashMap<Class<?>,Object>();
+
+ <jc>// In this simplified example, we expose the same POJO service under two different interfaces.
+ // One is IAddressBook which only exposes methods defined on that interface, and
+ // the other is AddressBook itself which exposes all public methods defined on the class itself.</jc>
+ m.put(IAddressBook.<jk>class</jk>, addressBook);
+ m.put(AddressBook.<jk>class</jk>, addressBook);
+ <jk>return</jk> m;
+ }
+ }
+ </p>
+ <p>
+ Since this class is a servlet, and can be deployed as such.
+ In the sample code, it's listed as a child resource to <code>org.apache.juneau.rest.samples.RootResources</code>
+ which makes it available under the URL <code>/juneau/sample/remoteable</code>.
+ </p>
+ <p>
+ If you point your browser to that URL, you get a list of available interfaces:
+ </p>
+ <img class='bordered' src="doc-files/1.png">
+ <p>
+ Clicking the hyperlinks on each shows you the list of methods that can be invoked on that service.
+ Note that the <code>IAddressBook</code> link shows that you can only invoke methods defined on that
+ interface, whereas the <code>AddressBook</code> link shows ALL public methods defined on that class.
+ Since <code>AddressBook</code> extends from <code>LinkedList</code>, you may notice familiar collections
+ framework methods listed.
+ </p>
+ <img class='bordered' src="doc-files/2.png">
+ <img class='bordered' src="doc-files/3.png">
+ <p>
+ Let's see how we can interact with this interface through nothing more than REST calls to get a better idea on
+ how this works.
+ We'll use the same method call as in the introduction.
+ First, we need to create the serialized form of the arguments:
+ </p>
+ <p class='bcode'>
+ Object[] args = <jk>new</jk> Object[] {
+ <jk>new</jk> CreatePerson(<js>"Test Person"</js>,
+ AddressBook.<jsm>toCalendar</jsm>(<js>"Aug 1, 1999"</js>),
+ <jk>new</jk> CreateAddress(<js>"Test street"</js>, <js>"Test city"</js>, <js>"Test state"</js>, 12345, <jk>true</jk>))
+ };
+ String asJson = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.toString(args);
+ System.<jsf>err</jsf>.println(asJson);
+ </p>
+ <p>
+ That produces the following JSON output:
+ </p>
+ <p class='bcode'>
+ [
+ {
+ name: <js>'Test Person'</js>,
+ birthDate: <js>'Aug 1, 1999'</js>,
+ addresses: [
+ {
+ street: <js>'Test street'</js>,
+ city: <js>'Test city'</js>,
+ state: <js>'Test state'</js>,
+ zip: 12345,
+ isCurrent: <jk>true</jk>
+ }
+ ]
+ }
+ ]
+ </p>
+ <p>
+ Note that in this example we're using JSON.
+ However, various other content types can also be used such as XML, URL-Encoding, UON, or HTML.
+ In practice however, JSON will preferred since it is often the most efficient.
+ </p>
+ <p>
+ Next, we can use a tool such as Poster to make the REST call.
+ Methods are invoked by POSTing the serialized object array to the URI of the interface method.
+ In this case, we want to POST our JSON to <code>/juneau/sample/remoteable/org.apache.juneau.examples.addressbook.IAddressBook/createPerson(org.apache.juneau.examples.addressbook.CreatePerson)</code>.
+ Make sure that we specify the <code>Content-Type</code> of the body as <code>text/json</code>.
+ We also want the results to be returned as JSON, so we set the <code>Accept</code> header to
+ <code>text/json</code> as well.
+ </p>
+ <img class='bordered' src="doc-files/4.png">
+ <p>
+ When we execute the POST, we should see the following successful response whose body contains the returned
+ <code>Person</code> bean serialized to JSON:
+ </p>
+ <img class='bordered' src="doc-files/5.png">
+ <p>
+ From there, we could use the following code snippet to reconstruct the response object from JSON:
+ </p>
+ <p class='bcode'>
+ String response = <js>"<i>output from above</i>"</js>;
+ Person p = JsonParser.<jsf>DEFAULT</jsf>.parse(response, Person.<jk>class</jk>);
+ </p>
+ <p>
+ If we alter our servlet to allow overloaded GET requests, we can invoke methods using nothing more than a
+ browser...
+ </p>
+ <p class='bcode'>
+ <ja>@RestResource</ja>(
+ path=<js>"/remoteable"</js>,
+ properties={
+ <jc>// Allow us to use method=POST from a browser.</jc>
+ <ja>@Property</ja>(name=<jsf>REST_allowMethodParam</jsf>, value=<js>"*"</js>)
+ }
+ )
+ <jk>public class</jk> SampleRemoteableServlet <jk>extends</jk> RemoteableServlet {
+ </p>
+ <p>
+ For example, here we call the <code>findPerson(<jk>int</jk>)</code> method to retrieve a person and get the
+ returned POJO (in this case as HTML since that's what's in the <code>Accept</code> header when calling from a
+ browser):
+ </p>
+ <img class='bordered' src="doc-files/6.png">
+ <p>
+ When specifying the POST body as a <code>&content</code> parameter, the method arguments should be in UON
+ notation.
+ See {@link org.apache.juneau.uon.UonSerializer} for more information about this encoding.
+ Usually you can also pass in JSON if you specify <code>&Content-Type=text/json</code> in the URL parameters
+ but passing in unencoded JSON in a URL may not work in all browsers.
+ Therefore, UON is preferred.
+ </p>
+</div>
+
+<!-- ======================================================================================================== -->
+<a id="RemoteableAnnotation"></a>
+<h2 class='topic' onclick='toggle(this)'>4 - @Remoteable Annotation</h2>
+<div class='topic'>
+ <p>
+ What if you want fine-tuned control over which methods are exposed in an interface instead of just all public
+ methods?
+ For this, the {@link org.apache.juneau.remoteable.Remoteable @Remoteable} annotation is provided.
+ It can be applied to individual interface methods to only expose those methods through the remoteable servlet.
+ </p>
+ <p>
+ For example, to expose only the first 2 methods in our <code>IAddressBook</code> interface...
+ </p>
+ <p class='bcode'>
+ <jk>public interface</jk> IAddressBook {
+ <ja>@Remoteable</ja> Person createPerson(CreatePerson cp) <jk>throws</jk> Exception;
+ <ja>@Remoteable</ja> Person findPerson(<jk>int</jk> id);
+ Address findAddress(<jk>int</jk> id);
+ Person findPersonWithAddress(<jk>int</jk> id);
+ }
+ </p>
+ <p>
+ On the server side, the option to restrict access to only annotated methods is defined through a property:
+ </p>
+ <p class='bcode'>
+ <ja>@RestResource</ja>(
+ path=<js>"/remoteable"</js>,
+ properties={
+ <jc>// Only expose methods annotated with @Remoteable.</jc>
+ <ja>@Property</ja>(name=<jsf>REMOTEABLE_includeOnlyRemotableMethods</jsf>, value=<js>"true"</js>)
+ }
+ )
+ <jk>public class</jk> SampleRemoteableServlet <jk>extends</jk> RemoteableServlet {
+ </p>
+ <p>
+ The <ja>@Remoteable</ja> annotation can also be applied to the interface class to expose all public methods
+ defined on that interface.
+ </p>
+ <p class='bcode'>
+ <ja>@Remoteable</ja>
+ <jk>public interface</jk> IAddressBook {
+ Person createPerson(CreatePerson cp) <jk>throws</jk> Exception;
+ Person findPerson(<jk>int</jk> id);
+ Address findAddress(<jk>int</jk> id);
+ Person findPersonWithAddress(<jk>int</jk> id);
+ }
+ </p>
+</div>
+</body>
+</html>
\ No newline at end of file
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/remoteable/package.html
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,93 @@
+// ***************************************************************************************************************************
+// * 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.response;
+
+import static javax.servlet.http.HttpServletResponse.*;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Response handler for POJOs not handled by other handlers.
+ *
+ * <p>
+ * This uses the serializers defined on the response to serialize the POJO.
+ *
+ * <p>
+ * The {@link Serializer} used is based on the <code>Accept</code> header on the request.
+ *
+ * <p>
+ * The <code>Content-Type</code> header is set to the mime-type defined on the selected serializer based on the
+ * <code>produces</code> value passed in through the constructor.
+ */
+public class DefaultHandler implements ResponseHandler {
+
+ @Override /* ResponseHandler */
+ public boolean handle(RestRequest req, RestResponse res, Object output) throws IOException, RestException {
+ SerializerGroup g = res.getSerializerGroup();
+ String accept = req.getHeaders().getString("Accept", "");
+ SerializerMatch sm = g.getSerializerMatch(accept);
+ if (sm != null) {
+ Serializer s = sm.getSerializer();
+ MediaType mediaType = res.getMediaType();
+ if (mediaType == null)
+ mediaType = sm.getMediaType();
+ res.setContentType(mediaType.toString());
+
+ try {
+ ObjectMap p = res.getProperties();
+ if (req.isPlainText()) {
+ res.setContentType("text/plain");
+ }
+ p.append("mediaType", mediaType).append("characterEncoding", res.getCharacterEncoding());
+
+ SerializerSession session = s.createSession(new SerializerSessionArgs(p, req.getJavaMethod(), req.getLocale(), req.getHeaders().getTimeZone(), mediaType, req.getUriContext()));
+
+ for (Map.Entry<String,String> h : session.getResponseHeaders().entrySet())
+ res.setHeader(h.getKey(), h.getValue());
+
+ if (! session.isWriterSerializer()) {
+ if (req.isPlainText()) {
+ Writer w = res.getNegotiatedWriter();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ session.serialize(baos, output);
+ w.write(StringUtils.toHex(baos.toByteArray()));
+ w.close(); // Leave open if exception occurs.
+ } else {
+ OutputStream os = res.getNegotiatedOutputStream();
+ session.serialize(os, output);
+ os.close(); // Leave open if exception occurs.
+ }
+ } else {
+ Writer w = res.getNegotiatedWriter();
+ session.serialize(w, output);
+ w.close(); // Leave open if exception occurs.
+ }
+ } catch (SerializeException e) {
+ throw new RestException(SC_INTERNAL_SERVER_ERROR, e);
+ }
+ } else {
+ throw new RestException(SC_NOT_ACCEPTABLE,
+ "Unsupported media-type in request header ''Accept'': ''{0}''\n\tSupported media-types: {1}",
+ req.getHeaders().getString("Accept", ""), g.getSupportedMediaTypes()
+ );
+ }
+ return true;
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/DefaultHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/InputStreamHandler.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/InputStreamHandler.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/InputStreamHandler.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,41 @@
+// ***************************************************************************************************************************
+// * 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.response;
+
+import java.io.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * Response handler for {@link InputStream} objects.
+ *
+ * <p>
+ * Simply pipes the contents of the {@link InputStream} to {@link RestResponse#getNegotiatedOutputStream()}.
+ *
+ * <p>
+ * Sets the <code>Content-Type</code> response header to whatever was set via {@link RestResponse#setContentType(String)}.
+ */
+public final class InputStreamHandler implements ResponseHandler {
+
+ @Override /* ResponseHandler */
+ public boolean handle(RestRequest req, RestResponse res, Object output) throws IOException, RestException {
+ if (output instanceof InputStream) {
+ res.setHeader("Content-Type", res.getContentType());
+ OutputStream os = res.getNegotiatedOutputStream();
+ IOPipe.create(output, os).closeOut().run();
+ return true;
+ }
+ return false;
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/InputStreamHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/ReaderHandler.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/ReaderHandler.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/ReaderHandler.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,38 @@
+// ***************************************************************************************************************************
+// * 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.response;
+
+import java.io.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * Response handler for {@link Reader} objects.
+ *
+ * <p>
+ * Simply pipes the contents of the {@link Reader} to {@link RestResponse#getNegotiatedWriter()}.
+ */
+public final class ReaderHandler implements ResponseHandler {
+
+ @Override /* ResponseHandler */
+ public boolean handle(RestRequest req, RestResponse res, Object output) throws IOException, RestException {
+ if (output instanceof Reader) {
+ Writer w = res.getNegotiatedWriter();
+ IOPipe.create(output, w).closeOut().run();
+ return true;
+ }
+ return false;
+ }
+}
+
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/ReaderHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/RedirectHandler.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/RedirectHandler.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/RedirectHandler.java Fri Sep 8 23:25:34 2017
@@ -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.response;
+
+import java.io.*;
+
+import org.apache.juneau.rest.*;
+
+/**
+ * Response handler for {@link Redirect} objects.
+ */
+public final class RedirectHandler implements ResponseHandler {
+
+ @Override /* ResponseHandler */
+ public boolean handle(RestRequest req, RestResponse res, Object output) throws IOException, RestException {
+ if (output instanceof Redirect) {
+ Redirect r = (Redirect)output;
+ String uri = req.getUriResolver().resolve(r.getURI());
+ int rc = r.getHttpResponseCode();
+ if (rc != 0)
+ res.setStatus(rc); // TODO - This may get ignored by the call below.
+ res.sendRedirect(uri);
+ return true;
+ }
+ return false;
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/RedirectHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/StreamableHandler.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/StreamableHandler.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/StreamableHandler.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,51 @@
+// ***************************************************************************************************************************
+// * 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.response;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.rest.*;
+
+/**
+ * Response handler for {@link Writable} and {@link ReaderResource} objects.
+ *
+ * <p>
+ * Uses the {@link Writable#writeTo(Writer)} method to send the contents to the
+ * {@link RestResponse#getNegotiatedWriter()} writer.
+ */
+public final class StreamableHandler implements ResponseHandler {
+
+ @Override /* ResponseHandler */
+ public boolean handle(RestRequest req, RestResponse res, Object output) throws IOException, RestException {
+ if (output instanceof Streamable) {
+ if (output instanceof StreamResource) {
+ StreamResource r = (StreamResource)output;
+ MediaType mediaType = r.getMediaType();
+ if (mediaType != null)
+ res.setContentType(mediaType.toString());
+ for (Map.Entry<String,String> h : r.getHeaders().entrySet())
+ res.setHeader(h.getKey(), h.getValue());
+ }
+ OutputStream os = res.getOutputStream();
+ ((Streamable)output).streamTo(os);
+ os.flush();
+ os.close();
+ return true;
+ }
+ return false;
+ }
+}
+
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/StreamableHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/WritableHandler.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/WritableHandler.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/WritableHandler.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,50 @@
+// ***************************************************************************************************************************
+// * 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.response;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.http.*;
+import org.apache.juneau.rest.*;
+
+/**
+ * Response handler for {@link Writable} and {@link ReaderResource} objects.
+ *
+ * <p>
+ * Uses the {@link Writable#writeTo(Writer)} method to send the contents to the {@link RestResponse#getNegotiatedWriter()} writer.
+ */
+public final class WritableHandler implements ResponseHandler {
+
+ @Override /* ResponseHandler */
+ public boolean handle(RestRequest req, RestResponse res, Object output) throws IOException, RestException {
+ if (output instanceof Writable) {
+ if (output instanceof ReaderResource) {
+ ReaderResource r = (ReaderResource)output;
+ MediaType mediaType = r.getMediaType();
+ if (mediaType != null)
+ res.setContentType(mediaType.toString());
+ for (Map.Entry<String,String> h : r.getHeaders().entrySet())
+ res.setHeader(h.getKey(), h.getValue());
+ }
+ Writer w = res.getNegotiatedWriter();
+ ((Writable)output).writeTo(w);
+ w.flush();
+ w.close();
+ return true;
+ }
+ return false;
+ }
+}
+
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/WritableHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/ZipFileListResponseHandler.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/ZipFileListResponseHandler.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/ZipFileListResponseHandler.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,66 @@
+// ***************************************************************************************************************************
+// * 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.response;
+
+import java.io.*;
+import java.util.zip.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.utils.*;
+import org.apache.juneau.utils.ZipFileList.*;
+
+/**
+ * Response handler for ZipFileList objects.
+ *
+ * <p>
+ * Can be associated with a REST resource using the {@link RestResource#responseHandlers} annotation.
+ *
+ * <p>
+ * Sets the following headers:
+ * <ul class='spaced-list'>
+ * <li>
+ * <code>Content-Type</code> - <code>application/zip</code>
+ * <li>
+ * <code>Content-Disposition=attachment;filename=X</code> - Sets X to the file name passed in through the
+ * constructor {@link ZipFileList#ZipFileList(String)}.
+ * </ul>
+ */
+public class ZipFileListResponseHandler implements ResponseHandler {
+
+ @Override /* ResponseHandler */
+ public boolean handle(RestRequest req, RestResponse res, Object output) throws IOException, RestException {
+ if (output.getClass() == ZipFileList.class) {
+ ZipFileList m = (ZipFileList)output;
+ res.setContentType("application/zip");
+ res.setHeader("Content-Disposition", "attachment;filename=" + m.fileName); //$NON-NLS-2$
+ OutputStream os = res.getOutputStream();
+ try {
+ ZipOutputStream zos = new ZipOutputStream(os);
+ try {
+ for (ZipFileEntry e : m)
+ e.write(zos);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ zos.flush();
+ zos.close();
+ }
+ } finally {
+ os.flush();
+ }
+ return true;
+ }
+ return false;
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/ZipFileListResponseHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/package.html
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/package.html (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/package.html Fri Sep 8 23:25:34 2017
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<!--
+/***************************************************************************************************************************
+ * 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.
+ *
+ ***************************************************************************************************************************/
+ -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <style type="text/css">
+ /* For viewing in Page Designer */
+ @IMPORT url("../../../../javadoc.css");
+
+ /* For viewing in REST interface */
+ @IMPORT url("../htdocs/javadoc.css");
+ body {
+ margin: 20px;
+ }
+ </style>
+ <script>
+ /* Replace all @code and @link tags. */
+ window.onload = function() {
+ document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+ document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>');
+ }
+ </script>
+</head>
+<body>
+<p>HTTP Response handlers</p>
+</body>
+</html>
\ No newline at end of file
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/response/package.html
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/FileVar.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/FileVar.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/FileVar.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,86 @@
+// ***************************************************************************************************************************
+// * 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.vars;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.svl.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * File resource variable resolver
+ *
+ * <p>
+ * The format for this var is <js>"$F{path[,defaultValue]}"</js>.
+ *
+ * <p>
+ * File variables resolve to the contents of resource files located on the classpath or local JVM directory.
+ * They use the {@link RestRequest#getReaderResource(String)} method to retrieve the contents of the file.
+ * That in turn uses the {@link ResourceFinder} associated with the servlet class to find the file.
+ *
+ * <p>
+ * The {@link ResourceFinder} is similar to {@link Class#getResourceAsStream(String)} except if it doesn't find the
+ * resource on this class, it searches up the parent hierarchy chain.
+ *
+ * <p>
+ * If the resource cannot be found in the classpath, then an attempt is made to look in the JVM working directory.
+ * <br>Path traversals outside the working directory are not allowed for security reasons.
+
+ * <p>
+ * Localized resources (based on the locale of the HTTP request) are supported.
+ * For example, if looking for the resource <js>"MyResource.txt"</js> for the Japanese locale, we will look for
+ * files in the following order:
+ * <ol>
+ * <li><js>"MyResource_ja_JP.txt"</js>
+ * <li><js>"MyResource_ja.txt"</js>
+ * <li><js>"MyResource.txt"</js>
+ * </ol>
+ *
+ * <p>
+ * Example:
+ * <p class='bcode'>
+ * <ja>@RestResource</ja>(
+ * htmldoc=<ja>@HtmlDoc</ja>(
+ * aside=<js>"$F{resources/MyAsideMessage.html, Oops not found!}"</js>
+ * )
+ * )
+ * </p>
+ *
+ * <p>
+ * Files of type HTML, XHTML, XML, JSON, Javascript, and CSS will be stripped of comments.
+ * This allows you to place license headers in files without them being serialized to the output.
+ *
+ * @see org.apache.juneau.svl
+ */
+public class FileVar extends DefaultingVar {
+
+ private static final String SESSION_req = "req";
+
+ /**
+ * The name of this variable.
+ */
+ public static final String NAME = "F";
+
+ /**
+ * Constructor.
+ */
+ public FileVar() {
+ super(NAME);
+ }
+
+ @Override /* Parameter */
+ public String resolve(VarResolverSession session, String key) throws Exception {
+ RestRequest req = session.getSessionObject(RestRequest.class, SESSION_req);
+ ReaderResource rr = req.getReaderResource(key);
+ return (rr == null ? null : rr.toCommentStrippedString());
+ }
+}
\ No newline at end of file
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/FileVar.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/LocalizationVar.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/LocalizationVar.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/LocalizationVar.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,61 @@
+// ***************************************************************************************************************************
+// * 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.vars;
+
+import java.util.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.svl.*;
+
+/**
+ * Localized string variable resolver.
+ *
+ * <p>
+ * The format for this var is <js>"$L{key[,args...]}"</js>.
+ *
+ * <p>
+ * This variable resolver requires that a {@link RestRequest} object be set as a context object on the resolver or a
+ * session object on the resolver session.
+ *
+ * <p>
+ * Values are pulled from the {@link RestRequest#getMessage(String,Object[])} method.
+ * These in turn are pulled from the resource bundle associated with the servlet class where the request was made.
+ *
+ * <p>
+ * Since this is a {@link SimpleVar}, any variables contained in the result will be recursively resolved.
+ * Likewise, if the arguments contain any variables, those will be resolved before they are passed to this var.
+ *
+ * @see org.apache.juneau.svl
+ */
+public class LocalizationVar extends MultipartVar {
+
+ /** The name of this variable. */
+ public static final String NAME = "L";
+
+ /**
+ * Constructor.
+ */
+ public LocalizationVar() {
+ super(NAME);
+ }
+
+ @Override /* Parameter */
+ public String resolve(VarResolverSession session, String[] args) {
+ if (args.length > 0) {
+ String key = args[0];
+ String[] a = (args.length > 1) ? Arrays.copyOfRange(args, 1, args.length) : new String[0];
+ return session.getSessionObject(RestRequest.class, RequestVar.SESSION_req).getMessage(key, (Object[])a);
+ }
+ return "";
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/LocalizationVar.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,101 @@
+// ***************************************************************************************************************************
+// * 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.vars;
+
+import javax.servlet.http.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.svl.*;
+
+/**
+ * Request attribute variable resolver.
+ *
+ * <p>
+ * The format for this var is <js>"$R{key[,defaultValue]}"</js>.
+ *
+ * <p>
+ * The possible values are:
+ * <ul>
+ * <li><js>"contextPath"</js> - Value returned by {@link RestRequest#getContextPath()}
+ * <li><js>"method"</js> - Value returned by {@link RestRequest#getMethod()}
+ * <li><js>"methodDescription"</js> - Value returned by {@link RestRequest#getMethodDescription()}
+ * <li><js>"methodSummary"</js> - Value returned by {@link RestRequest#getMethodSummary()}
+ * <li><js>"pathInfo"</js> - Value returned by {@link RestRequest#getPathInfo()}
+ * <li><js>"requestParentURI"</js> - Value returned by {@link UriContext#getRootRelativePathInfoParent()}
+ * <li><js>"requestURI"</js> - Value returned by {@link RestRequest#getRequestURI()}
+ * <li><js>"servletDescription"</js> - Value returned by {@link RestRequest#getServletDescription()}
+ * <li><js>"servletParentURI"</js> - Value returned by {@link UriContext#getRootRelativeServletPathParent()}
+ * <li><js>"servletPath"</js> - See {@link RestRequest#getServletPath()}
+ * <li><js>"servletTitle"</js> - See {@link RestRequest#getServletTitle()}
+ * <li><js>"servletURI"</js> - See {@link UriContext#getRootRelativeServletPath()}
+ * <li><js>"siteName"</js> - See {@link RestRequest#getSiteName()}
+ * <li><js>"Attribute.x"</js> - Value returned by {@link HttpServletRequest#getAttribute(String)}.
+ * <li><js>"FormData.x"</js> - Value returned by {@link RestRequest#getFormData(String)}.
+ * <li><js>"Header.x"</js> - Value returned by {@link RestRequest#getHeader(String)}.
+ * <li><js>"Path.x"</js> - Value returned by {@link RestRequest#getPath(String)}.
+ * <li><js>"Query.x"</js> = Value returned by {@link RestRequest#getQuery(String)}.
+ * </ul>
+ * <p>
+ * This variable resolver requires that a {@link RestRequest} object be set as a context object on the resolver or a
+ * session object on the resolver session.
+ *
+ * <p>
+ * Since this is a {@link SimpleVar}, any variables contained in the result will be recursively resolved.
+ * Likewise, if the arguments contain any variables, those will be resolved before they are passed to this var.
+ *
+ * @see org.apache.juneau.svl
+ */
+public class RequestVar extends DefaultingVar {
+
+ /**
+ * The name of the session or context object that identifies the {@link RestRequest} object.
+ */
+ public static final String SESSION_req = "req";
+
+
+ /** The name of this variable. */
+ public static final String NAME = "R";
+
+ /**
+ * Constructor.
+ */
+ public RequestVar() {
+ super(NAME);
+ }
+
+ @Override /* Parameter */
+ public String resolve(VarResolverSession session, String key) {
+ RestRequest req = session.getSessionObject(RestRequest.class, SESSION_req);
+ if (key.length() > 0) {
+ String k = key.toString();
+ int i = k.indexOf('.');
+ if (i != -1) {
+ String prefix = k.substring(0, i);
+ String remainder = k.substring(i+1);
+ Object o = req.resolveProperty(null, prefix, remainder);
+ if (o != null)
+ return o.toString();
+ } else {
+ Object o = req.resolveProperty(null, "Request", key);
+ if (o != null)
+ return o.toString();
+ }
+ Object o = req.getProperties().get(key);
+ if (o != null)
+ return o.toString();
+ return req.getPathMatch().get(key);
+ }
+ return null;
+ }
+}
\ No newline at end of file
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/RequestVar.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,67 @@
+// ***************************************************************************************************************************
+// * 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.vars;
+
+import static org.apache.juneau.internal.StringUtils.*;
+
+import java.io.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.svl.*;
+
+/**
+ * Serialized request attribute variable resolver.
+ *
+ * <p>
+ * The format for this var is <js>"$SA{contentType,key[,defaultValue]}"</js>.
+ *
+ * <p>
+ * This variable resolver requires that a {@link RestRequest} object be set as a context object on the resolver or a
+ * session object on the resolver session.
+ *
+ * <p>
+ * Since this is a {@link SimpleVar}, any variables contained in the result will be recursively resolved.
+ * Likewise, if the arguments contain any variables, those will be resolved before they are passed to this var.
+ *
+ * @see org.apache.juneau.svl
+ */
+public class SerializedRequestAttrVar extends StreamedVar {
+
+ /** The name of this variable. */
+ public static final String NAME = "SA";
+
+ /**
+ * Constructor.
+ */
+ public SerializedRequestAttrVar() {
+ super(NAME);
+ }
+
+ @Override /* Parameter */
+ public void resolveTo(VarResolverSession session, Writer w, String key) throws Exception {
+ int i = key.indexOf(',');
+ if (i == -1)
+ throw new RuntimeException("Invalid format for $SA var. Must be of the format $SA{contentType,key[,defaultValue]}");
+ String[] s2 = split(key);
+ RestRequest req = session.getSessionObject(RestRequest.class, RequestVar.SESSION_req);
+ if (req != null) {
+ Object o = req.getAttribute(key);
+ if (o == null)
+ o = key;
+ Serializer s = req.getSerializerGroup().getSerializer(s2[0]);
+ if (s != null)
+ s.serialize(w, o);
+ }
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/ServletInitParamVar.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/ServletInitParamVar.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/ServletInitParamVar.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,53 @@
+// ***************************************************************************************************************************
+// * 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.vars;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.svl.*;
+
+/**
+ * Servlet init parameter variable resolver.
+ *
+ * <p>
+ * The format for this var is <js>"$I{key[,defaultValue]}"</js>.
+ *
+ * <p>
+ * This variable resolver requires that a {@link RestRequest} object be set as a context object on the resolver or a
+ * session object on the resolver session.
+ *
+ * <p>
+ * Values are pulled from the {@link RestServlet#getInitParameter(String)} method.
+ *
+ * <p>
+ * Since this is a {@link SimpleVar}, any variables contained in the result will be recursively resolved.
+ * Likewise, if the arguments contain any variables, those will be resolved before they are passed to this var.
+ *
+ * @see org.apache.juneau.svl
+ */
+public class ServletInitParamVar extends DefaultingVar {
+
+ /** The name of this variable. */
+ public static final String NAME = "I";
+
+ /**
+ * Constructor.
+ */
+ public ServletInitParamVar() {
+ super(NAME);
+ }
+
+ @Override /* Parameter */
+ public String resolve(VarResolverSession session, String key) {
+ return session.getSessionObject(RestRequest.class, RequestVar.SESSION_req).getContext().getServletInitParameter(key);
+ }
+}
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/ServletInitParamVar.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/UrlEncodeVar.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/UrlEncodeVar.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/UrlEncodeVar.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,52 @@
+// ***************************************************************************************************************************
+// * 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.vars;
+
+import static org.apache.juneau.internal.StringUtils.*;
+
+import org.apache.juneau.internal.*;
+import org.apache.juneau.svl.*;
+
+/**
+ * URL-encoding variable resolver.
+ *
+ * <p>
+ * The format for this var is <js>"$UE{uriPart}"</js>.
+ *
+ * <p>
+ * This variable takes the contents inside the variable and replaces it with a value returned by calling
+ * {@link StringUtils#urlEncode(String)}).
+ *
+ * <p>
+ * Since this is a {@link SimpleVar}, any variables contained in the result will be recursively resolved.
+ * Likewise, if the arguments contain any variables, those will be resolved before they are passed to this var.
+ *
+ * @see org.apache.juneau.svl
+ */
+public class UrlEncodeVar extends SimpleVar {
+
+ /** The name of this variable. */
+ public static final String NAME = "UE";
+
+ /**
+ * Constructor.
+ */
+ public UrlEncodeVar() {
+ super(NAME);
+ }
+
+ @Override /* Parameter */
+ public String resolve(VarResolverSession session, String key) {
+ return urlEncode(key);
+ }
+}
\ No newline at end of file
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/UrlEncodeVar.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/UrlVar.java
==============================================================================
--- release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/UrlVar.java (added)
+++ release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/UrlVar.java Fri Sep 8 23:25:34 2017
@@ -0,0 +1,62 @@
+// ***************************************************************************************************************************
+// * 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.vars;
+
+import org.apache.juneau.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.svl.*;
+
+/**
+ * URL variable resolver.
+ *
+ * <p>
+ * The format for this var is <js>"$U{uri}"</js>.
+ *
+ * <p>
+ * The advantage of using this variable is that you can resolve URLs with special protocols such as
+ * <js>"servlet:/xxx"</js>.
+ *
+ * <p>
+ * See {@link UriResolver} for the kinds of URIs that can be resolved.
+ * <ul>
+ * <li>{@link HtmlDoc#widgets() @HtmlDoc.widgets()}
+ * <li>{@link RestConfig#addHtmlWidget(Class)}
+ * </ul>
+ *
+ * <p>
+ * Uses the URI resolver returned by {@link RestRequest#getUriResolver(UriResolution, UriRelativity)} with resolution
+ * {@link UriResolution#ROOT_RELATIVE} and relativity {@link UriRelativity#RESOURCE}.
+ *
+ * @see org.apache.juneau.svl
+ */
+public class UrlVar extends SimpleVar {
+
+ private static final String SESSION_req = "req";
+
+ /** The name of this variable. */
+ public static final String NAME = "U";
+
+ /**
+ * Constructor.
+ */
+ public UrlVar() {
+ super(NAME);
+ }
+
+ @Override /* Parameter */
+ public String resolve(VarResolverSession session, String key) {
+ RestRequest req = session.getSessionObject(RestRequest.class, SESSION_req);
+ return req.getUriResolver().resolve(key);
+ }
+}
\ No newline at end of file
Propchange: release/incubator/juneau/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/UrlVar.java
------------------------------------------------------------------------------
svn:mime-type = text/plain