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