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