001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2005-2009 Pentaho and others 008// All Rights Reserved. 009*/ 010package mondrian.tui; 011 012import java.io.*; 013import java.security.Principal; 014import java.text.ParseException; 015import java.text.SimpleDateFormat; 016import java.util.*; 017import javax.servlet.*; 018import javax.servlet.http.*; 019 020/** 021 * Partial implementation of the {@link HttpServletRequest} where just 022 * enough is present to allow for communication between Mondrian's 023 * XMLA code and other code in the same JVM. 024 * 025 * <p>Currently it is used in both the CmdRunner and in XMLA JUnit tests. 026 * If you need to add to this implementation, please do so. 027 * 028 * @author Richard M. Emberson 029 */ 030public class MockHttpServletRequest implements HttpServletRequest { 031 public static String AUTHORIZATION = "Authorization"; 032 public static final String DATE_FORMAT_HEADER = 033 "EEE, d MMM yyyy HH:mm:ss Z"; 034 035 public static class MockRequestDispatcher implements RequestDispatcher { 036 private ServletRequest forwardedRequest; 037 private ServletResponse forwardedResponse; 038 private ServletRequest includedRequest; 039 private ServletResponse includedResponse; 040 private String path; 041 042 MockRequestDispatcher() { 043 } 044 045 public void setPath(String path) { 046 this.path = path; 047 } 048 049 public String getPath() { 050 return this.path; 051 } 052 053 public void forward(ServletRequest request, ServletResponse response) 054 throws ServletException, IOException 055 { 056 this.forwardedRequest = request; 057 this.forwardedResponse = response; 058 } 059 060 public void include(ServletRequest request, ServletResponse response) 061 throws ServletException, IOException 062 { 063 this.includedRequest = request; 064 this.includedResponse = response; 065 } 066 067 public ServletRequest getForwardedRequest() { 068 return this.forwardedRequest; 069 } 070 071 public ServletResponse getForwardedResponse() { 072 return this.forwardedResponse; 073 } 074 public ServletRequest getIncludedRequest() { 075 return this.includedRequest; 076 } 077 078 public ServletResponse getIncludedResponse() { 079 return this.includedResponse; 080 } 081 } 082 static class MockServletInputStream extends ServletInputStream { 083 private ByteArrayInputStream stream; 084 085 public MockServletInputStream(byte[] data) { 086 stream = new ByteArrayInputStream(data); 087 } 088 089 public int read() throws IOException { 090 return stream.read(); 091 } 092 } 093 094 095 private HttpSession session; 096 //private ByteArrayInputStream bin; 097 private Map<String, String[]> parameters; 098 private Map<String, RequestDispatcher> requestDispatchers; 099 private List<Locale> locales; 100 private String serverName; 101 private String charEncoding; 102 private String method; 103 private String pathInfo; 104 private String pathTranslated; 105 private String contextPath; 106 private String queryString; 107 private String remoteUser; 108 private String requestedSessionId; 109 private String servletPath; 110 private String scheme; 111 private String localName; 112 private String localAddr; 113 private String authType; 114 private String protocol; 115 private String schema; 116 private Principal principal; 117 private List<Cookie> cookies; 118 private boolean requestedSessionIdIsFromCookie; 119 private int remotePort; 120 private int localPort; 121 private int serverPort; 122 private String remoteAddr; 123 private String remoteHost; 124 private Map<String, Object> attributes; 125 private final LinkedHashMap<String, List<String>> headers; 126 private boolean sessionCreated; 127 private String requestedURI; 128 private StringBuffer requestUrl; 129 private String bodyContent; 130 private Map<String, Boolean> roles; 131 132 public MockHttpServletRequest() { 133 this(new byte[0]); 134 } 135 public MockHttpServletRequest(byte[] bytes) { 136 this(new String(bytes)); 137 } 138 public MockHttpServletRequest(String bodyContent) { 139 this.bodyContent = bodyContent; 140 this.attributes = Collections.emptyMap(); 141 //this.bin = new ByteArrayInputStream(bytes); 142 this.headers = new LinkedHashMap<String, List<String>>(); 143 this.requestDispatchers = new HashMap<String, RequestDispatcher>(); 144 this.parameters = new HashMap<String, String[]>(); 145 this.cookies = new ArrayList<Cookie>(); 146 this.locales = new ArrayList<Locale>(); 147 this.roles = new HashMap<String, Boolean>(); 148 this.requestedSessionIdIsFromCookie = true; 149 this.method = "GET"; 150 this.protocol = "HTTP/1.1"; 151 this.serverName = "localhost"; 152 this.serverPort = 8080; 153 this.scheme = "http"; 154 this.remoteHost = "localhost"; 155 this.remoteAddr = "127.0.0.1"; 156 this.localAddr = "127.0.0.1"; 157 this.localName = "localhost"; 158 this.localPort = 8080; 159 this.remotePort = 5000; 160 161 this.sessionCreated = false; 162 } 163 164 165 /** 166 * Returns the value of the named attribute as an Object, or null if no 167 * attribute of the given name exists. 168 * 169 */ 170 public Object getAttribute(String name) { 171 return this.attributes.get(name); 172 } 173 174 /** 175 * to this request. 176 * 177 */ 178 public Enumeration getAttributeNames() { 179 return Collections.enumeration(attributes.keySet()); 180 } 181 182 /** 183 * Returns the name of the character encoding used in the body of this 184 * request. 185 * 186 */ 187 public String getCharacterEncoding() { 188 return charEncoding; 189 } 190 191 /** 192 * 193 * 194 */ 195 public void setCharacterEncoding(String charEncoding) 196 throws UnsupportedEncodingException 197 { 198 this.charEncoding = charEncoding; 199 } 200 201 /** 202 * Returns the length, in bytes, of the request body and made available by 203 * the input stream, or -1 if the length is not known. 204 * 205 */ 206 public int getContentLength() { 207 return getIntHeader("Content-Length"); 208 } 209 210 /** 211 * Returns the MIME type of the body of the request, or null if the type is 212 * not known. 213 * 214 */ 215 public String getContentType() { 216 return getHeader("Content-Type"); 217 } 218 219 /** 220 * Retrieves the body of the request as binary data using a 221 * ServletInputStream. 222 * 223 * @throws IOException 224 */ 225 public ServletInputStream getInputStream() throws IOException { 226 return new MockServletInputStream(bodyContent.getBytes()); 227 } 228 229 /** 230 * Returns the value of a request parameter as a String, or null if the 231 * parameter does not exist. 232 * 233 */ 234 public String getParameter(String name) { 235 String[] values = getParameterValues(name); 236 return (null != values && 0 < values.length) 237 ? values[0] : null; 238 } 239 240 /** 241 * Returns an Enumeration of String objects containing the names of the 242 * parameters contained in this request. 243 * 244 */ 245 public Enumeration getParameterNames() { 246 return Collections.enumeration(parameters.keySet()); 247 } 248 249 /** 250 * Returns an array of String objects containing all of the values the given 251 * request parameter has, or null if the parameter does not exist. 252 * 253 */ 254 public String[] getParameterValues(String name) { 255 return parameters.get(name); 256 } 257 258 259 /** 260 * Returns the name and version of the protocol the request uses in the form 261 * protocol/majorVersion.minorVersion, for example, HTTP/1.1. 262 * 263 */ 264 public String getProtocol() { 265 return protocol; 266 } 267 268 /** 269 * Returns the name of the scheme used to make this request, for example, 270 * http, https, or ftp. 271 * 272 */ 273 public String getScheme() { 274 return schema; 275 } 276 277 /** 278 * Returns the host name of the server that received the request. 279 * 280 */ 281 public String getServerName() { 282 return serverName; 283 } 284 285 /** 286 * Returns the port number on which this request was received. 287 * 288 */ 289 public int getServerPort() { 290 return serverPort; 291 } 292 293 /** 294 * Retrieves the body of the request as character data using a 295 * BufferedReader. 296 * 297 * @throws IOException 298 */ 299 public BufferedReader getReader() throws IOException { 300 return (bodyContent == null) 301 ? null 302 : new BufferedReader(new StringReader(bodyContent)); 303 } 304 305 /** 306 * Returns the Internet Protocol (IP) address of the client that sent the 307 * request. 308 * 309 */ 310 public String getRemoteAddr() { 311 return remoteAddr; 312 } 313 314 /** 315 * Returns the fully qualified name of the client that sent the request, or 316 * the IP address of the client if the name cannot be determined. 317 * 318 */ 319 public String getRemoteHost() { 320 return remoteHost; 321 } 322 323 /** 324 * Stores an attribute in this request. 325 * 326 */ 327 public void setAttribute(String name, Object obj) { 328 if (attributes == Collections.EMPTY_MAP) { 329 attributes = new HashMap<String, Object>(); 330 } 331 this.attributes.put(name, obj); 332 } 333 334 /** 335 * Removes an attribute from this request. 336 * 337 */ 338 public void removeAttribute(String name) { 339 this.attributes.remove(name); 340 } 341 342 /** 343 * Returns the preferred Locale that the client will accept content in, 344 * based on the Accept-Language header. 345 * 346 */ 347 public Locale getLocale() { 348 return (locales.size() < 1) 349 ? Locale.getDefault() 350 : locales.get(0); 351 } 352 353 /** 354 * Returns an Enumeration of Locale objects indicating, in decreasing order 355 * starting with the preferred locale, the locales that are acceptable to 356 * the client based on the Accept-Language header. 357 * 358 */ 359 public Enumeration getLocales() { 360 return Collections.enumeration(locales); 361 } 362 363 /** 364 * Returns a boolean indicating whether this request was made using a 365 * secure channel, such as HTTPS. 366 * 367 */ 368 public boolean isSecure() { 369 String scheme = getScheme(); 370 return (scheme == null) 371 ? false 372 : scheme.equals("https"); 373 } 374 375 /** 376 * Returns a RequestDispatcher object that acts as a wrapper for the 377 * resource located at the given path. 378 * 379 */ 380 public RequestDispatcher getRequestDispatcher(String path) { 381 RequestDispatcher dispatcher = 382 requestDispatchers.get(path); 383 if (dispatcher == null) { 384 dispatcher = new MockRequestDispatcher(); 385 setRequestDispatcher(path, dispatcher); 386 } 387 return dispatcher; 388 } 389 390 /** 391 * Deprecated. As of Version 2.1 of the Java Servlet API, use 392 * ServletContext.getRealPath(java.lang.String) instead. 393 * @deprecated Method getRealPath is deprecated 394 * 395 */ 396 public String getRealPath(String path) { 397 HttpSession session = getSession(); 398 return (session == null) 399 ? null 400 : session.getServletContext().getRealPath(path); 401 } 402 403 /** 404 * 405 * 406 */ 407 public int getRemotePort() { 408 return remotePort; 409 } 410 411 /** 412 * 413 * 414 */ 415 public String getLocalName() { 416 return localName; 417 } 418 419 /** 420 * 421 * 422 */ 423 public String getLocalAddr() { 424 return localAddr; 425 } 426 427 /** 428 * 429 * 430 */ 431 public int getLocalPort() { 432 return localPort; 433 } 434 435 /** 436 * Returns the name of the authentication scheme used to protect the 437 * servlet, for example, "BASIC" or "SSL," or null if the servlet was not 438 * protected. 439 * 440 */ 441 public String getAuthType() { 442 return authType; 443 } 444 445 /** 446 * Returns an array containing all of the Cookie objects the client sent 447 * with this request. 448 * 449 */ 450 public Cookie[] getCookies() { 451 return cookies.toArray(new Cookie[cookies.size()]); 452 } 453 454 /** 455 * Returns the value of the specified request header as a long value that 456 * represents a Date object. 457 * 458 */ 459 public long getDateHeader(String name) { 460 String header = getHeader(name); 461 if (header == null) { 462 return -1; 463 } 464 try { 465 Date dateValue = 466 new SimpleDateFormat( 467 DATE_FORMAT_HEADER, Locale.US).parse(header); 468 return dateValue.getTime(); 469 } catch (ParseException exc) { 470 throw new IllegalArgumentException(exc.getMessage()); 471 } 472 } 473 474 /** 475 * Returns the value of the specified request header as a String. 476 * 477 */ 478 public String getHeader(String name) { 479 List<String> headerList = headers.get(name); 480 481 return ((headerList == null) || (headerList.size() == 0)) 482 ? null 483 : headerList.get(0); 484 } 485 486 /** 487 * Returns all the values of the specified request header as an Enumeration 488 * of String objects. 489 * 490 */ 491 public Enumeration getHeaders(String name) { 492 List<String> headerList = headers.get(name); 493 return (headerList == null) 494 ? null 495 : Collections.enumeration(headerList); 496 } 497 498 /** 499 * Returns an enumeration of all the header names this request contains. 500 * 501 */ 502 public Enumeration getHeaderNames() { 503 return Collections.enumeration(headers.keySet()); 504 } 505 506 /** 507 * Returns the value of the specified request header as an int. 508 * 509 */ 510 public int getIntHeader(String name) { 511 String header = getHeader(name); 512 return (header == null) 513 ? -1 514 : Integer.parseInt(header); 515 } 516 517 /** 518 * Returns the name of the HTTP method with which this request was made, for 519 * example, GET, POST, or PUT. 520 * 521 */ 522 public String getMethod() { 523 return this.method; 524 } 525 526 /** 527 * Returns any extra path information associated with the URL the client 528 * sent when it made this request. 529 * 530 */ 531 public String getPathInfo() { 532 return pathInfo; 533 } 534 535 /** 536 * Returns any extra path information after the servlet name but before the 537 * query string, and translates it to a real path. 538 * 539 */ 540 public String getPathTranslated() { 541 return pathTranslated; 542 } 543 544 /** 545 * Returns the portion of the request URI that indicates the context of the 546 * request. 547 * 548 */ 549 public String getContextPath() { 550 return contextPath; 551 } 552 553 /** 554 * Returns the query string that is contained in the request URL after the 555 * path. 556 * 557 */ 558 public String getQueryString() { 559 return queryString; 560 } 561 562 /** 563 * Returns the login of the user making this request, if the user has been 564 * authenticated, or null if the user has not been authenticated. 565 * 566 */ 567 public String getRemoteUser() { 568 return remoteUser; 569 } 570 571 /** 572 * Returns a boolean indicating whether the authenticated user is included 573 * in the specified logical "role". 574 * 575 */ 576 public boolean isUserInRole(String role) { 577 return roles.get(role); 578 } 579 580 /** 581 * Returns a java.security.Principal object containing the name of the 582 * current authenticated user. 583 * 584 */ 585 public Principal getUserPrincipal() { 586 return principal; 587 } 588 589 /** 590 * Returns the session ID specified by the client. 591 * 592 */ 593 public String getRequestedSessionId() { 594 HttpSession session = getSession(); 595 return (session == null) 596 ? null 597 : session.getId(); 598 } 599 600 /** 601 * Returns the part of this request's URL from the protocol name up to the 602 * query string in the first line of the HTTP request. 603 * 604 */ 605 public String getRequestURI() { 606 return requestedURI; 607 } 608 609 /** 610 * 611 * 612 */ 613 public StringBuffer getRequestURL() { 614 return requestUrl; 615 } 616 617 /** 618 * Returns the part of this request's URL that calls the servlet. 619 * 620 */ 621 public String getServletPath() { 622 return servletPath; 623 } 624 625 /** 626 * Returns the current HttpSession associated with this request or, if if 627 * there is no current session and create is true, returns a new session. 628 * 629 */ 630 public HttpSession getSession(boolean create) { 631 if (! create && ! sessionCreated) { 632 return null; 633 } 634 return getSession(); 635 } 636 637 /** 638 * Returns the current session associated with this request, or if the 639 * request does not have a session, creates one. 640 * 641 */ 642 public HttpSession getSession() { 643 sessionCreated = true; 644 return session; 645 } 646 647 /** 648 * Checks whether the requested session ID is still valid. 649 * 650 */ 651 public boolean isRequestedSessionIdValid() { 652 HttpSession session = getSession(); 653 return (session != null); 654 } 655 656 /** 657 * Checks whether the requested session ID came in as a cookie. 658 * 659 */ 660 public boolean isRequestedSessionIdFromCookie() { 661 return requestedSessionIdIsFromCookie; 662 } 663 664 /** 665 * Checks whether the requested session ID came in as part of the request 666 * URL. 667 * 668 */ 669 public boolean isRequestedSessionIdFromURL() { 670 return !requestedSessionIdIsFromCookie; 671 } 672 673 public boolean isRequestedSessionIdFromUrl() { 674 // deprecated as of version 2.1 of Servlet API. 675 return isRequestedSessionIdFromURL(); 676 } 677 678 ///////////////////////////////////////////////////////////////////////// 679 // 680 // implementation access 681 // 682 ///////////////////////////////////////////////////////////////////////// 683/* 684 public void setBytes(byte[] bytes) { 685 this.bin = new ByteArrayInputStream(bytes); 686 } 687*/ 688 /** 689 * 690 * 691 */ 692 public Map getParameterMap() { 693 return Collections.unmodifiableMap(parameters); 694 } 695 696 public void setServerName(String serverName) { 697 this.serverName = serverName; 698 } 699 public void setRemoteHost(String remoteHost) { 700 this.remoteHost = remoteHost; 701 } 702 public void setRemoteAddr(String remoteAddr) { 703 this.remoteAddr = remoteAddr; 704 } 705 public void setMethod(String method) { 706 this.method = method; 707 } 708 public void setPathInfo(String pathInfo) { 709 this.pathInfo = pathInfo; 710 } 711 public void setPathTranslated(String pathTranslated) { 712 this.pathTranslated = pathTranslated; 713 } 714 public void setContextPath(String contextPath) { 715 this.contextPath = contextPath; 716 } 717 public void setQueryString(String queryString) { 718 this.queryString = queryString; 719 } 720 public void setRemoteUser(String remoteUser) { 721 this.remoteUser = remoteUser; 722 } 723 public void setRequestedSessionId(String requestedSessionId) { 724 this.requestedSessionId = requestedSessionId; 725 } 726 public void setRequestURI(String requestedURI) { 727 this.requestedURI = requestedURI; 728 } 729 public void setServletPath(String servletPath) { 730 this.servletPath = servletPath; 731 } 732 public void setLocalName(String localName) { 733 this.localName = localName; 734 } 735 public void setLocalAddr(String localAddr) { 736 this.localAddr = localAddr; 737 } 738 public void setAuthType(String authType) { 739 this.authType = authType; 740 } 741 public void setProtocol(String protocol) { 742 this.protocol = protocol; 743 } 744 public void setScheme(String schema) { 745 this.schema = schema; 746 } 747 748 public void setRemotePort(int remotePort) { 749 this.remotePort = remotePort; 750 } 751 public void setLocalPort(int localPort) { 752 this.localPort = localPort; 753 } 754 public void setServerPort(int serverPort) { 755 this.serverPort = serverPort; 756 } 757 758 public void setContentType(String contentType) { 759 setHeader("Content-Type", contentType); 760 } 761 public void setHeader(String name, String value) { 762 List<String> valueList = headers.get(name); 763 if (valueList == null) { 764 valueList = new ArrayList<String>(); 765 headers.put(name, valueList); 766 } 767 valueList.add(value); 768 } 769 ///////////////////////////////////////////////////////////////////////// 770 // 771 // helpers 772 // 773 ///////////////////////////////////////////////////////////////////////// 774 775 public void clearParameters() { 776 parameters.clear(); 777 } 778 779 public void setupAddParameter(String key, String[] values) { 780 parameters.put(key, values); 781 } 782 public void setupAddParameter(String key, String value) { 783 setupAddParameter(key, new String[] { value }); 784 } 785 786 public void clearAttributes() { 787 attributes.clear(); 788 } 789 790 public void setSession(HttpSession session) { 791 this.session = session; 792 } 793 794 public Map<String, RequestDispatcher> getRequestDispatcherMap() { 795 return Collections.unmodifiableMap(requestDispatchers); 796 } 797 798 public void setRequestDispatcher( 799 String path, 800 RequestDispatcher dispatcher) 801 { 802 if (dispatcher instanceof MockRequestDispatcher) { 803 ((MockRequestDispatcher)dispatcher).setPath(path); 804 } 805 requestDispatchers.put(path, dispatcher); 806 } 807 808 public void addLocale(Locale locale) { 809 locales.add(locale); 810 } 811 812 public void addLocales(List<Locale> localeList) { 813 locales.addAll(localeList); 814 } 815 816 public void addHeader(String key, String value) { 817 List<String> valueList = headers.get(key); 818 if (valueList == null) { 819 valueList = new ArrayList<String>(); 820 headers.put(key, valueList); 821 } 822 valueList.add(value); 823 } 824 public void clearHeader(String key) { 825 headers.remove(key); 826 } 827 828 public void setRequestURL(String requestUrl) { 829 this.requestUrl = new StringBuffer(requestUrl); 830 } 831 832 public void setUserPrincipal(Principal principal) { 833 this.principal = principal; 834 } 835 836 public void addCookie(Cookie cookie) { 837 cookies.add(cookie); 838 } 839 840 public void setRequestedSessionIdFromCookie( 841 boolean requestedSessionIdIsFromCookie) 842 { 843 this.requestedSessionIdIsFromCookie = requestedSessionIdIsFromCookie; 844 } 845 846 public void setUserInRole(String role, boolean isInRole) { 847 roles.put(role, isInRole); 848 } 849 850 public void setBodyContent(byte[] data) { 851 setBodyContent(new String(data)); 852 } 853 854 public void setBodyContent(String bodyContent) { 855 this.bodyContent = bodyContent; 856 } 857 858 859} 860 861// End MockHttpServletRequest.java