001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *
010     *        http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License.
018     */
019    
020    package org.apache.isis.viewer.scimpi.servlet;
021    
022    import java.io.IOException;
023    import java.io.InputStream;
024    import java.io.PrintWriter;
025    import java.net.MalformedURLException;
026    import java.util.Enumeration;
027    import java.util.Map;
028    
029    import javax.servlet.ServletContext;
030    import javax.servlet.ServletException;
031    import javax.servlet.http.Cookie;
032    import javax.servlet.http.HttpServletRequest;
033    import javax.servlet.http.HttpServletResponse;
034    import javax.servlet.http.HttpSession;
035    
036    import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
037    import org.apache.isis.core.metamodel.spec.ObjectSpecification;
038    import org.apache.isis.viewer.scimpi.dispatcher.DispatchException;
039    import org.apache.isis.viewer.scimpi.dispatcher.ScimpiException;
040    import org.apache.isis.viewer.scimpi.dispatcher.ScimpiNotFoundException;
041    import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
042    import org.apache.isis.viewer.scimpi.dispatcher.debug.DebugUsers;
043    import org.apache.isis.viewer.scimpi.dispatcher.debug.DebugWriter;
044    
045    public class ServletRequestContext extends RequestContext {
046        private HttpServletRequest request;
047        private HttpServletResponse response;
048        private ServletContext servletContext;
049        private boolean isAborted;
050    
051        public ServletRequestContext(final DebugUsers debugUsers) {
052            super(debugUsers);
053        }
054    
055        public void append(final DebugWriter view) {
056            /*
057             * view.divider("System"); Runtime.getRuntime().
058             */
059            view.appendTitle("Request");
060            view.appendln("Auth type", request.getAuthType());
061            view.appendln("Character encoding", request.getCharacterEncoding());
062            view.appendln("Class", request.getClass());
063            view.appendln("Content type", request.getContentType());
064            view.appendln("Context path", getContextPath());
065            view.appendln("Locale", request.getLocale());
066            view.appendln("Method", request.getMethod());
067            view.appendln("Path info", request.getPathInfo());
068            view.appendln("Path translated", request.getPathTranslated());
069            view.appendln("Protocol", request.getProtocol());
070            view.appendln("Query string", request.getQueryString());
071            view.appendln("Remote host", request.getRemoteHost());
072            view.appendln("Remote user", request.getRemoteUser());
073            view.appendln("Real path", servletContext.getRealPath("/"));
074            view.appendln("Scheme", request.getScheme());
075            view.appendln("Server name", request.getServerName());
076            view.appendln("Servlet path", request.getServletPath());
077            view.appendln("Session", request.getSession());
078            view.appendln("Session ID", request.getRequestedSessionId());
079            view.appendln("URI", request.getRequestURI());
080            view.appendln("URL", request.getRequestURL());
081            view.appendln("User principle", request.getUserPrincipal());
082    
083            view.appendTitle("Cookies");
084            final Cookie[] cookies = request.getCookies();
085            for (final Cookie cookie : cookies) {
086                view.appendln(cookie.getName(), cookie.getValue());
087            }
088    
089            final Enumeration attributeNames = request.getAttributeNames();
090            if (attributeNames.hasMoreElements()) {
091                view.appendTitle("Attributes");
092                while (attributeNames.hasMoreElements()) {
093                    final String name = (String) attributeNames.nextElement();
094                    view.appendln(name, request.getAttribute(name));
095                }
096            }
097    
098            view.appendTitle("Headers");
099            final Enumeration headerNames = request.getHeaderNames();
100            while (headerNames.hasMoreElements()) {
101                final String name = (String) headerNames.nextElement();
102                view.appendln(name, request.getHeader(name));
103            }
104    
105            view.appendTitle("Parameters");
106            final Enumeration parameterNames = request.getParameterNames();
107            while (parameterNames.hasMoreElements()) {
108                final String name = (String) parameterNames.nextElement();
109                view.appendln(name, request.getParameter(name));
110            }
111    
112            view.appendTitle("Servlet Context");
113            final ServletContext context = getServletContext();
114            view.appendln("Name", context.getServletContextName());
115            view.appendln("Server Info", context.getServerInfo());
116            view.appendln("Version", context.getMajorVersion() + "." + context.getMinorVersion());
117            view.appendln("Attributes", getAttributes(context));
118            view.appendln("Init parameters", getParameters(context));
119            view.appendln("Real path", context.getRealPath("/"));
120    
121            super.append(view);
122        }
123    
124        private String getAttributes(final ServletContext context) {
125            final StringBuffer buf = new StringBuffer();
126            final Enumeration names = context.getAttributeNames();
127            while (names.hasMoreElements()) {
128                final String name = (String) names.nextElement();
129                buf.append(name + "=" + context.getAttribute(name));
130            }
131            return buf.toString();
132        }
133    
134        private String getParameters(final ServletContext context) {
135            final StringBuffer buf = new StringBuffer();
136            final Enumeration names = context.getInitParameterNames();
137            while (names.hasMoreElements()) {
138                final String name = (String) names.nextElement();
139                buf.append(name + "=" + context.getInitParameter(name));
140            }
141            return buf.toString();
142        }
143    
144        public void startRequest(final HttpServletRequest request, final HttpServletResponse response,
145            final ServletContext servletContext) {
146            this.request = request;
147            this.response = response;
148            this.servletContext = servletContext;
149            final Enumeration parameterNames = request.getParameterNames();
150            while (parameterNames.hasMoreElements()) {
151                final String name = (String) parameterNames.nextElement();
152                addParameter(name, request.getParameter(name));
153            }
154    
155            // TODO move this
156            // response.sendError(403);
157            // response.setContentType("text/html");
158        }
159    
160        public HttpServletRequest getRequest() {
161            return request;
162        }
163    
164        public HttpServletResponse getResponse() {
165            return response;
166        }
167    
168        public ServletContext getServletContext() {
169            return servletContext;
170        }
171    
172        @Override
173        public PrintWriter getWriter() {
174            try {
175                return response.getWriter();
176            } catch (final IOException e) {
177                throw new ScimpiException(e);
178            }
179        }
180    
181        @Override
182        public String findFile(final String fileName) {
183            try {
184                if (getServletContext().getResource(fileName) == null) {
185                    return null;
186                } else {
187                    return fileName;
188                }
189            } catch (final MalformedURLException e) {
190                throw new ScimpiException(e);
191            }
192        }
193    
194        @Override
195        public InputStream openStream(final String path) {
196            final InputStream in = servletContext.getResourceAsStream(path);
197    
198            if (in == null) {
199                servletContext.getResourcePaths("/");
200                try {
201                    servletContext.getResource(path);
202                } catch (final MalformedURLException e) {
203                    throw new ScimpiException(e);
204                }
205    
206                throw new ScimpiNotFoundException("Cannot find file " + path);
207            }
208            return in;
209        }
210    
211        @Override
212        public void startHttpSession() {
213            addVariable("_auth_session", getSession(), Scope.SESSION);
214            final HttpSession httpSession = request.getSession(true);
215            final Map<String, Object> sessionData = getSessionData();
216            httpSession.setAttribute("scimpi-context", sessionData);
217        }
218    
219        @Override
220        protected String getSessionId() {
221            return request.getSession().getId();
222        }
223    
224        @Override
225        public String clearSession() {
226            request.getSession().invalidate();
227            return null;
228        }
229    
230        @Override
231        public void reset() {
232            try {
233                response.getWriter().print("<h1>RESET</h1>");
234            } catch (final IOException e) {
235                throw new DispatchException(e);
236            }
237            response.reset();
238        }
239    
240        @Override
241        public void forward(final String view) {
242            try {
243                isAborted = true;
244                getRequest().getRequestDispatcher(view).forward(getRequest(), getResponse());
245            } catch (final IOException e) {
246                throw new DispatchException(e);
247            } catch (final ServletException e) {
248                throw new DispatchException(e);
249            }
250        }
251    
252        @Override
253        public void redirectTo(final String view) {
254            try {
255                isAborted = true;
256                getResponse().sendRedirect(view);
257            } catch (final IOException e) {
258                throw new DispatchException(e);
259            }
260        }
261    
262        @Override
263        public void raiseError(final int status) {
264            try {
265                isAborted = true;
266                getResponse().sendError(status);
267            } catch (final IOException e) {
268                throw new RuntimeException(e);
269            }
270            getResponse().setStatus(status);
271        }
272    
273        @Override
274        public boolean isAborted() {
275            return isAborted;
276        }
277    
278        @Override
279        public void setContentType(final String string) {
280            getResponse().setContentType(string);
281        }
282    
283        @Override
284        public String imagePath(final ObjectAdapter object) {
285            final String contextPath = getContextPath();
286            return ImageLookup.imagePath(object, contextPath);
287        }
288    
289        @Override
290        public String imagePath(final ObjectSpecification specification) {
291            final String contextPath = getContextPath();
292            return ImageLookup.imagePath(specification, contextPath);
293        }
294    
295        @Override
296        public String getContextPath() {
297            return request.getContextPath();
298        }
299    
300        @Override
301        public String getHeader(final String name) {
302            return request.getHeader(name);
303        }
304    
305        @Override
306        public String getQueryString() {
307            return request.getQueryString();
308        }
309    
310        @Override
311        public String getUri() {
312            return request.getRequestURI() + "?" + request.getQueryString();
313        }
314    
315        @Override
316        public String getUrlBase() {
317            // return request.getScheme() + request.getServerName() + request.getServerPort();
318            final StringBuffer url = request.getRequestURL();
319            url.setLength(url.length() - request.getRequestURI().length());
320            return url.toString();
321        }
322    
323        @Override
324        public void addCookie(final String name, final String value, final int minutesUtilExpires) {
325            final Cookie cookie = new Cookie(name, value);
326            cookie.setMaxAge(minutesUtilExpires * 60);
327            response.addCookie(cookie);
328        }
329    
330        @Override
331        public String getCookie(final String name) {
332            final Cookie[] cookies = request.getCookies();
333            if (cookies != null) {
334                for (final Cookie cookie : cookies) {
335                    if (cookie.getName().equals(name)) {
336                        return cookie.getValue();
337                    }
338                }
339            }
340            return null;
341        }
342    }