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, final ServletContext servletContext) {
145            this.request = request;
146            this.response = response;
147            this.servletContext = servletContext;
148            final Enumeration parameterNames = request.getParameterNames();
149            while (parameterNames.hasMoreElements()) {
150                final String name = (String) parameterNames.nextElement();
151                addParameter(name, request.getParameter(name));
152            }
153    
154            // TODO move this
155            // response.sendError(403);
156            // response.setContentType("text/html");
157        }
158    
159        public HttpServletRequest getRequest() {
160            return request;
161        }
162    
163        public HttpServletResponse getResponse() {
164            return response;
165        }
166    
167        public ServletContext getServletContext() {
168            return servletContext;
169        }
170    
171        @Override
172        public PrintWriter getWriter() {
173            try {
174                return response.getWriter();
175            } catch (final IOException e) {
176                throw new ScimpiException(e);
177            }
178        }
179    
180        @Override
181        public String findFile(final String fileName) {
182            try {
183                if (getServletContext().getResource(fileName) == null) {
184                    return null;
185                } else {
186                    return fileName;
187                }
188            } catch (final MalformedURLException e) {
189                throw new ScimpiException(e);
190            }
191        }
192    
193        @Override
194        public InputStream openStream(final String path) {
195            final InputStream in = servletContext.getResourceAsStream(path);
196    
197            if (in == null) {
198                servletContext.getResourcePaths("/");
199                try {
200                    servletContext.getResource(path);
201                } catch (final MalformedURLException e) {
202                    throw new ScimpiException(e);
203                }
204    
205                throw new ScimpiNotFoundException("Cannot find file " + path);
206            }
207            return in;
208        }
209    
210        @Override
211        public void startHttpSession() {
212            addVariable("_auth_session", getSession(), Scope.SESSION);
213            final HttpSession httpSession = request.getSession(true);
214            final Map<String, Object> sessionData = getSessionData();
215            httpSession.setAttribute("scimpi-context", sessionData);
216        }
217    
218        @Override
219        protected String getSessionId() {
220            return request.getSession().getId();
221        }
222    
223        @Override
224        public String clearSession() {
225            request.getSession().invalidate();
226            return null;
227        }
228    
229        @Override
230        public void reset() {
231            try {
232                response.getWriter().print("<h1>RESET</h1>");
233            } catch (final IOException e) {
234                throw new DispatchException(e);
235            }
236            response.reset();
237        }
238    
239        @Override
240        public void forward(final String view) {
241            try {
242                isAborted = true;
243                getRequest().getRequestDispatcher(view).forward(getRequest(), getResponse());
244            } catch (final IOException e) {
245                throw new DispatchException(e);
246            } catch (final ServletException e) {
247                throw new DispatchException(e);
248            }
249        }
250    
251        @Override
252        public void redirectTo(final String view) {
253            try {
254                isAborted = true;
255                getResponse().sendRedirect(view);
256            } catch (final IOException e) {
257                throw new DispatchException(e);
258            }
259        }
260    
261        @Override
262        public void raiseError(final int status) {
263            try {
264                isAborted = true;
265                getResponse().sendError(status);
266            } catch (final IOException e) {
267                throw new RuntimeException(e);
268            }
269            getResponse().setStatus(status);
270        }
271    
272        @Override
273        public boolean isAborted() {
274            return isAborted;
275        }
276    
277        @Override
278        public void setContentType(final String string) {
279            getResponse().setContentType(string);
280        }
281    
282        @Override
283        public String imagePath(final ObjectAdapter object) {
284            final String contextPath = getContextPath();
285            return ImageLookup.imagePath(object, contextPath);
286        }
287    
288        @Override
289        public String imagePath(final ObjectSpecification specification) {
290            final String contextPath = getContextPath();
291            return ImageLookup.imagePath(specification, contextPath);
292        }
293    
294        @Override
295        public String getContextPath() {
296            return request.getContextPath();
297        }
298    
299        @Override
300        public String getHeader(final String name) {
301            return request.getHeader(name);
302        }
303    
304        @Override
305        public String getQueryString() {
306            return request.getQueryString();
307        }
308    
309        @Override
310        public String getUri() {
311            return request.getRequestURI() + "?" + request.getQueryString();
312        }
313    
314        @Override
315        public String getUrlBase() {
316            // return request.getScheme() + request.getServerName() +
317            // 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    }