001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.rest; 014 015import java.io.*; 016 017import org.apache.http.*; 018import org.apache.juneau.*; 019import org.apache.juneau.cp.*; 020import org.apache.juneau.http.response.*; 021import org.apache.juneau.rest.converter.*; 022import org.apache.juneau.rest.guard.*; 023import org.apache.juneau.rest.logger.*; 024 025/** 026 * A session for a single HTTP request. 027 * 028 * <p> 029 * This session object gets created by {@link RestSession} once the Java method to be invoked has been determined. 030 * 031 * <h5 class='section'>Notes:</h5><ul> 032 * <li class='warn'>This class is not thread safe. 033 * </ul> 034 * 035 * <h5 class='section'>See Also:</h5><ul> 036 * </ul> 037 */ 038public class RestOpSession extends ContextSession { 039 040 041 //----------------------------------------------------------------------------------------------------------------- 042 // Static 043 //----------------------------------------------------------------------------------------------------------------- 044 045 /** 046 * Static creator. 047 * 048 * @param ctx The context object of the Java method being invoked. 049 * @param session The REST session object creating this object. 050 * @return A new builder. 051 */ 052 public static Builder create(RestOpContext ctx, RestSession session) { 053 return new Builder(ctx, session); 054 } 055 056 //----------------------------------------------------------------------------------------------------------------- 057 // Builder 058 //----------------------------------------------------------------------------------------------------------------- 059 060 /** 061 * Builder class. 062 */ 063 public static class Builder extends ContextSession.Builder { 064 065 final RestOpContext ctx; 066 final RestSession session; 067 068 /** 069 * Constructor. 070 * 071 * @param ctx The context object of the Java method being invoked. 072 * @param session The REST session object creating this object. 073 */ 074 public Builder(RestOpContext ctx, RestSession session) { 075 super(ctx); 076 this.ctx = ctx; 077 this.session = session; 078 } 079 080 /** 081 * Sets the logger to use when logging this call. 082 * 083 * @param value The new value for this setting. Can be <jk>null</jk>. 084 * @return This object. 085 */ 086 public Builder logger(CallLogger value) { 087 session.logger(value); 088 return this; 089 } 090 091 /** 092 * Enables or disabled debug mode on this call. 093 * 094 * @param value The new value for this setting. 095 * @return This object. 096 * @throws IOException Occurs if request content could not be cached into memory. 097 */ 098 public Builder debug(boolean value) throws IOException { 099 session.debug(value); 100 return this; 101 } 102 103 @Override /* Session.Builder */ 104 public RestOpSession build() { 105 return new RestOpSession(this); 106 } 107 } 108 109 //----------------------------------------------------------------------------------------------------------------- 110 // Instance 111 //----------------------------------------------------------------------------------------------------------------- 112 113 private final RestOpContext ctx; 114 private final RestSession session; 115 private final RestRequest req; 116 private final RestResponse res; 117 118 /** 119 * Constructor. 120 * 121 * @param builder The builder for this object. 122 */ 123 protected RestOpSession(Builder builder) { 124 super(builder); 125 ctx = builder.ctx; 126 session = builder.session; 127 try { 128 req = session.getBeanStore().add(RestRequest.class, ctx.createRequest(session)); 129 res = session.getBeanStore().add(RestResponse.class, ctx.createResponse(session, req)); 130 } catch (RuntimeException e) { 131 throw e; 132 } catch (Exception e) { 133 throw new InternalServerError(e); 134 } 135 } 136 137 @Override /* ContextSession */ 138 public RestOpContext getContext() { 139 return ctx; 140 } 141 142 /** 143 * Runs this session. 144 * 145 * <p> 146 * Does the following: 147 * <ol> 148 * <li>Runs the guards on the method. 149 * <li>Finds the parameter values to pass to the Java method. 150 * <li>Invokes the Java method. 151 * <li>Sets the output and status on the response. 152 * <li>Calls the converters on the Java method. 153 * </ol> 154 * 155 * @throws Throwable Any throwable can be thrown. 156 */ 157 public void run() throws Throwable { 158 159 for (RestGuard guard : ctx.getGuards()) 160 if (! guard.guard(req, res)) 161 return; 162 163 ctx.getMethodInvoker().invoke(this); 164 165 if (res.hasContent()) 166 for (RestConverter converter : ctx.getConverters()) 167 res.setContent(converter.convert(req, res.getContent().orElse(null))); 168 } 169 170 /** 171 * Returns the REST request object for this session. 172 * 173 * @return The REST request object for this session. 174 */ 175 public RestRequest getRequest() { 176 return req; 177 } 178 179 /** 180 * Returns the REST response object for this session. 181 * 182 * @return The REST response object for this session. 183 */ 184 public RestResponse getResponse() { 185 return res; 186 } 187 188 /** 189 * Returns the bean store for this session. 190 * 191 * @return The bean store for this session. 192 */ 193 public BeanStore getBeanStore() { 194 return session.getBeanStore(); 195 } 196 197 /** 198 * Returns the context of the parent class of this Java method. 199 * 200 * @return The context of the parent class of this Java method. 201 */ 202 public RestContext getRestContext() { 203 return session.getContext(); 204 } 205 206 /** 207 * Returns the session of the parent class of this Java method. 208 * 209 * @return The session of the parent class of this Java method. 210 */ 211 public RestSession getRestSession() { 212 return session; 213 } 214 215 /** 216 * Sets the status of the response. 217 * 218 * @param value The new status. 219 * @return This object. 220 */ 221 public RestOpSession status(StatusLine value) { 222 session.status(value); 223 return this; 224 } 225 226 /** 227 * Called at the end of a call to finish any remaining tasks such as flushing buffers and logging the response. 228 * 229 * @return This object. 230 */ 231 public RestOpSession finish() { 232 try { 233 res.flushBuffer(); 234 req.close(); 235 } catch (Exception e) { 236 session.exception(e); 237 } 238 return this; 239 } 240}