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.mock; 014 015import static org.apache.juneau.internal.StringUtils.*; 016 017import java.io.*; 018import java.security.*; 019import java.util.*; 020 021import javax.servlet.*; 022import javax.servlet.http.*; 023 024import org.apache.juneau.internal.*; 025import org.apache.juneau.rest.*; 026import org.apache.juneau.rest.util.*; 027import org.apache.juneau.rest.util.RestUtils; 028import org.apache.juneau.urlencoding.*; 029import org.apache.juneau.utils.*; 030 031/** 032 * An implementation of {@link HttpServletRequest} for mocking purposes. 033 * 034 * <div class='warn'> 035 * <b>Deprecated</b> - Use <c>org.apache.juneau.restmock2</c> 036 * </div> 037 */ 038@Deprecated 039public class MockServletRequest implements HttpServletRequest, MockHttpRequest { 040 041 private String method = "GET"; 042 private Map<String,String[]> queryData; 043 private Map<String,String[]> formDataMap; 044 private Map<String,String[]> headerMap = new LinkedHashMap<>(); 045 private Map<String,Object> attributeMap = new LinkedHashMap<>(); 046 private String characterEncoding = "UTF-8"; 047 private byte[] body = new byte[0]; 048 private String protocol = "HTTP/1.1"; 049 private String scheme = "http"; 050 private String serverName = "localhost"; 051 private int serverPort = 8080; 052 private String remoteAddr = ""; 053 private String remoteHost = ""; 054 private Locale locale = Locale.ENGLISH; 055 private String realPath; 056 private int remotePort; 057 private String localName; 058 private String localAddr; 059 private int localPort; 060 private RequestDispatcher requestDispatcher; 061 private ServletContext servletContext; 062 private DispatcherType dispatcherType; 063 private String authType; 064 private Cookie[] cookies; 065 private String pathInfo; 066 private String pathTranslated; 067 private String contextPath = ""; 068 private String queryString; 069 private String remoteUser; 070 private Principal userPrincipal; 071 private String requestedSessionId; 072 private String requestURI; 073 private String servletPath = ""; 074 private HttpSession httpSession = MockHttpSession.create(); 075 private RestContext restContext; 076 private String uri = ""; 077 private boolean debug = false; 078 079 /** 080 * Creates a new servlet request. 081 * 082 * Initialized with the following: 083 * <ul> 084 * <li><c>"Accept: text/json+simple"</c> 085 * <li><c>"Content-Type: text/json"</c> 086 * </ul> 087 * 088 * @return A new request. 089 */ 090 public static MockServletRequest create() { 091 MockServletRequest r = new MockServletRequest(); 092 return r; 093 } 094 095 /** 096 * Creates a new servlet request with the specified method name and request path. 097 * 098 * Initialized with the following: 099 * <ul> 100 * <li><c>"Accept: text/json+simple"</c> 101 * <li><c>"Content-Type: text/json"</c> 102 * </ul> 103 * 104 * @param method The HTTP method name. 105 * @param path The request path. 106 * @param pathArgs Optional path arguments. 107 * 108 * @return A new request. 109 */ 110 public static MockServletRequest create(String method, String path, Object...pathArgs) { 111 return create() 112 .method(method) 113 .uri(StringUtils.format(path, pathArgs)); 114 } 115 116 /** 117 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"application/json"</js>. 118 * 119 * @return This object (for method chaining). 120 */ 121 public MockServletRequest json() { 122 return header("Accept", "application/json").header("Content-Type", "application/json"); 123 } 124 125 /** 126 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/xml"</js>. 127 * 128 * @return This object (for method chaining). 129 */ 130 public MockServletRequest xml() { 131 return header("Accept", "text/xml").header("Content-Type", "text/xml"); 132 } 133 134 /** 135 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/html"</js>. 136 * 137 * @return This object (for method chaining). 138 */ 139 public MockServletRequest html() { 140 return header("Accept", "text/html").header("Content-Type", "text/html"); 141 } 142 143 /** 144 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/plain"</js>. 145 * 146 * @return This object (for method chaining). 147 */ 148 public MockServletRequest plainText() { 149 return header("Accept", "text/plain").header("Content-Type", "text/plain"); 150 } 151 152 /** 153 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"octal/msgpack"</js>. 154 * 155 * @return This object (for method chaining). 156 */ 157 public MockServletRequest msgpack() { 158 return header("Accept", "octal/msgpack").header("Content-Type", "octal/msgpack"); 159 } 160 161 /** 162 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/uon"</js>. 163 * 164 * @return This object (for method chaining). 165 */ 166 public MockServletRequest uon() { 167 return header("Accept", "text/uon").header("Content-Type", "text/uon"); 168 } 169 170 /** 171 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"application/x-www-form-urlencoded"</js>. 172 * 173 * @return This object (for method chaining). 174 */ 175 public MockServletRequest urlEnc() { 176 return header("Accept", "application/x-www-form-urlencoded").header("Content-Type", "application/x-www-form-urlencoded"); 177 } 178 179 /** 180 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/yaml"</js>. 181 * 182 * @return This object (for method chaining). 183 */ 184 public MockServletRequest yaml() { 185 return header("Accept", "text/yaml").header("Content-Type", "text/yaml"); 186 } 187 188 /** 189 * Fluent setter. 190 * 191 * @param uri The URI of the request. 192 * @return This object (for method chaining). 193 */ 194 @Override /* MockHttpRequest */ 195 public MockServletRequest uri(String uri) { 196 this.uri = emptyIfNull(uri); 197 return this; 198 } 199 200 /** 201 * Fluent setter. 202 * 203 * @param restContext The rest context. 204 * @return This object (for method chaining). 205 */ 206 public MockServletRequest restContext(RestContext restContext) { 207 this.restContext = restContext; 208 return this; 209 } 210 211 /** 212 * Executes this request and returns the response object. 213 * 214 * @return The response object. 215 * @throws Exception Error occurred. 216 */ 217 @Override /* MockHttpRequest */ 218 public MockServletResponse execute() throws Exception { 219 MockServletResponse res = MockServletResponse.create(); 220 restContext.getCallHandler().service(this, res); 221 222 // If the status isn't set, something's broken. 223 if (res.getStatus() == 0) 224 throw new RuntimeException("Response status was 0."); 225 226 if (debug) 227 log(this, res); 228 229 return res; 230 } 231 232 private void log(MockServletRequest req, MockServletResponse res) { 233 StringBuilder sb = new StringBuilder(); 234 sb.append("\n=== HTTP Call ================================================================="); 235 236 sb.append("\n=== REQUEST ==="); 237 sb.append("\nTODO"); 238 sb.append("\n=== RESPONSE ==="); 239 sb.append("\nStatus: ").append(res.getStatus()); 240 sb.append("\n---response headers---"); 241 for (Map.Entry<String,String[]> h : res.getHeaders().entrySet()) 242 for (String h2 : h.getValue()) 243 sb.append("\n").append(h.getKey()).append(": ").append(h2); 244 sb.append("\n---response content---\n"); 245 sb.append(res.getBodyAsString()); 246 sb.append("\n=== END ========================================================================"); 247 248 System.err.println(sb); // NOT DEBUG 249 } 250 251 /** 252 * Fluent setter. 253 * 254 * @param value The method name for this request. 255 * @return This object (for method chaining). 256 */ 257 @Override /* MockHttpRequest */ 258 public MockServletRequest method(String value) { 259 this.method = value; 260 return this; 261 } 262 263 /** 264 * Fluent setter. 265 * 266 * @param value The character encoding. 267 * @return This object (for method chaining). 268 */ 269 public MockServletRequest characterEncoding(String value) { 270 this.characterEncoding = value; 271 return this; 272 } 273 274 /** 275 * Fluent setter. 276 * 277 * @param value The protocol. 278 * @return This object (for method chaining). 279 */ 280 public MockServletRequest protocol(String value) { 281 this.protocol = value; 282 return this; 283 } 284 285 /** 286 * Fluent setter. 287 * 288 * @param value The scheme. 289 * @return This object (for method chaining). 290 */ 291 public MockServletRequest scheme(String value) { 292 this.scheme = value; 293 return this; 294 } 295 296 /** 297 * Fluent setter. 298 * 299 * @param value The server name. 300 * @return This object (for method chaining). 301 */ 302 public MockServletRequest serverName(String value) { 303 this.serverName = value; 304 return this; 305 } 306 307 /** 308 * Fluent setter. 309 * 310 * @param value The server port. 311 * @return This object (for method chaining). 312 */ 313 public MockServletRequest serverPort(int value) { 314 this.serverPort = value; 315 return this; 316 } 317 318 /** 319 * Fluent setter. 320 * 321 * @param value The remote address. 322 * @return This object (for method chaining). 323 */ 324 public MockServletRequest remoteAddr(String value) { 325 this.remoteAddr = value; 326 return this; 327 } 328 329 /** 330 * Fluent setter. 331 * 332 * @param value The remote port. 333 * @return This object (for method chaining). 334 */ 335 public MockServletRequest remoteHost(String value) { 336 this.remoteHost = value; 337 return this; 338 } 339 340 /** 341 * Fluent setter. 342 * 343 * @param value The locale. 344 * @return This object (for method chaining). 345 */ 346 public MockServletRequest locale(Locale value) { 347 this.locale = value; 348 return this; 349 } 350 351 /** 352 * Fluent setter. 353 * 354 * @param value The real path. 355 * @return This object (for method chaining). 356 */ 357 public MockServletRequest realPath(String value) { 358 this.realPath = value; 359 return this; 360 } 361 362 /** 363 * Fluent setter. 364 * 365 * @param value The remote port. 366 * @return This object (for method chaining). 367 */ 368 public MockServletRequest remotePort(int value) { 369 this.remotePort = value; 370 return this; 371 } 372 373 /** 374 * Fluent setter. 375 * 376 * @param value The local name. 377 * @return This object (for method chaining). 378 */ 379 public MockServletRequest localName(String value) { 380 this.localName = value; 381 return this; 382 } 383 384 /** 385 * Fluent setter. 386 * 387 * @param value The local address. 388 * @return This object (for method chaining). 389 */ 390 public MockServletRequest localAddr(String value) { 391 this.localAddr = value; 392 return this; 393 } 394 395 /** 396 * Fluent setter. 397 * 398 * @param value The local port. 399 * @return This object (for method chaining). 400 */ 401 public MockServletRequest localPort(int value) { 402 this.localPort = value; 403 return this; 404 } 405 406 /** 407 * Fluent setter. 408 * 409 * @param value The request dispatcher. 410 * @return This object (for method chaining). 411 */ 412 public MockServletRequest requestDispatcher(RequestDispatcher value) { 413 this.requestDispatcher = value; 414 return this; 415 } 416 417 /** 418 * Fluent setter. 419 * 420 * @param value The servlet context. 421 * @return This object (for method chaining). 422 */ 423 public MockServletRequest servletContext(ServletContext value) { 424 this.servletContext = value; 425 return this; 426 } 427 428 /** 429 * Fluent setter. 430 * 431 * @param value The dispatcher type. 432 * @return This object (for method chaining). 433 */ 434 public MockServletRequest dispatcherType(DispatcherType value) { 435 this.dispatcherType = value; 436 return this; 437 } 438 439 /** 440 * Fluent setter. 441 * 442 * @param value The auth type. 443 * @return This object (for method chaining). 444 */ 445 public MockServletRequest authType(String value) { 446 this.authType = value; 447 return this; 448 } 449 450 /** 451 * Fluent setter. 452 * 453 * @param value The cookies. 454 * @return This object (for method chaining). 455 */ 456 public MockServletRequest cookies(Cookie[] value) { 457 this.cookies = value; 458 return this; 459 } 460 461 /** 462 * Fluent setter. 463 * 464 * @param value The path info. 465 * @return This object (for method chaining). 466 */ 467 public MockServletRequest pathInfo(String value) { 468 this.pathInfo = value; 469 return this; 470 } 471 472 /** 473 * Fluent setter. 474 * 475 * @param value The path translated. 476 * @return This object (for method chaining). 477 */ 478 public MockServletRequest pathTranslated(String value) { 479 this.pathTranslated = value; 480 return this; 481 } 482 483 /** 484 * Fluent setter. 485 * 486 * @param value The context path. 487 * @return This object (for method chaining). 488 */ 489 public MockServletRequest contextPath(String value) { 490 this.contextPath = value; 491 return this; 492 } 493 494 /** 495 * Fluent setter. 496 * 497 * @param value The query string. 498 * @return This object (for method chaining). 499 */ 500 public MockServletRequest queryString(String value) { 501 this.queryString = value; 502 return this; 503 } 504 505 /** 506 * Fluent setter. 507 * 508 * @param value The remote user. 509 * @return This object (for method chaining). 510 */ 511 public MockServletRequest remoteUser(String value) { 512 this.remoteUser = value; 513 return this; 514 } 515 516 /** 517 * Fluent setter. 518 * 519 * @param value The user principal. 520 * @return This object (for method chaining). 521 */ 522 public MockServletRequest userPrincipal(Principal value) { 523 this.userPrincipal = value; 524 return this; 525 } 526 527 /** 528 * Fluent setter. 529 * 530 * @param value The requested session ID. 531 * @return This object (for method chaining). 532 */ 533 public MockServletRequest requestedSessionId(String value) { 534 this.requestedSessionId = value; 535 return this; 536 } 537 538 /** 539 * Fluent setter. 540 * 541 * @param value The request URI. 542 * @return This object (for method chaining). 543 */ 544 public MockServletRequest requestURI(String value) { 545 this.requestURI = value; 546 return this; 547 } 548 549 /** 550 * Fluent setter. 551 * 552 * @param value The servlet path. 553 * @return This object (for method chaining). 554 */ 555 public MockServletRequest servletPath(String value) { 556 this.servletPath = value; 557 return this; 558 } 559 560 /** 561 * Fluent setter. 562 * 563 * @param value The HTTP session. 564 * @return This object (for method chaining). 565 */ 566 public MockServletRequest httpSession(HttpSession value) { 567 this.httpSession = value; 568 return this; 569 } 570 571 @Override /* HttpServletRequest */ 572 public Object getAttribute(String name) { 573 return attributeMap.get(name); 574 } 575 576 @Override /* HttpServletRequest */ 577 public Enumeration<String> getAttributeNames() { 578 return Collections.enumeration(attributeMap.keySet()); 579 } 580 581 @Override /* HttpServletRequest */ 582 public String getCharacterEncoding() { 583 return characterEncoding; 584 } 585 586 @Override /* HttpServletRequest */ 587 public void setCharacterEncoding(String characterEncoding) throws UnsupportedEncodingException { 588 this.characterEncoding = characterEncoding; 589 } 590 591 @Override /* HttpServletRequest */ 592 public int getContentLength() { 593 return body == null ? 0 : body.length; 594 } 595 596 @Override /* HttpServletRequest */ 597 public long getContentLengthLong() { 598 return body == null ? 0 : body.length; 599 } 600 601 @Override /* HttpServletRequest */ 602 public String getContentType() { 603 return getHeader("Content-Type"); 604 } 605 606 @Override /* HttpServletRequest */ 607 public ServletInputStream getInputStream() throws IOException { 608 if (formDataMap != null) 609 body = UrlEncodingSerializer.DEFAULT.toString(formDataMap).getBytes(); 610 return new BoundedServletInputStream(new ByteArrayInputStream(body), Integer.MAX_VALUE); 611 } 612 613 @Override /* HttpServletRequest */ 614 public String getParameter(String name) { 615 String[] s = getParameterMap().get(name); 616 return s == null || s.length == 0 ? null : s[0]; 617 } 618 619 @Override /* HttpServletRequest */ 620 public Enumeration<String> getParameterNames() { 621 return Collections.enumeration(new ArrayList<>(getParameterMap().keySet())); 622 } 623 624 @Override /* HttpServletRequest */ 625 public String[] getParameterValues(String name) { 626 return getParameterMap().get(name); 627 } 628 629 @Override /* HttpServletRequest */ 630 public Map<String,String[]> getParameterMap() { 631 if (queryData == null) { 632 try { 633 if ("POST".equalsIgnoreCase(method)) { 634 if (formDataMap != null) 635 queryData = formDataMap; 636 else 637 queryData = RestUtils.parseQuery(IOUtils.read(body)); 638 } else { 639 queryData = RestUtils.parseQuery(getQueryString()); 640 } 641 } catch (Exception e) { 642 throw new RuntimeException(e); 643 } 644 } 645 return queryData; 646 } 647 648 @Override /* HttpServletRequest */ 649 public String getProtocol() { 650 return protocol; 651 } 652 653 @Override /* HttpServletRequest */ 654 public String getScheme() { 655 return scheme; 656 } 657 658 @Override /* HttpServletRequest */ 659 public String getServerName() { 660 return serverName; 661 } 662 663 @Override /* HttpServletRequest */ 664 public int getServerPort() { 665 return serverPort; 666 } 667 668 @Override /* HttpServletRequest */ 669 public BufferedReader getReader() throws IOException { 670 return new BufferedReader(new InputStreamReader(getInputStream(), characterEncoding)); 671 } 672 673 @Override /* HttpServletRequest */ 674 public String getRemoteAddr() { 675 return remoteAddr; 676 } 677 678 @Override /* HttpServletRequest */ 679 public String getRemoteHost() { 680 return remoteHost; 681 } 682 683 @Override /* HttpServletRequest */ 684 public void setAttribute(String name, Object o) { 685 this.attributeMap.put(name, o); 686 } 687 688 @Override /* HttpServletRequest */ 689 public void removeAttribute(String name) { 690 this.attributeMap.remove(name); 691 } 692 693 @Override /* HttpServletRequest */ 694 public Locale getLocale() { 695 return locale; 696 } 697 698 @Override /* HttpServletRequest */ 699 public Enumeration<Locale> getLocales() { 700 return Collections.enumeration(Arrays.asList(locale)); 701 } 702 703 @Override /* HttpServletRequest */ 704 public boolean isSecure() { 705 return false; 706 } 707 708 @Override /* HttpServletRequest */ 709 public RequestDispatcher getRequestDispatcher(String path) { 710 return requestDispatcher; 711 } 712 713 @Override /* HttpServletRequest */ 714 public String getRealPath(String path) { 715 return realPath; 716 } 717 718 @Override /* HttpServletRequest */ 719 public int getRemotePort() { 720 return remotePort; 721 } 722 723 @Override /* HttpServletRequest */ 724 public String getLocalName() { 725 return localName; 726 } 727 728 @Override /* HttpServletRequest */ 729 public String getLocalAddr() { 730 return localAddr; 731 } 732 733 @Override /* HttpServletRequest */ 734 public int getLocalPort() { 735 return localPort; 736 } 737 738 @Override /* HttpServletRequest */ 739 public ServletContext getServletContext() { 740 return servletContext; 741 } 742 743 @Override /* HttpServletRequest */ 744 public AsyncContext startAsync() throws IllegalStateException { 745 return null; 746 } 747 748 @Override /* HttpServletRequest */ 749 public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException { 750 return null; 751 } 752 753 @Override /* HttpServletRequest */ 754 public boolean isAsyncStarted() { 755 return false; 756 } 757 758 @Override /* HttpServletRequest */ 759 public boolean isAsyncSupported() { 760 return false; 761 } 762 763 @Override /* HttpServletRequest */ 764 public AsyncContext getAsyncContext() { 765 return null; 766 } 767 768 @Override /* HttpServletRequest */ 769 public DispatcherType getDispatcherType() { 770 return dispatcherType; 771 } 772 773 @Override /* HttpServletRequest */ 774 public String getAuthType() { 775 return authType; 776 } 777 778 @Override /* HttpServletRequest */ 779 public Cookie[] getCookies() { 780 return cookies; 781 } 782 783 @Override /* HttpServletRequest */ 784 public long getDateHeader(String name) { 785 String s = getHeader(name); 786 return s == null ? 0 : org.apache.juneau.http.Date.forString(s).asDate().getTime(); 787 } 788 789 @Override /* HttpServletRequest */ 790 public String getHeader(String name) { 791 String[] s = headerMap.get(name); 792 return s == null || s.length == 0 ? null : s[0]; 793 } 794 795 @Override /* HttpServletRequest */ 796 public Enumeration<String> getHeaders(String name) { 797 String[] s = headerMap.get(name); 798 return Collections.enumeration(Arrays.asList(s == null ? new String[0] : s)); 799 } 800 801 @Override /* HttpServletRequest */ 802 public Enumeration<String> getHeaderNames() { 803 return Collections.enumeration(headerMap.keySet()); 804 } 805 806 @Override /* HttpServletRequest */ 807 public int getIntHeader(String name) { 808 String s = getHeader(name); 809 return s == null || s.isEmpty() ? 0 : Integer.parseInt(s); 810 } 811 812 @Override /* HttpServletRequest */ 813 public String getMethod() { 814 return method; 815 } 816 817 @Override /* HttpServletRequest */ 818 public String getPathInfo() { 819 if (pathInfo == null) { 820 pathInfo = getRequestURI(); 821 if (isNotEmpty(contextPath)) 822 pathInfo = pathInfo.substring(contextPath.length()); 823 if (isNotEmpty(servletPath)) 824 pathInfo = pathInfo.substring(servletPath.length()); 825 } 826 return nullIfEmpty(urlDecode(pathInfo)); 827 } 828 829 @Override /* HttpServletRequest */ 830 public String getPathTranslated() { 831 if (pathTranslated == null) 832 pathTranslated = "/mock-path" + getPathInfo(); 833 return pathTranslated; 834 } 835 836 @Override /* HttpServletRequest */ 837 public String getContextPath() { 838 return contextPath; 839 } 840 841 @Override /* HttpServletRequest */ 842 public String getQueryString() { 843 if (queryString == null) { 844 queryString = ""; 845 if (uri.indexOf('?') != -1) { 846 queryString = uri.substring(uri.indexOf('?') + 1); 847 if (queryString.indexOf('#') != -1) 848 queryString = queryString.substring(0, queryString.indexOf('#')); 849 } 850 } 851 return isEmpty(queryString) ? null : queryString; 852 } 853 854 @Override /* HttpServletRequest */ 855 public String getRemoteUser() { 856 return remoteUser; 857 } 858 859 @Override /* HttpServletRequest */ 860 public boolean isUserInRole(String role) { 861 return false; 862 } 863 864 @Override /* HttpServletRequest */ 865 public Principal getUserPrincipal() { 866 return userPrincipal; 867 } 868 869 @Override /* HttpServletRequest */ 870 public String getRequestedSessionId() { 871 return requestedSessionId; 872 } 873 874 @Override /* HttpServletRequest */ 875 public String getRequestURI() { 876 if (requestURI == null) { 877 requestURI = uri; 878 requestURI = requestURI.replaceAll("^\\w+\\:\\/\\/[^\\/]+", "").replaceAll("\\?.*$", ""); 879 } 880 return requestURI; 881 } 882 883 @Override /* HttpServletRequest */ 884 public StringBuffer getRequestURL() { 885 return new StringBuffer(uri.replaceAll("\\?.*$", "")); 886 } 887 888 @Override /* HttpServletRequest */ 889 public String getServletPath() { 890 return servletPath; 891 } 892 893 @Override /* HttpServletRequest */ 894 public HttpSession getSession(boolean create) { 895 return httpSession; 896 } 897 898 @Override /* HttpServletRequest */ 899 public HttpSession getSession() { 900 return httpSession; 901 } 902 903 @Override /* HttpServletRequest */ 904 public String changeSessionId() { 905 return null; 906 } 907 908 @Override /* HttpServletRequest */ 909 public boolean isRequestedSessionIdValid() { 910 return false; 911 } 912 913 @Override /* HttpServletRequest */ 914 public boolean isRequestedSessionIdFromCookie() { 915 return false; 916 } 917 918 @Override /* HttpServletRequest */ 919 public boolean isRequestedSessionIdFromURL() { 920 return false; 921 } 922 923 @Override /* HttpServletRequest */ 924 public boolean isRequestedSessionIdFromUrl() { 925 return false; 926 } 927 928 @Override /* HttpServletRequest */ 929 public boolean authenticate(HttpServletResponse response) throws IOException, ServletException { 930 return false; 931 } 932 933 @Override /* HttpServletRequest */ 934 public void login(String username, String password) throws ServletException { 935 } 936 937 @Override /* HttpServletRequest */ 938 public void logout() throws ServletException { 939 } 940 941 @Override /* HttpServletRequest */ 942 public Collection<Part> getParts() throws IOException, ServletException { 943 return null; 944 } 945 946 @Override /* HttpServletRequest */ 947 public Part getPart(String name) throws IOException, ServletException { 948 return null; 949 } 950 951 @Override /* HttpServletRequest */ 952 public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException { 953 return null; 954 } 955 956 //================================================================================================================= 957 // Convenience methods 958 //================================================================================================================= 959 960 /** 961 * Fluent setter. 962 * 963 * @param name Header name. 964 * @param value 965 * Header value. 966 * <br>The value is converted to a simple string using {@link Object#toString()}. 967 * @return This object (for method chaining). 968 */ 969 @Override /* MockHttpRequest */ 970 public MockServletRequest header(String name, Object value) { 971 this.headerMap.put(name, new String[] {stringify(value)}); 972 return this; 973 } 974 975 /** 976 * Fluent setter. 977 * 978 * @param name Request attribute name. 979 * @param value Request attribute value. 980 * @return This object (for method chaining). 981 */ 982 public MockServletRequest attribute(String name, Object value) { 983 this.attributeMap.put(name, value); 984 return this; 985 } 986 987 /** 988 * Fluent setter. 989 * 990 * @param value 991 * The body of the request. 992 * <br>Can be any of the following data types: 993 * <ul> 994 * <li><code><jk>byte</jk>[]</code> 995 * <li>{@link Reader} 996 * <li>{@link InputStream} 997 * <li>{@link CharSequence} 998 * </ul> 999 * @return This object (for method chaining). 1000 */ 1001 @Override /* MockHttpRequest */ 1002 public MockServletRequest body(Object value) { 1003 try { 1004 if (value instanceof byte[]) 1005 this.body = (byte[])value; 1006 if (value instanceof Reader) 1007 this.body = IOUtils.read((Reader)value).getBytes(); 1008 if (value instanceof InputStream) 1009 this.body = IOUtils.readBytes((InputStream)value, 1024); 1010 if (value instanceof CharSequence) 1011 this.body = ((CharSequence)value).toString().getBytes(); 1012 } catch (IOException e) { 1013 throw new RuntimeException(e); 1014 } 1015 return this; 1016 } 1017 1018 /** 1019 * Adds a form data entry to this request. 1020 * 1021 * @param key The form data key. 1022 * @param value The form data value. 1023 * <br>The value is converted to a simple string using {@link Object#toString()}. 1024 * @return This object (for method chaining). 1025 */ 1026 public MockServletRequest formData(String key, Object value) { 1027 if (formDataMap == null) 1028 formDataMap = new LinkedHashMap<>(); 1029 String s = stringify(value); 1030 String[] existing = formDataMap.get(key); 1031 if (existing == null) 1032 existing = new String[]{s}; 1033 else 1034 existing = new AList<>().appendAll(Arrays.asList(existing)).append(s).toArray(new String[0]); 1035 formDataMap.put(key, existing); 1036 return this; 1037 } 1038 1039 /** 1040 * Adds a query data entry to this request. 1041 * 1042 * @param key The query key. 1043 * @param value The query value. 1044 * <br>The value is converted to a simple string using {@link Object#toString()}. 1045 * @return This object (for method chaining). 1046 */ 1047 public MockServletRequest query(String key, Object value) { 1048 if (queryData == null) 1049 queryData = new LinkedHashMap<>(); 1050 String s = stringify(value); 1051 String[] existing = queryData.get(key); 1052 if (existing == null) 1053 existing = new String[]{s}; 1054 else 1055 existing = new AList<>().appendAll(Arrays.asList(existing)).append(s).toArray(new String[0]); 1056 queryData.put(key, existing); 1057 return this; 1058 } 1059 1060 //================================================================================================================= 1061 // Convenience methods - headers 1062 //================================================================================================================= 1063 1064 /** 1065 * Specifies the <c>Accept</c> header value on the request. 1066 * 1067 * @param value The new value. 1068 * @return This object (for method chaining). 1069 */ 1070 public MockServletRequest accept(Object value) { 1071 return header("Accept", value); 1072 } 1073 1074 /** 1075 * Specifies the <c>Accept-Charset</c> header value on the request. 1076 * 1077 * @param value The new value. 1078 * @return This object (for method chaining). 1079 */ 1080 public MockServletRequest acceptCharset(Object value) { 1081 return header("Accept-Charset", value); 1082 } 1083 1084 /** 1085 * Specifies the <c>Accept-Encoding</c> header value on the request. 1086 * 1087 * @param value The new value. 1088 * @return This object (for method chaining). 1089 */ 1090 public MockServletRequest acceptEncoding(Object value) { 1091 return header("Accept-Encoding", value); 1092 } 1093 1094 /** 1095 * Specifies the <c>Accept-Language</c> header value on the request. 1096 * 1097 * @param value The new value. 1098 * @return This object (for method chaining). 1099 */ 1100 public MockServletRequest acceptLanguage(Object value) { 1101 return header("Accept-Language", value); 1102 } 1103 1104 /** 1105 * Specifies the <c>Authorization</c> header value on the request. 1106 * 1107 * @param value The new value for the header. 1108 * @return This object (for method chaining). 1109 */ 1110 public MockServletRequest authorization(Object value) { 1111 return header("Authorization", value); 1112 } 1113 1114 /** 1115 * Specifies the <c>Cache-Control</c> header value on the request. 1116 * 1117 * @param value The new value for the header. 1118 * @return This object (for method chaining). 1119 */ 1120 public MockServletRequest cacheControl(Object value) { 1121 return header("Cache-Control", value); 1122 } 1123 1124 /** 1125 * Specifies the <c>X-Client-Version</c> header value on the request. 1126 * 1127 * @param value The new value. 1128 * @return This object (for method chaining). 1129 */ 1130 public MockServletRequest clientVersion(Object value) { 1131 return header("X-Client-Version", value); 1132 } 1133 1134 /** 1135 * Specifies the <c>Connection</c> header value on the request. 1136 * 1137 * @param value The new value for the header. 1138 * @return This object (for method chaining). 1139 */ 1140 public MockServletRequest connection(Object value) { 1141 return header("Connection", value); 1142 } 1143 1144 /** 1145 * Specifies the <c>Content-Encoding</c> header value on the request. 1146 * 1147 * @param value The new value. 1148 * @return This object (for method chaining). 1149 */ 1150 public MockServletRequest contentEncoding(Object value) { 1151 return header("Content-Encoding", value); 1152 } 1153 1154 /** 1155 * Specifies the <c>Content-Length</c> header value on the request. 1156 * 1157 * @param value The new value for the header. 1158 * @return This object (for method chaining). 1159 */ 1160 public MockServletRequest contentLength(Object value) { 1161 return header("Content-Length", value); 1162 } 1163 1164 /** 1165 * Specifies the <c>Content-Type</c> header value on the request. 1166 * 1167 * @param value The new value. 1168 * @return This object (for method chaining). 1169 */ 1170 public MockServletRequest contentType(Object value) { 1171 return header("Content-Type", value); 1172 } 1173 1174 /** 1175 * Specifies the <c>Date</c> header value on the request. 1176 * 1177 * @param value The new value for the header. 1178 * @return This object (for method chaining). 1179 */ 1180 public MockServletRequest date(Object value) { 1181 return header("Date", value); 1182 } 1183 1184 /** 1185 * Specifies the <c>Expect</c> header value on the request. 1186 * 1187 * @param value The new value for the header. 1188 * @return This object (for method chaining). 1189 */ 1190 public MockServletRequest expect(Object value) { 1191 return header("Expect", value); 1192 } 1193 1194 /** 1195 * Specifies the <c>From</c> header value on the request. 1196 * 1197 * @param value The new value for the header. 1198 * @return This object (for method chaining). 1199 */ 1200 public MockServletRequest from(Object value) { 1201 return header("From", value); 1202 } 1203 1204 /** 1205 * Specifies the <c>Host</c> header value on the request. 1206 * 1207 * @param value The new value for the header. 1208 * @return This object (for method chaining). 1209 */ 1210 public MockServletRequest host(Object value) { 1211 return header("Host", value); 1212 } 1213 1214 /** 1215 * Specifies the <c>If-Match</c> header value on the request. 1216 * 1217 * @param value The new value for the header. 1218 * @return This object (for method chaining). 1219 */ 1220 public MockServletRequest ifMatch(Object value) { 1221 return header("If-Match", value); 1222 } 1223 1224 /** 1225 * Specifies the <c>If-Modified-Since</c> header value on the request. 1226 * 1227 * @param value The new value for the header. 1228 * @return This object (for method chaining). 1229 */ 1230 public MockServletRequest ifModifiedSince(Object value) { 1231 return header("If-Modified-Since", value); 1232 } 1233 1234 /** 1235 * Specifies the <c>If-None-Match</c> header value on the request. 1236 * 1237 * @param value The new value for the header. 1238 * @return This object (for method chaining). 1239 */ 1240 public MockServletRequest ifNoneMatch(Object value) { 1241 return header("If-None-Match", value); 1242 } 1243 1244 /** 1245 * Specifies the <c>If-Range</c> header value on the request. 1246 * 1247 * @param value The new value for the header. 1248 * @return This object (for method chaining). 1249 */ 1250 public MockServletRequest ifRange(Object value) { 1251 return header("If-Range", value); 1252 } 1253 1254 /** 1255 * Specifies the <c>If-Unmodified-Since</c> header value on the request. 1256 * 1257 * @param value The new value for the header. 1258 * @return This object (for method chaining). 1259 */ 1260 public MockServletRequest ifUnmodifiedSince(Object value) { 1261 return header("If-Unmodified-Since", value); 1262 } 1263 1264 /** 1265 * Specifies the <c>Max-Forwards</c> header value on the request. 1266 * 1267 * @param value The new value for the header. 1268 * @return This object (for method chaining). 1269 */ 1270 public MockServletRequest maxForwards(Object value) { 1271 return header("Max-Forwards", value); 1272 } 1273 1274 /** 1275 * Specifies the <c>Pragma</c> header value on the request. 1276 * 1277 * @param value The new value for the header. 1278 * @return This object (for method chaining). 1279 */ 1280 public MockServletRequest pragma(Object value) { 1281 return header("Pragma", value); 1282 } 1283 1284 /** 1285 * Specifies the <c>Proxy-Authorization</c> header value on the request. 1286 * 1287 * @param value The new value for the header. 1288 * @return This object (for method chaining). 1289 */ 1290 public MockServletRequest proxyAuthorization(Object value) { 1291 return header("Proxy-Authorization", value); 1292 } 1293 1294 /** 1295 * Specifies the <c>Range</c> header value on the request. 1296 * 1297 * @param value The new value for the header. 1298 * @return This object (for method chaining). 1299 */ 1300 public MockServletRequest range(Object value) { 1301 return header("Range", value); 1302 } 1303 1304 /** 1305 * Specifies the <c>Referer</c> header value on the request. 1306 * 1307 * @param value The new value for the header. 1308 * @return This object (for method chaining). 1309 */ 1310 public MockServletRequest referer(Object value) { 1311 return header("Referer", value); 1312 } 1313 1314 /** 1315 * Specifies the <c>TE</c> header value on the request. 1316 * 1317 * @param value The new value for the header. 1318 * @return This object (for method chaining). 1319 */ 1320 public MockServletRequest te(Object value) { 1321 return header("TE", value); 1322 } 1323 1324 /** 1325 * Specifies the <c>Upgrade</c> header value on the request. 1326 * 1327 * @param value The new value for the header. 1328 * @return This object (for method chaining). 1329 */ 1330 public MockServletRequest upgrade(Object value) { 1331 return header("Upgrade", value); 1332 } 1333 1334 /** 1335 * Specifies the <c>User-Agent</c> header value on the request. 1336 * 1337 * @param value The new value for the header. 1338 * @return This object (for method chaining). 1339 */ 1340 public MockServletRequest userAgent(Object value) { 1341 return header("User-Agent", value); 1342 } 1343 1344 /** 1345 * Specifies the <c>Warning</c> header value on the request. 1346 * 1347 * @param value The new value for the header. 1348 * @return This object (for method chaining). 1349 */ 1350 public MockServletRequest warning(Object value) { 1351 return header("Warning", value); 1352 } 1353 1354 /** 1355 * Enabled debug mode on this request. 1356 * 1357 * <p> 1358 * Causes information about the request execution to be sent to STDERR. 1359 * 1360 * @return This object (for method chaining). 1361 */ 1362 public MockServletRequest debug() { 1363 this.debug = true; 1364 return this; 1365 } 1366}