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