This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 86e055f  Context API refactoring
86e055f is described below

commit 86e055ff8348c673bf9cfd28a47942299e02d43b
Author: JamesBognar <[email protected]>
AuthorDate: Sun Oct 17 12:27:32 2021 -0400

    Context API refactoring
---
 .../main/java/org/apache/juneau/rest/RestCall.java | 143 ++++++++++++---------
 .../java/org/apache/juneau/rest/RestChildren.java  |   2 +-
 .../java/org/apache/juneau/rest/RestContext.java   |  62 +++++----
 3 files changed, 116 insertions(+), 91 deletions(-)

diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
index b3bf530..019e968 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestCall.java
@@ -63,6 +63,8 @@ public class RestCall extends ContextSession {
                HttpServletRequest req;
                HttpServletResponse res;
                RestLogger logger;
+               String pathInfoUndecoded;
+               UrlPath urlPath;
 
                /**
                 * Constructor.
@@ -86,7 +88,7 @@ public class RestCall extends ContextSession {
                }
 
                /**
-                * Specifies the incoming HTTP servlet request object.
+                * Specifies the HTTP servlet request object on this call.
                 *
                 * @param value The value for this setting.
                 * @return This object.
@@ -97,7 +99,18 @@ public class RestCall extends ContextSession {
                }
 
                /**
-                * Specifies the incoming HTTP servlet response object.
+                * Returns the HTTP servlet request object on this call.
+                *
+                * @return The HTTP servlet request object on this call.
+                */
+               public HttpServletRequest req() {
+                       urlPath = null;
+                       pathInfoUndecoded = null;
+                       return req;
+               }
+
+               /**
+                * Specifies the HTTP servlet response object on this call.
                 *
                 * @param value The value for this setting.
                 * @return This object.
@@ -108,6 +121,15 @@ public class RestCall extends ContextSession {
                }
 
                /**
+                * Returns the HTTP servlet response object on this call.
+                *
+                * @return The HTTP servlet response object on this call.
+                */
+               public HttpServletResponse res() {
+                       return res;
+               }
+
+               /**
                 * Specifies the logger to use for this session.
                 *
                 * @param value The value for this setting.
@@ -122,6 +144,47 @@ public class RestCall extends ContextSession {
                public RestCall build() {
                        return new RestCall(this);
                }
+
+               /**
+                * Returns the request path info as a {@link UrlPath} bean.
+                *
+                * @return The request path info as a {@link UrlPath} bean.
+                */
+               public UrlPath getUrlPath() {
+                       if (urlPath == null)
+                               urlPath = UrlPath.of(getPathInfoUndecoded());
+                       return urlPath;
+               }
+
+               /**
+                * Returns the request path info as a {@link UrlPath} bean.
+                *
+                * @return The request path info as a {@link UrlPath} bean.
+                */
+               public String getPathInfoUndecoded() {
+                       if (pathInfoUndecoded == null)
+                               pathInfoUndecoded = 
RestUtils.getPathInfoUndecoded(req);
+                       return pathInfoUndecoded;
+               }
+
+               /**
+                * Adds resolved <c><ja>@Resource</ja>(path)</c> variable 
values to this call.
+                *
+                * @param value The variables to add to this call.
+                * @return This object (for method chaining).
+                */
+               @SuppressWarnings("unchecked")
+               public Builder pathVars(Map<String,String> value) {
+                       if (value != null && ! value.isEmpty()) {
+                               Map<String,String> m = 
(Map<String,String>)req.getAttribute(REST_PATHVARS_ATTR);
+                               if (m == null) {
+                                       m = new TreeMap<>();
+                                       req.setAttribute(REST_PATHVARS_ATTR, m);
+                               }
+                               m.putAll(value);
+                       }
+                       return this;
+               }
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
@@ -130,10 +193,10 @@ public class RestCall extends ContextSession {
 
        private final Object resource;
        private final RestContext context;
-
-       private RestLogger logger;
        private HttpServletRequest req;
        private HttpServletResponse res;
+
+       private RestLogger logger;
        private RestRequest rreq;
        private RestResponse rres;
        private RestOpContext opContext;
@@ -155,11 +218,13 @@ public class RestCall extends ContextSession {
                super(builder);
                context = builder.ctx;
                resource = builder.resource;
-               logger = builder.logger;
-               beanStore = BeanStore.of(context.getRootBeanStore(), resource);
-               beanStore.addBean(RestContext.class, context);
-               beanStore.addBean(RestLogger.class, logger);
-               request(builder.req).response(builder.res);
+               beanStore = BeanStore.of(context.getRootBeanStore(), 
resource).addBean(RestContext.class, context);
+
+               req = beanStore.add(HttpServletRequest.class, builder.req);
+               res = beanStore.add(HttpServletResponse.class, builder.res);
+               logger = beanStore.add(RestLogger.class, builder.logger);
+               urlPath = beanStore.add(UrlPath.class, builder.urlPath);
+               pathInfoUndecoded = builder.pathInfoUndecoded;
        }
 
        
//------------------------------------------------------------------------------------------------------------------
@@ -167,32 +232,6 @@ public class RestCall extends ContextSession {
        
//------------------------------------------------------------------------------------------------------------------
 
        /**
-        * Overrides the request object on the REST call.
-        *
-        * @param value The new HTTP servlet request.
-        * @return This object (for method chaining).
-        */
-       public RestCall request(HttpServletRequest value) {
-               req = value;
-               urlPath = null;
-               pathInfoUndecoded = null;
-               beanStore.addBean(HttpServletRequest.class, value);
-               return this;
-       }
-
-       /**
-        * Overrides the response object on the REST call.
-        *
-        * @param value The new HTTP servlet response.
-        * @return This object (for method chaining).
-        */
-       public RestCall response(HttpServletResponse value) {
-               res = value;
-               beanStore.addBean(HttpServletResponse.class, value);
-               return this;
-       }
-
-       /**
         * Sets the method context on this call.
         *
         * <p>
@@ -203,12 +242,9 @@ public class RestCall extends ContextSession {
         * @throws Exception If thrown from the {@link RestRequest} or {@link 
RestResponse} constructors.
         */
        public RestCall restOpContext(RestOpContext value) throws Exception {
-               opContext = value;
-               beanStore.addBean(RestOpContext.class, value);
-               rreq = context.createRequest(this);
-               beanStore.addBean(RestRequest.class, rreq);
-               rres = context.createResponse(this);
-               beanStore.addBean(RestResponse.class, rres);
+               opContext = beanStore.add(RestOpContext.class, value);
+               rreq = beanStore.add(RestRequest.class, 
context.createRequest(this));
+               rres = beanStore.add(RestResponse.class, 
context.createResponse(this));
                return this;
        }
 
@@ -219,27 +255,7 @@ public class RestCall extends ContextSession {
         * @return This object (for method chaining).
         */
        public RestCall logger(RestLogger value) {
-               logger = value;
-               beanStore.addBean(RestLogger.class, value);
-               return this;
-       }
-
-       /**
-        * Adds resolved <c><ja>@Resource</ja>(path)</c> variable values to 
this call.
-        *
-        * @param value The variables to add to this call.
-        * @return This object (for method chaining).
-        */
-       @SuppressWarnings("unchecked")
-       public RestCall pathVars(Map<String,String> value) {
-               if (value != null && ! value.isEmpty()) {
-                       Map<String,String> m = 
(Map<String,String>)req.getAttribute(REST_PATHVARS_ATTR);
-                       if (m == null) {
-                               m = new TreeMap<>();
-                               req.setAttribute(REST_PATHVARS_ATTR, m);
-                       }
-                       m.putAll(value);
-               }
+               logger = beanStore.add(RestLogger.class, value);
                return this;
        }
 
@@ -316,8 +332,7 @@ public class RestCall extends ContextSession {
         * @return This object (for method chaining).
         */
        public RestCall urlPathMatch(UrlPathMatch value) {
-               urlPathMatch = value;
-               beanStore.addBean(UrlPathMatch.class, value);
+               urlPathMatch = beanStore.add(UrlPathMatch.class, value);
                return this;
        }
 
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
index 3887b70..55c72e3 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
@@ -157,7 +157,7 @@ public class RestChildren {
         * @param call The HTTP call.
         * @return The child that best matches the call, or an empty {@link 
Optional} if a match could not be made.
         */
-       public Optional<RestChildMatch> findMatch(RestCall call) {
+       public Optional<RestChildMatch> findMatch(RestCall.Builder call) {
                String pi = call.getPathInfoUndecoded();
                if ((! children.isEmpty()) && pi != null && ! pi.equals("/")) {
                        for (RestContext rc : children.values()) {
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 6870645..fd5e1eb 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
@@ -7038,12 +7038,11 @@ public class RestContext extends Context {
         */
        public void execute(Object resource, HttpServletRequest r1, 
HttpServletResponse r2) throws ServletException, IOException {
 
-               RestCall call = 
createSession().resource(resource).req(r1).res(r2).logger(getCallLogger()).build();
-
                // Must be careful not to bleed thread-locals.
                if (this.call.get() != null)
                        System.err.println("WARNING:  Thread-local call object 
was not cleaned up from previous request.  " + this + ", 
thread=["+Thread.currentThread().getId()+"]");
-               this.call.set(call);
+
+               RestCall.Builder cb = 
createSession().resource(resource).req(r1).res(r2).logger(getCallLogger());
 
                try {
 
@@ -7055,69 +7054,80 @@ public class RestContext extends Context {
                        // the remainder after the new servletPath.
                        // Only do this for the top-level resource because the 
logic for child resources are processed next.
                        if (pathMatcher.hasVars() && parentContext == null) {
-                               String sp = call.getServletPath();
-                               String pi = call.getPathInfoUndecoded();
+                               String sp = cb.req().getServletPath();
+                               String pi = cb.getPathInfoUndecoded();
                                UrlPath upi2 = UrlPath.of(pi == null ? sp : sp 
+ pi);
                                UrlPathMatch uppm = pathMatcher.match(upi2);
                                if (uppm != null && ! uppm.hasEmptyVars()) {
-                                       call.pathVars(uppm.getVars());
-                                       call.request(
-                                               new 
OverrideableHttpServletRequest(call.getRequest())
+                                       cb.pathVars(uppm.getVars());
+                                       cb.req(
+                                               new 
OverrideableHttpServletRequest(cb.req())
                                                        
.pathInfo(nullIfEmpty(urlDecode(uppm.getSuffix())))
                                                        
.servletPath(uppm.getPrefix())
                                        );
                                } else {
+                                       RestCall call = cb.build();
                                        
call.debug(isDebug(call)).status(SC_NOT_FOUND).finish();
                                        return;
                                }
                        }
 
                        // If this resource has child resources, try to 
recursively call them.
-                       Optional<RestChildMatch> childMatch = 
restChildren.findMatch(call);
+                       Optional<RestChildMatch> childMatch = 
restChildren.findMatch(cb);
                        if (childMatch.isPresent()) {
                                UrlPathMatch uppm = 
childMatch.get().getPathMatch();
                                RestContext rc = 
childMatch.get().getChildContext();
                                if (! uppm.hasEmptyVars()) {
-                                       call.pathVars(uppm.getVars());
-                                       HttpServletRequest childRequest = new 
OverrideableHttpServletRequest(call.getRequest())
+                                       cb.pathVars(uppm.getVars());
+                                       HttpServletRequest childRequest = new 
OverrideableHttpServletRequest(cb.req())
                                                
.pathInfo(nullIfEmpty(urlDecode(uppm.getSuffix())))
-                                               
.servletPath(call.getServletPath() + uppm.getPrefix());
-                                       rc.execute(rc.getResource(), 
childRequest, call.getResponse());
+                                               
.servletPath(cb.req().getServletPath() + uppm.getPrefix());
+                                       rc.execute(rc.getResource(), 
childRequest, cb.res());
                                } else {
+                                       RestCall call = cb.build();
                                        
call.debug(isDebug(call)).status(SC_NOT_FOUND).finish();
                                }
                                return;
                        }
 
-                       call.debug(isDebug(call));
+               } catch (Throwable e) {
+                       handleError(cb.build(), convertThrowable(e));
+               } finally {
+                       clearState();
+               }
+
+               RestCall c = cb.build();
+               c.debug(isDebug(c));
+               this.call.set(c);
 
-                       startCall(call);
+               try {
+
+                       startCall(c);
 
                        // If the specified method has been defined in a 
subclass, invoke it.
                        try {
-                               restOperations.findOperation(call).invoke(call);
+                               restOperations.findOperation(c).invoke(c);
                        } catch (NotFound e) {
-                               if (call.getStatus() == 0)
-                                       call.status(404);
-                               call.exception(e);
-                               handleNotFound(call);
+                               if (c.getStatus() == 0)
+                                       c.status(404);
+                               c.exception(e);
+                               handleNotFound(c);
                        }
 
-                       if (call.hasOutput()) {
+                       if (c.hasOutput()) {
                                // Now serialize the output if there was any.
                                // Some subclasses may write to the 
OutputStream or Writer directly.
-                               processResponse(call);
+                               processResponse(c);
                        }
 
-
                } catch (Throwable e) {
-                       handleError(call, convertThrowable(e));
+                       handleError(c, convertThrowable(e));
                } finally {
                        clearState();
                }
 
-               call.finish();
-               finishCall(call);
+               c.finish();
+               finishCall(c);
        }
 
        private boolean isDebug(RestCall call) {

Reply via email to