juneau-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamesbog...@apache.org
Subject juneau git commit: RestContext refactoring.
Date Sat, 06 Jan 2018 01:55:44 GMT
Repository: juneau
Updated Branches:
  refs/heads/master 30ac20a16 -> b766e1d07


RestContext refactoring.

Project: http://git-wip-us.apache.org/repos/asf/juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/juneau/commit/b766e1d0
Tree: http://git-wip-us.apache.org/repos/asf/juneau/tree/b766e1d0
Diff: http://git-wip-us.apache.org/repos/asf/juneau/diff/b766e1d0

Branch: refs/heads/master
Commit: b766e1d07d2add197d3735cb5c08669013ad107f
Parents: 30ac20a
Author: JamesBognar <jamesbognar@apache.org>
Authored: Fri Jan 5 20:55:39 2018 -0500
Committer: JamesBognar <jamesbognar@apache.org>
Committed: Fri Jan 5 20:55:39 2018 -0500

----------------------------------------------------------------------
 juneau-doc/src/main/javadoc/overview.html       |   2 +-
 .../java/org/apache/juneau/rest/RestChild.java  |  36 ++
 .../org/apache/juneau/rest/RestContext.java     |  89 +++-
 .../apache/juneau/rest/RestContextBuilder.java  | 418 ++++++++++---------
 .../juneau/rest/RestResourceResolver.java       |   6 +-
 .../juneau/rest/RestResourceResolverSimple.java |  20 +-
 .../juneau/rest/annotation/RestResource.java    |  35 +-
 .../java/org/apache/juneau/rest/package.html    |   8 +-
 8 files changed, 394 insertions(+), 220 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/juneau/blob/b766e1d0/juneau-doc/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index 98c60a9..46901ca 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -4493,7 +4493,7 @@
 				The <l>children</l> annotation approach simply makes it easier to define
them without having to touch the 
 				<l>web.xml</l> file again.
 				Child resources can also be defined programmatically by using the 
-				{@link org.apache.juneau.rest.RestContextBuilder#childResources(Class[])} method.
+				{@link org.apache.juneau.rest.RestContextBuilder#children(Class[])} method.
 			</p>
 			<p>
 				Note that these router pages can be arbitrarily nested deep.  

http://git-wip-us.apache.org/repos/asf/juneau/blob/b766e1d0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
new file mode 100644
index 0000000..8817192
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
@@ -0,0 +1,36 @@
+// ***************************************************************************************************************************
+// * 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;
+
+/**
+ * Represents a simple child REST resource / path mapping.
+ */
+public class RestChild {
+
+	final String path;
+	final Object resource;
+	
+	/**
+	 * Constructor.
+	 * 
+	 * @param path The child resource path relative to the parent resource URI.
+	 * @param resource 
+	 * 	The child resource.
+	 * 	<br>Can either be a Class (which will be instantiated using the registered {@link
RestResourceResolver}, 
+	 * 	or an already-instantiated object.
+	 */
+	public RestChild(String path, Object resource) {
+		this.path = path;
+		this.resource = resource;
+	}
+}

http://git-wip-us.apache.org/repos/asf/juneau/blob/b766e1d0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index bc2aa30..0810abc 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -199,6 +199,82 @@ public final class RestContext extends BeanContext {
 	public static final String REST_callHandler = PREFIX + "callHandler.o";
 
 	/**
+	 * <b>Configuration property:</b>  Children.
+	 *
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RestContext.children.lo"</js>
+	 * 	<li><b>Data type:</b> <code>List&lt;Class | Object | RestChild&gt;</code>
+	 * 	<li><b>Default:</b> empty list
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * 
+	 * <p>
+	 * Defines children of this resource.
+	 *
+	 * <p>
+	 * A REST child resource is simply another servlet or object that is initialized as part
of the parent resource and has a
+	 * servlet path directly under the parent servlet path.
+	 * <br>The main advantage to defining servlets as REST children is that you do not
need to define them in the
+	 * <code>web.xml</code> file of the web application.
+	 * <br>This can cut down on the number of entries that show up in the <code>web.xml</code>
file if you are defining
+	 * large numbers of servlets.
+	 *
+	 * <p>
+	 * Child resources must specify a value for {@link RestResource#path()} that identifies
the subpath of the child resource
+	 * relative to the parent path.
+	 *
+	 * <p>
+	 * Child resources can be nested arbitrarily deep using this technique (i.e. children can
also have children).
+	 *
+	 * <dl>
+	 * 	<dt>Servlet initialization:</dt>
+	 * 	<dd>
+	 * 		<p>
+	 * 			A child resource will be initialized immediately after the parent servlet is initialized.
+	 * 			The child resource receives the same servlet config as the parent resource.
+	 * 			This allows configuration information such as servlet initialization parameters to
filter to child
+	 * 			resources.
+	 * 		</p>
+	 * 	</dd>
+	 * 	<dt>Runtime behavior:</dt>
+	 * 	<dd>
+	 * 		<p>
+	 * 			As a rule, methods defined on the <code>HttpServletRequest</code> object
will behave as if the child
+	 * 			servlet were deployed as a top-level resource under the child's servlet path.
+	 * 			For example, the <code>getServletPath()</code> and <code>getPathInfo()</code>
methods on the
+	 * 			<code>HttpServletRequest</code> object will behave as if the child resource
were deployed using the
+	 * 			child's servlet path.
+	 * 			Therefore, the runtime behavior should be equivalent to deploying the child servlet
in the
+	 * 			<code>web.xml</code> file of the web application.
+	 * 		</p>
+	 * 	</dd>
+	 * </dl>
+	 * 
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property:  {@link RestContext#REST_children}
+	 * 	<li>Annotations:  
+	 * 		<ul>
+	 * 			<li>{@link RestResource#children()}
+	 * 		</ul>
+	 * 	<li>Methods: 
+	 * 		<ul>
+	 * 			<li>{@link RestContextBuilder#child(String,Object)}
+	 * 			<li>{@link RestContextBuilder#children(Class...)}
+	 * 			<li>{@link RestContextBuilder#children(Object...)}
+	 * 		</ul>
+	 * 	<li>When defined as classes, instances are resolved using the registered {@link
#REST_resourceResolver} which
+	 * 		by default is {@link RestResourceResolverSimple} which requires the class have one
of the following
+	 * 		constructors:
+	 * 		<ul>
+	 * 			<li><code><jk>public</jk> T(RestContextBuilder)</code>
+	 * 			<li><code><jk>public</jk> T()</code>
+	 * 		</ul>
+	 *	</ul>
+	 */
+	public static final String REST_children = PREFIX + "children.lo";
+
+	/**
 	 * <b>Configuration property:</b>  Classpath resource finder. 
 	 *
 	 * <ul>
@@ -1400,7 +1476,6 @@ public final class RestContext extends BeanContext {
 	 * @param builder The servlet configuration object.
 	 * @throws Exception If any initialization problems were encountered.
 	 */
-	@SuppressWarnings("unchecked")
 	public RestContext(RestContextBuilder builder) throws Exception {
 		super(builder.getPropertyStore());
 		
@@ -1701,13 +1776,13 @@ public final class RestContext extends BeanContext {
 
 			// Initialize our child resources.
 			resourceResolver = getInstanceProperty(REST_resourceResolver, resource, RestResourceResolver.class,
parentContext == null ? RestResourceResolverSimple.class : parentContext.resourceResolver,
true, this, ps);
-			for (Object o : builder.childResources) {
+			for (Object o : getArrayProperty(REST_children, Object.class)) {
 				String path = null;
 				Object r = null;
-				if (o instanceof Pair) {
-					Pair<String,Object> p = (Pair<String,Object>)o;
-					path = p.first();
-					r = p.second();
+				if (o instanceof RestChild) {
+					RestChild rc = (RestChild)o;
+					path = rc.path;
+					r = rc.resource;
 				} else if (o instanceof Class<?>) {
 					Class<?> c = (Class<?>)o;
 					// Don't allow specifying yourself as a child.  Causes an infinite loop.
@@ -1723,7 +1798,7 @@ public final class RestContext extends BeanContext {
 				if (o instanceof Class) {
 					Class<?> oc = (Class<?>)o;
 					childBuilder = new RestContextBuilder(builder.inner, oc, this);
-					r = resourceResolver.resolve(oc, childBuilder);
+					r = resourceResolver.resolve(resource, oc, childBuilder);
 				} else {
 					r = o;
 					childBuilder = new RestContextBuilder(builder.inner, o.getClass(), this);

http://git-wip-us.apache.org/repos/asf/juneau/blob/b766e1d0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
index 8a3d14c..3d727f6 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
@@ -98,8 +98,6 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon
 	ObjectMap properties;
 	ConfigFile configFile;
 	VarResolverBuilder varResolverBuilder;
-
-	List<Object> childResources = new ArrayList<>();
 	String path;
 	HtmlDocBuilder htmlDocBuilder;
 
@@ -199,7 +197,7 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 				responseHandlers(r.responseHandlers());
 				converters(r.converters());
 				guards(reverse(r.guards()));
-				childResources(r.children());
+				children(r.children());
 				beanFilters(r.beanFilters());
 				pojoSwaps(r.pojoSwaps());
 				paramResolvers(r.paramResolvers());
@@ -412,60 +410,6 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 	}
 
 	/**
-	 * Adds a child resource to this resource.
-	 *
-	 * <p>
-	 * Child resources are resources that are accessed under the path of the parent resource.
-	 *
-	 * <p>
-	 * This is the programmatic equivalent to the {@link RestResource#children() @RestResource.children()}
annotation.
-	 *
-	 * @param path The child path of the resource.  Must conform to {@link RestResource#path()}
format.
-	 * @param child The child resource.
-	 * @return This object (for method chaining).
-	 */
-	public RestContextBuilder childResource(String path, Object child) {
-		this.childResources.add(new Pair<>(path, child));
-		return this;
-	}
-
-	/**
-	 * Add child resources to this resource.
-	 *
-	 * <p>
-	 * Child resources are resources that are accessed under the path of the parent resource.
-	 *
-	 * <p>
-	 * This is the programmatic equivalent to the {@link RestResource#children() @RestResource.children()}
annotation.
-	 *
-	 * @param children The child resources to add to this resource.
-	 * Children must be annotated with {@link RestResource#path()} to identify the child path.
-	 * @return This object (for method chaining).
-	 */
-	public RestContextBuilder childResources(Object...children) {
-		this.childResources.addAll(Arrays.asList(children));
-		return this;
-	}
-
-	/**
-	 * Add child resources to this resource.
-	 *
-	 * <p>
-	 * Child resources are resources that are accessed under the path of the parent resource.
-	 *
-	 * <p>
-	 * This is the programmatic equivalent to the {@link RestResource#children() @RestResource.children()}
annotation.
-	 *
-	 * @param children The child resources to add to this resource.
-	 * Children must be annotated with {@link RestResource#path()} to identify the child path.
-	 * @return This object (for method chaining).
-	 */
-	public RestContextBuilder childResources(Class<?>...children) {
-		this.childResources.addAll(Arrays.asList(children));
-		return this;
-	}
-
-	/**
 	 * Returns an instance of an HTMLDOC builder for setting HTMLDOC-related properties.
 	 * 
 	 * @return An instance of an HTMLDOC builder for setting HTMLDOC-related properties.
@@ -561,73 +505,77 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 	//----------------------------------------------------------------------------------------------------
 
 	/**
-	 * <b>Configuration property:</b>  Resource path.   
+	 * <b>Configuration property:</b>  Allow body URL parameter.
 	 *
-	 * <p>
-	 * Identifies the URL subpath relative to the parent resource.
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RestContext.allowBodyParam.b"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
 	 *
 	 * <p>
+	 * When enabled, the HTTP body content on PUT and POST requests can be passed in as text
using the <js>"body"</js>
+	 * URL parameter.
+	 * <br>
+	 * For example:  <js>"?body=(name='John%20Smith',age=45)"</js>
+	 * 
 	 * <h5 class='section'>Notes:</h5>
 	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_path}
+	 * 	<li>Property:  {@link RestContext#REST_allowBodyParam}
 	 * 	<li>Annotations:
 	 * 		<ul>
-	 * 			<li>{@link RestResource#path()}
-	 * 		</ul> 
+	 * 			<li>{@link RestResource#allowBodyParam()}
+	 * 		</ul>
 	 * 	<li>Methods:
 	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#path(String)} 
+	 * 			<li>{@link RestContextBuilder#allowBodyParam(boolean)}
 	 * 		</ul>
-	 * 	<li>This annotation is ignored on top-level servlets (i.e. servlets defined in
<code>web.xml</code> files).
-	 * 		<br>Therefore, implementers can optionally specify a path value for documentation
purposes.
-	 * 	<li>Typically, this setting is only applicable to resources defined as children
through the 
-	 * 		{@link RestResource#children()} annotation.
-	 * 		<br>However, it may be used in other ways (e.g. defining paths for top-level
resources in microservices).
+	 * 	<li>Parameter name is case-insensitive.
+	 * 	<li>Useful for debugging PUT and POST methods using only a browser.
 	 *	</ul>
 	 *
-	 * @param path The URL path of this resource.
+	 * @param value The new value for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public RestContextBuilder path(String path) {
-		if (startsWith(path, '/'))
-			path = path.substring(1);
-		this.path = path;
-		return this;
+	public RestContextBuilder allowBodyParam(boolean value) {
+		return set(REST_allowBodyParam, value);
 	}
 
 	/**
-	 * <b>Configuration property:</b>  Resource context path. 
+	 * <b>Configuration property:</b>  Allowed method parameters.
 	 *
 	 * <p>
-	 * Overrides the context path value for this resource and any child resources.
+	 * When specified, the HTTP method can be overridden by passing in a <js>"method"</js>
URL parameter on a regular
+	 * GET request.
+	 * <br>
+	 * For example:  <js>"?method=OPTIONS"</js>
 	 *
-	 * <p>
-	 * This setting is useful if you want to use <js>"context:/child/path"</js>
URLs in child resource POJOs but
-	 * the context path is not actually specified on the servlet container.
-	 * The net effect is that the {@link RestRequest#getContextPath()} and {@link RestRequest#getServletPath()}
methods
-	 * will return this value instead of the actual context path of the web app.
-	 * 
-	 * <p>
 	 * <h5 class='section'>Notes:</h5>
 	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_contextPath}
+	 * 	<li>Property:  {@link RestContext#REST_allowedMethodParams}
 	 * 	<li>Annotations:
 	 * 		<ul>
-	 * 			<li>{@link RestResource#contextPath()} 
+	 * 			<li>{@link RestResource#allowedMethodParams()}
 	 * 		</ul>
 	 * 	<li>Methods:
 	 * 		<ul>
-	 * 			<li>@link RestContextBuilder#contextPath(String)} 
+	 * 			<li>{@link RestContextBuilder#allowedMethodParams(String...)}
 	 * 		</ul>
+	 * 	<li>Parameter name is case-insensitive.
+	 * 	<li>Use "*" to represent all methods.
 	 *	</ul>
 	 *
-	 * @param contextPath The context path for this resource and any child resources.
+	 * <p>
+	 * Note that per the <a class="doclink"
+	 * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">HTTP specification</a>,
special care should
+	 * be taken when allowing non-safe (POST, PUT, DELETE) methods to be invoked through GET
requests.
+	 *
+	 * @param value The new value for this setting.
 	 * @return This object (for method chaining).
 	 */
-	public RestContextBuilder contextPath(String contextPath) {
-		if (! contextPath.isEmpty())
-			set(REST_contextPath, contextPath);
-		return this;
+	public RestContextBuilder allowedMethodParams(String...value) {
+		return set(REST_allowedMethodParams, StringUtils.join(value, ','));
 	}
 
 	/**
@@ -662,77 +610,229 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 	}
 
 	/**
-	 * <b>Configuration property:</b>  Allow body URL parameter.
-	 *
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"RestContext.allowBodyParam.b"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
+	 * <b>Configuration property:</b>  REST call handler.
 	 *
 	 * <p>
-	 * When enabled, the HTTP body content on PUT and POST requests can be passed in as text
using the <js>"body"</js>
-	 * URL parameter.
-	 * <br>
-	 * For example:  <js>"?body=(name='John%20Smith',age=45)"</js>
-	 * 
+	 * This class handles the basic lifecycle of an HTTP REST call.
+	 * <br>Subclasses can be used to customize how these HTTP calls are handled.
+
+	 * <p>
 	 * <h5 class='section'>Notes:</h5>
 	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_allowBodyParam}
+	 * 	<li>Property:  {@link RestContext#REST_callHandler}
 	 * 	<li>Annotations:
 	 * 		<ul>
-	 * 			<li>{@link RestResource#allowBodyParam()}
+	 * 			<li>{@link RestResource#callHandler()} 
 	 * 		</ul>
 	 * 	<li>Methods:
 	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#allowBodyParam(boolean)}
+	 * 			<li>{@link RestContextBuilder#callHandler(Class)}
+	 * 			<li>{@link RestContextBuilder#callHandler(RestCallHandler)} 
 	 * 		</ul>
-	 * 	<li>Parameter name is case-insensitive.
-	 * 	<li>Useful for debugging PUT and POST methods using only a browser.
 	 *	</ul>
 	 *
-	 * @param value The new value for this setting.
+	 * @param restHandler The new call handler for this resource.
 	 * @return This object (for method chaining).
 	 */
-	public RestContextBuilder allowBodyParam(boolean value) {
-		return set(REST_allowBodyParam, value);
+	public RestContextBuilder callHandler(Class<? extends RestCallHandler> restHandler)
{
+		return set(REST_callHandler, restHandler);
 	}
 
 	/**
-	 * <b>Configuration property:</b>  Allowed method parameters.
+	 * <b>Configuration property:</b>  REST call handler.
 	 *
 	 * <p>
-	 * When specified, the HTTP method can be overridden by passing in a <js>"method"</js>
URL parameter on a regular
-	 * GET request.
-	 * <br>
-	 * For example:  <js>"?method=OPTIONS"</js>
+	 * Same as {@link #callHandler(Class)} but allows you to pass in a call handler instance.
+	 * 
+	 * @param restHandler The new call handler for this resource.
+	 * @return This object (for method chaining).
+	 */
+	public RestContextBuilder callHandler(RestCallHandler restHandler) {
+		return set(REST_callHandler, restHandler);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Children.
+	 *
+	 * <p>
+	 * Defines children of this resource.
+	 *
+	 * <p>
+	 * A REST child resource is simply another servlet that is initialized as part of the parent
resource and has a
+	 * servlet path directly under the parent servlet path.
+	 * <br>The main advantage to defining servlets as REST children is that you do not
need to define them in the
+	 * <code>web.xml</code> file of the web application.
+	 * <br>This can cut down on the number of entries that show up in the <code>web.xml</code>
file if you are defining
+	 * large numbers of servlets.
+	 *
+	 * <p>
+	 * Child resources must specify a value for {@link RestResource#path()} that identifies
the subpath of the child resource
+	 * relative to the parent path.
 	 *
+	 * <p>
+	 * It should be noted that servlets can be nested arbitrarily deep using this technique
(i.e. children can also have
+	 * children).
+	 *
+	 * <dl>
+	 * 	<dt>Servlet initialization:</dt>
+	 * 	<dd>
+	 * 		<p>
+	 * 			A child resource will be initialized immediately after the parent servlet is initialized.
+	 * 			The child resource receives the same servlet config as the parent resource.
+	 * 			This allows configuration information such as servlet initialization parameters to
filter to child
+	 * 			resources.
+	 * 		</p>
+	 * 	</dd>
+	 * 	<dt>Runtime behavior:</dt>
+	 * 	<dd>
+	 * 		<p>
+	 * 			As a rule, methods defined on the <code>HttpServletRequest</code> object
will behave as if the child
+	 * 			servlet were deployed as a top-level resource under the child's servlet path.
+	 * 			For example, the <code>getServletPath()</code> and <code>getPathInfo()</code>
methods on the
+	 * 			<code>HttpServletRequest</code> object will behave as if the child resource
were deployed using the
+	 * 			child's servlet path.
+	 * 			Therefore, the runtime behavior should be equivalent to deploying the child servlet
in the
+	 * 			<code>web.xml</code> file of the web application.
+	 * 		</p>
+	 * 	</dd>
+	 * </dl>
+	 * 
 	 * <h5 class='section'>Notes:</h5>
 	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_allowedMethodParams}
-	 * 	<li>Annotations:
+	 * 	<li>Property:  {@link RestContext#REST_children}
+	 * 	<li>Annotations:  
 	 * 		<ul>
-	 * 			<li>{@link RestResource#allowedMethodParams()}
+	 * 			<li>{@link RestResource#children()}
+	 * 		</ul>
+	 * 	<li>Methods: 
+	 * 		<ul>
+	 * 			<li>{@link RestContextBuilder#child(String,Object)}
+	 * 			<li>{@link RestContextBuilder#children(Class...)}
+	 * 			<li>{@link RestContextBuilder#children(Object...)}
+	 * 		</ul>
+	 * 	<li>When defined as classes, instances are resolved using the registered {@link
RestContext#REST_resourceResolver} which
+	 * 		by default is {@link RestResourceResolverSimple} which requires the class have one
of the following
+	 * 		constructors:
+	 * 		<ul>
+	 * 			<li><code><jk>public</jk> T(RestContextBuilder)</code>
+	 * 			<li><code><jk>public</jk> T()</code>
 	 * 		</ul>
+	 *	</ul>
+	 * 
+	 * @param children The children to add to this resource..
+	 * @return This object (for method chaining).
+	 */
+	public RestContextBuilder children(Class<?>...children) {
+		return addTo(REST_children, children);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Children.
+	 *
+	 * <p>
+	 * Same as {@link #children(Class...)} but allows you to pass in already-constructed child
instances.
+	 * 
+	 * @param children 
+	 * 	The children to add to this resource.
+	 * 	<br>Objects can be any of the following:
+	 * 	<ul>
+	 * 		<li>A class that can be resolved to an instance using the registered {@link RestContext#REST_resourceResolver
resource resolver}.
+	 * 			<br>The class must specify a {@link RestResource#path()} annotation to identify
parent-relative path for the child.
+	 * 		<li>A resource instance.
+	 * 			<br>The class must specify a {@link RestResource#path()} annotation to identify
parent-relative path for the child.
+	 * 		<li>An instance of {@link RestChild} that defines the path/resource mapping.
+	 * 	</ul>
+	 * @return This object (for method chaining).
+	 */
+	public RestContextBuilder children(Object...children) {
+		return addTo(REST_children, children);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Children.
+	 *
+	 * <p>
+	 * Shortcut for adding a single child to this resource.
+	 * 
+	 * <p>
+	 * This can be used for resources that don't have a {@link RestResource#path()} annotation.
+	 * 
+	 * @param path The child path relative to the parent resource URI.
+	 * @param child The child to add to this resource.
+	 * @return This object (for method chaining).
+	 */
+	public RestContextBuilder child(String path, Object child) {
+		return addTo(REST_children, new RestChild(path, child));
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Resource path.   
+	 *
+	 * <p>
+	 * Identifies the URL subpath relative to the parent resource.
+	 *
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property:  {@link RestContext#REST_path}
+	 * 	<li>Annotations:
+	 * 		<ul>
+	 * 			<li>{@link RestResource#path()}
+	 * 		</ul> 
 	 * 	<li>Methods:
 	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#allowedMethodParams(String...)}
+	 * 			<li>{@link RestContextBuilder#path(String)} 
 	 * 		</ul>
-	 * 	<li>Parameter name is case-insensitive.
-	 * 	<li>Use "*" to represent all methods.
+	 * 	<li>This annotation is ignored on top-level servlets (i.e. servlets defined in
<code>web.xml</code> files).
+	 * 		<br>Therefore, implementers can optionally specify a path value for documentation
purposes.
+	 * 	<li>Typically, this setting is only applicable to resources defined as children
through the 
+	 * 		{@link RestResource#children()} annotation.
+	 * 		<br>However, it may be used in other ways (e.g. defining paths for top-level
resources in microservices).
 	 *	</ul>
 	 *
+	 * @param path The URL path of this resource.
+	 * @return This object (for method chaining).
+	 */
+	public RestContextBuilder path(String path) {
+		if (startsWith(path, '/'))
+			path = path.substring(1);
+		this.path = path;
+		return this;
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Resource context path. 
+	 *
 	 * <p>
-	 * Note that per the <a class="doclink"
-	 * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">HTTP specification</a>,
special care should
-	 * be taken when allowing non-safe (POST, PUT, DELETE) methods to be invoked through GET
requests.
+	 * Overrides the context path value for this resource and any child resources.
 	 *
-	 * @param value The new value for this setting.
+	 * <p>
+	 * This setting is useful if you want to use <js>"context:/child/path"</js>
URLs in child resource POJOs but
+	 * the context path is not actually specified on the servlet container.
+	 * The net effect is that the {@link RestRequest#getContextPath()} and {@link RestRequest#getServletPath()}
methods
+	 * will return this value instead of the actual context path of the web app.
+	 * 
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property:  {@link RestContext#REST_contextPath}
+	 * 	<li>Annotations:
+	 * 		<ul>
+	 * 			<li>{@link RestResource#contextPath()} 
+	 * 		</ul>
+	 * 	<li>Methods:
+	 * 		<ul>
+	 * 			<li>@link RestContextBuilder#contextPath(String)} 
+	 * 		</ul>
+	 *	</ul>
+	 *
+	 * @param contextPath The context path for this resource and any child resources.
 	 * @return This object (for method chaining).
 	 */
-	public RestContextBuilder allowedMethodParams(String...value) {
-		return set(REST_allowedMethodParams, StringUtils.join(value, ','));
+	public RestContextBuilder contextPath(String contextPath) {
+		if (! contextPath.isEmpty())
+			set(REST_contextPath, contextPath);
+		return this;
 	}
 
 	/**
@@ -1632,64 +1732,6 @@ public class RestContextBuilder extends BeanContextBuilder implements
ServletCon
 	}
 
 	/**
-	 * <b>Configuration property:</b>  REST call handler.
-	 *
-	 * <p>
-	 * This class handles the basic lifecycle of an HTTP REST call.
-	 * <br>Subclasses can be used to customize how these HTTP calls are handled.
-
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_callHandler}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#callHandler()} 
-	 * 		</ul>
-	 * 	<li>Methods:
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#callHandler(Class)}
-	 * 			<li>{@link RestContextBuilder#callHandler(RestCallHandler)} 
-	 * 		</ul>
-	 *	</ul>
-	 *
-	 * @param restHandler The new call handler for this resource.
-	 * @return This object (for method chaining).
-	 */
-	public RestContextBuilder callHandler(Class<? extends RestCallHandler> restHandler)
{
-		return set(REST_callHandler, restHandler);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  REST call handler.
-	 *
-	 * <p>
-	 * This class handles the basic lifecycle of an HTTP REST call.
-	 * <br>Subclasses can be used to customize how these HTTP calls are handled.
-	 * 
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>Property:  {@link RestContext#REST_callHandler}
-	 * 	<li>Annotations:
-	 * 		<ul>
-	 * 			<li>{@link RestResource#callHandler()} 
-	 * 		</ul>
-	 * 	<li>Methods:
-	 * 		<ul>
-	 * 			<li>{@link RestContextBuilder#callHandler(Class)}
-	 * 			<li>{@link RestContextBuilder#callHandler(RestCallHandler)} 
-	 * 		</ul>
-	 *	</ul>
-	 *
-	 * @param restHandler The new call handler for this resource.
-	 * @return This object (for method chaining).
-	 */
-	public RestContextBuilder callHandler(RestCallHandler restHandler) {
-		return set(REST_callHandler, restHandler);
-	}
-
-	/**
 	 * <b>Configuration property:</b>  REST info provider. 
 	 *
 	 * <p>

http://git-wip-us.apache.org/repos/asf/juneau/blob/b766e1d0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolver.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolver.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolver.java
index aef11de..8489a29 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolver.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolver.java
@@ -45,11 +45,13 @@ public interface RestResourceResolver {
 	 *
 	 * <p>
 	 * The default implementation simply creates a new class instance using {@link Class#newInstance()}.
-	 *
+	 * 
+	 * @param parent 
+	 * 	The parent resource (i.e. the instance whose class has the {@link RestResource#children()}
annotation.
 	 * @param c The class to resolve.
 	 * @param builder The initialization configuration for the resource.
 	 * @return The instance of that class.
 	 * @throws Exception If class could not be resolved.
 	 */
-	Object resolve(Class<?> c, RestContextBuilder builder) throws Exception;
+	Object resolve(Object parent, Class<?> c, RestContextBuilder builder) throws Exception;
 }

http://git-wip-us.apache.org/repos/asf/juneau/blob/b766e1d0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolverSimple.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolverSimple.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolverSimple.java
index eda2fe2..0121558 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolverSimple.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResourceResolverSimple.java
@@ -12,12 +12,10 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest;
 
-import static org.apache.juneau.internal.ClassUtils.*;
-
-import java.lang.reflect.*;
+import org.apache.juneau.internal.*;
 
 /**
- * Denotes the default resolver.
+ * Denotes the default resolver for child resources.
  *
  * The default implementation simply instantiates the class using one of the following constructors:
  * <ul>
@@ -29,6 +27,9 @@ import java.lang.reflect.*;
  * The former constructor can be used to get access to the {@link RestContextBuilder} object
to get access to the
  * config file and initialization information or make programmatic modifications to the resource
before
  * full initialization.
+ * 
+ * <p>
+ * Child classes can also be defined as inner-classes of the parent resource class.
  *
  * <p>
  * Non-<code>RestServlet</code> classes can also add the following method to
get access to the {@link RestContextBuilder} 
@@ -41,14 +42,11 @@ import java.lang.reflect.*;
 public class RestResourceResolverSimple implements RestResourceResolver {
 
 	@Override /* RestResourceResolver */
-	public Object resolve(Class<?> c, RestContextBuilder builder) throws Exception {
+	public Object resolve(Object parent, Class<?> c, RestContextBuilder builder) throws
Exception {
 		try {
-			Constructor<?> c1 = findPublicConstructor(c, RestContextBuilder.class);
-			if (c1 != null)
-				return c1.newInstance(builder);
-			c1 = findPublicConstructor(c);
-			if (c1 != null)
-				return c1.newInstance();
+			Object r = ClassUtils.newInstanceFromOuter(parent, Object.class, c, true, builder);
+			if (r != null)
+				return r;
 		} catch (Exception e) {
 			throw new RestServletException("Could not instantiate resource class ''{0}''", c.getName()).initCause(e);
 		}

http://git-wip-us.apache.org/repos/asf/juneau/blob/b766e1d0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
index de0f449..58ccab0 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
@@ -613,18 +613,21 @@ public @interface RestResource {
 	String[] defaultResponseHeaders() default {};
 
 	/**
+	 *Children.
+	 *
+	 * <p>
 	 * Defines children of this resource.
 	 *
 	 * <p>
 	 * A REST child resource is simply another servlet that is initialized as part of the parent
resource and has a
 	 * servlet path directly under the parent servlet path.
-	 * The main advantage to defining servlets as REST children is that you do not need to define
them in the
+	 * <br>The main advantage to defining servlets as REST children is that you do not
need to define them in the
 	 * <code>web.xml</code> file of the web application.
-	 * This can cut down on the number of entries that show up in the <code>web.xml</code>
file if you are defining
+	 * <br>This can cut down on the number of entries that show up in the <code>web.xml</code>
file if you are defining
 	 * large numbers of servlets.
 	 *
 	 * <p>
-	 * Child resources must specify a value for {@link #path()} that identifies the subpath
of the child resource
+	 * Child resources must specify a value for {@link RestResource#path()} that identifies
the subpath of the child resource
 	 * relative to the parent path.
 	 *
 	 * <p>
@@ -654,10 +657,28 @@ public @interface RestResource {
 	 * 		</p>
 	 * 	</dd>
 	 * </dl>
-	 *
-	 * <p>
-	 * The programmatic equivalent to this annotation are the {@link RestContextBuilder#childResource(String,
Object)}/
-	 * {@link RestContextBuilder#childResources(Class...)}/{@link RestContextBuilder#childResources(Object...)}
methods.
+	 * 
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li>Property:  {@link RestContext#REST_children}
+	 * 	<li>Annotations:  
+	 * 		<ul>
+	 * 			<li>{@link RestResource#children()}
+	 * 		</ul>
+	 * 	<li>Methods: 
+	 * 		<ul>
+	 * 			<li>{@link RestContextBuilder#child(String,Object)}
+	 * 			<li>{@link RestContextBuilder#children(Class...)}
+	 * 			<li>{@link RestContextBuilder#children(Object...)}
+	 * 		</ul>
+	 * 	<li>When defined as classes, instances are resolved using the registered {@link
RestContext#REST_resourceResolver} which
+	 * 		by default is {@link RestResourceResolverSimple} which requires the class have one
of the following
+	 * 		constructors:
+	 * 		<ul>
+	 * 			<li><code><jk>public</jk> T(RestContextBuilder)</code>
+	 * 			<li><code><jk>public</jk> T()</code>
+	 * 		</ul>
+	 *	</ul>
 	 */
 	Class<?>[] children() default {};
 

http://git-wip-us.apache.org/repos/asf/juneau/blob/b766e1d0/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/package.html
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/package.html
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/package.html
index ac9a814..b5a3441 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/package.html
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/package.html
@@ -2065,18 +2065,18 @@
 	}		
 		</p>
 		<p>
-			Children can also be defined programmatically by overriding any of the following methods:
+			Children can also be defined programmatically using any of the following methods:
 		</p>
 		<ul class='doctree'>
 			<li class='jac'>
 			{@link org.apache.juneau.rest.RestContextBuilder}
 			<ul>
 				<li class='jm'>
-					{@link org.apache.juneau.rest.RestContextBuilder#childResource(String,Object)}
+					{@link org.apache.juneau.rest.RestContextBuilder#child(String,Object)}
 				<li class='jm'>
-					{@link org.apache.juneau.rest.RestContextBuilder#childResources(Class[])}
+					{@link org.apache.juneau.rest.RestContextBuilder#children(Class[])}
 				<li class='jm'>
-					{@link org.apache.juneau.rest.RestContextBuilder#childResources(Object[])}
+					{@link org.apache.juneau.rest.RestContextBuilder#children(Object[])}
 			</ul> 
 		</ul>
 	</div>



Mime
View raw message