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