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.httppart; 018 019import static org.apache.juneau.common.utils.Utils.*; 020 021import java.util.*; 022 023import org.apache.juneau.collections.*; 024import org.apache.juneau.common.utils.*; 025import org.apache.juneau.rest.*; 026import org.apache.juneau.svl.*; 027 028import jakarta.servlet.http.*; 029 030/** 031 * Represents the attributes in an HTTP request. 032 * 033 * <p> 034 * The {@link RequestAttributes} object is the API for accessing the standard servlet attributes on an HTTP request 035 * (i.e. {@link jakarta.servlet.ServletRequest#getAttribute(String)}). 036 * </p> 037 * 038 * <p class='bjava'> 039 * <ja>@RestPost</ja>(...) 040 * <jk>public</jk> Object myMethod(RequestAttributes <jv>attributes</jv>) {...} 041 * </p> 042 * 043 * <h5 class='figure'>Example:</h5> 044 * <p class='bjava'> 045 * <ja>@RestPost</ja>(...) 046 * <jk>public</jk> Object myMethod(RequestAttributes <jv>attributes</jv>) { 047 * 048 * <jc>// Add a default value.</jc> 049 * <jv>attributes</jv>.addDefault(<js>"Foo"</js>, 123); 050 * 051 * <jc>// Get an attribute value as a POJO.</jc> 052 * UUID <jv>etag</jv> = <jv>attributes</jv>.get(<js>"ETag"</js>).as(UUID.<jk>class</jk>).orElse(<jk>null</jk>); 053 * } 054 * </p> 055 * 056 * <p> 057 * Some important methods on this class are: 058 * </p> 059 * <ul class='javatree'> 060 * <li class='jc'>{@link RequestHeaders} 061 * <ul class='spaced-list'> 062 * <li>Methods for retrieving request attributes: 063 * <ul class='javatreec'> 064 * <li class='jm'>{@link RequestAttributes#contains(String...) contains(String...)} 065 * <li class='jm'>{@link RequestAttributes#containsAny(String...) containsAny(String...)} 066 * <li class='jm'>{@link RequestAttributes#get(String) get(String)} 067 * <li class='jm'>{@link RequestAttributes#getAll() getAll()} 068 * </ul> 069 * <li>Methods for overriding request attributes: 070 * <ul class='javatreec'> 071 * <li class='jm'>{@link RequestAttributes#addDefault(List) addDefault(List)} 072 * <li class='jm'>{@link RequestAttributes#addDefault(NamedAttribute...) addDefault(NamedAttribute...)} 073 * <li class='jm'>{@link RequestAttributes#addDefault(NamedAttributeMap) addDefault(NamedAttributeMap)} 074 * <li class='jm'>{@link RequestAttributes#addDefault(String,Object) addDefault(String,Object)} 075 * <li class='jm'>{@link RequestAttributes#remove(NamedAttribute...) remove(NamedAttribute...)} 076 * <li class='jm'>{@link RequestAttributes#remove(String...) remove(String...)} 077 * <li class='jm'>{@link RequestAttributes#set(NamedAttribute...) set(NamedAttribute...)} 078 * <li class='jm'>{@link RequestAttributes#set(String,Object) set(String,Object)} 079 * </ul> 080 * <li>Other methods: 081 * <ul class='javatreec'> 082 * <li class='jm'>{@link RequestAttributes#asMap() asMap()} 083 * </ul> 084 * </ul> 085 * </ul> 086 * 087 * <p> 088 * Modifications made to request attributes through the <c>RequestAttributes</c> bean are automatically reflected in 089 * the underlying servlet request attributes making it possible to mix the usage of both APIs. 090 * </p> 091 * 092 * <h5 class='section'>See Also:</h5><ul> 093 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/HttpParts">HTTP Parts</a> 094 * </ul> 095 */ 096public class RequestAttributes { 097 098 final RestRequest req; 099 final HttpServletRequest sreq; 100 final VarResolverSession vs; 101 102 /** 103 * Constructor. 104 * 105 * @param req The request creating this bean. 106 */ 107 public RequestAttributes(RestRequest req) { 108 this.req = req; 109 this.sreq = req.getHttpServletRequest(); 110 this.vs = req.getVarResolverSession(); 111 } 112 113 /** 114 * Adds default entries to the request attributes. 115 * 116 * @param pairs 117 * The default entries. 118 * <br>Can be <jk>null</jk>. 119 * @return This object. 120 */ 121 public RequestAttributes addDefault(List<NamedAttribute> pairs) { 122 for (NamedAttribute p : pairs) 123 if (sreq.getAttribute(p.getName()) == null) { 124 Object o = p.getValue(); 125 sreq.setAttribute(p.getName(), o instanceof String ? vs.resolve(o) : o); 126 } 127 return this; 128 } 129 130 /** 131 * Adds default entries to the request attributes. 132 * 133 * @param pairs 134 * The default entries. 135 * <br>Can be <jk>null</jk>. 136 * @return This object. 137 */ 138 public RequestAttributes addDefault(NamedAttributeMap pairs) { 139 for (NamedAttribute p : pairs.values()) 140 if (sreq.getAttribute(p.getName()) == null) { 141 Object o = p.getValue(); 142 sreq.setAttribute(p.getName(), o instanceof String ? vs.resolve(o) : o); 143 } 144 return this; 145 } 146 147 /** 148 * Adds default entries to the request attributes. 149 * 150 * @param pairs 151 * The default entries. 152 * <br>Can be <jk>null</jk>. 153 * @return This object. 154 */ 155 public RequestAttributes addDefault(NamedAttribute...pairs) { 156 return addDefault(alist(pairs)); 157 } 158 159 /** 160 * Adds a default entry to the request attributes. 161 * 162 * @param name The name. 163 * @param value The value. 164 * @return This object. 165 */ 166 public RequestAttributes addDefault(String name, Object value) { 167 return addDefault(BasicNamedAttribute.of(name, value)); 168 } 169 170 /** 171 * Returns the request attribute with the specified name. 172 * 173 * @param name The attribute name. 174 * @return The parameter value, or {@link Optional#empty()} if it doesn't exist. 175 */ 176 public RequestAttribute get(String name) { 177 return new RequestAttribute(req, name, sreq.getAttribute(name)); 178 } 179 180 /** 181 * Returns all the attribute on this request. 182 * 183 * @return All the attribute on this request. 184 */ 185 public List<RequestAttribute> getAll() { 186 List<RequestAttribute> l = Utils.list(); 187 Enumeration<String> e = sreq.getAttributeNames(); 188 while (e.hasMoreElements()) { 189 String n = e.nextElement(); 190 l.add(new RequestAttribute(req, n, sreq.getAttribute(n))); 191 } 192 return l; 193 } 194 195 /** 196 * Returns <jk>true</jk> if the attributes with the specified names are present. 197 * 198 * @param names The attribute names. Must not be <jk>null</jk>. 199 * @return <jk>true</jk> if the parameters with the specified names are present. 200 */ 201 public boolean contains(String...names) { 202 Utils.assertArgNotNull("names", names); 203 for (String n : names) 204 if (sreq.getAttribute(n) == null) 205 return false; 206 return true; 207 } 208 209 /** 210 * Returns <jk>true</jk> if the attribute with any of the specified names are present. 211 * 212 * @param names The attribute names. Must not be <jk>null</jk>. 213 * @return <jk>true</jk> if the attribute with any of the specified names are present. 214 */ 215 public boolean containsAny(String...names) { 216 Utils.assertArgNotNull("names", names); 217 for (String n : names) 218 if (sreq.getAttribute(n) != null) 219 return true; 220 return false; 221 } 222 223 /** 224 * Sets a request attribute. 225 * 226 * @param name The attribute name. Must not be <jk>null</jk>. 227 * @param value 228 * The attribute value. 229 * <br>Can be <jk>null</jk>. 230 * @return This object. 231 */ 232 public RequestAttributes set(String name, Object value) { 233 Utils.assertArgNotNull("name", name); 234 sreq.setAttribute(name, value); 235 return this; 236 } 237 238 /** 239 * Sets request attributes. 240 * 241 * @param attributes The parameters to set. Must not be <jk>null</jk> or contain <jk>null</jk>. 242 * @return This object. 243 */ 244 public RequestAttributes set(NamedAttribute...attributes) { 245 Utils.assertArgNotNull("attributes", attributes); 246 for (NamedAttribute p : attributes) 247 set(p); 248 return this; 249 } 250 251 /** 252 * Remove request attributes. 253 * 254 * @param name The attribute names. Must not be <jk>null</jk>. 255 * @return This object. 256 */ 257 public RequestAttributes remove(String...name) { 258 Utils.assertArgNotNull("name", name); 259 for (String n : name) { 260 sreq.removeAttribute(n); 261 } 262 return this; 263 } 264 265 /** 266 * Remove request attributes. 267 * 268 * @param attributes The attributes to remove. Must not be <jk>null</jk>. 269 * @return This object. 270 */ 271 public RequestAttributes remove(NamedAttribute...attributes) { 272 for (NamedAttribute p : attributes) 273 remove(p.getName()); 274 return this; 275 } 276 277 /** 278 * Returns the request attributes as a map. 279 * 280 * @return The request attributes as a map. Never <jk>null</jk>. 281 */ 282 public Map<String,Object> asMap() { 283 JsonMap m = new JsonMap(); 284 Enumeration<String> e = sreq.getAttributeNames(); 285 while (e.hasMoreElements()) { 286 String n = e.nextElement(); 287 m.put(n, sreq.getAttribute(n)); 288 } 289 return m; 290 } 291 292 @Override /* Object */ 293 public String toString() { 294 return asMap().toString(); 295 } 296}