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
020package org.apache.isis.core.webapp.content;
021
022import java.io.FileInputStream;
023import java.io.FileNotFoundException;
024import java.io.IOException;
025import java.io.InputStream;
026
027import javax.servlet.ServletException;
028import javax.servlet.http.HttpServlet;
029import javax.servlet.http.HttpServletRequest;
030import javax.servlet.http.HttpServletResponse;
031
032import org.slf4j.Logger;
033import org.slf4j.LoggerFactory;
034
035import org.apache.isis.core.commons.lang.InputStreamExtensions;
036import org.apache.isis.core.commons.lang.ResourceUtil;
037import org.apache.isis.core.commons.lang.StringExtensions;
038
039public class ResourceServlet extends HttpServlet {
040
041    private static final Logger LOG = LoggerFactory.getLogger(ResourceServlet.class);
042    private static final long serialVersionUID = 1L;
043
044    @Override
045    protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
046        processRequest(request, response);
047    }
048
049    @Override
050    protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
051        processRequest(request, response);
052    }
053
054    private void processRequest(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
055        final String servletPath = StringExtensions.stripLeadingSlash(request.getServletPath());
056        if (LOG.isDebugEnabled()) {
057            LOG.debug("request: " + servletPath);
058        }
059
060        // try to load from filesystem
061        final InputStream is2 = getRealPath(request);
062        if (is2 != null) {
063            if (LOG.isDebugEnabled()) {
064                LOG.debug("request: " + servletPath + " loaded from filesystem");
065            }
066            writeContentType(request, response);
067            InputStreamExtensions.copyTo(is2, response.getOutputStream());
068            is2.close();
069            return;
070        }
071
072        // otherwise, try to load from classpath
073        final InputStream is = ResourceUtil.getResourceAsStream(servletPath);
074        if (is != null) {
075            if (LOG.isDebugEnabled()) {
076                LOG.debug("request: " + servletPath + " loaded from classpath");
077            }
078            writeContentType(request, response);
079            InputStreamExtensions.copyTo(is, response.getOutputStream());
080            is.close();
081            return;
082        }
083
084        LOG.warn("failed to load resource from classpath or file system: " + servletPath);
085    }
086
087    private static void writeContentType(final HttpServletRequest request, final HttpServletResponse response) {
088        final String contentType = guessContentType(request.getServletPath());
089        if(contentType != null) {
090            response.setContentType(contentType);
091        }
092    }
093
094    private static String guessContentType(String servletPath) {
095        if(servletPath.endsWith(".js")) {
096            return "application/x-javascript";
097        } else if(servletPath.endsWith(".css")) {
098            return "text/css";
099        } else if(servletPath.endsWith(".html")) {
100            return "text/html";
101        } else if(servletPath.endsWith(".png")) {
102            return "image/png";
103        } else if(servletPath.endsWith(".jpg")) {
104            return "image/jpeg";
105        } else if(servletPath.endsWith(".jpeg")) {
106            return "image/jpeg";
107        } else if(servletPath.endsWith(".gif")) {
108            return "image/gif";
109        }
110        return null;
111    }
112
113    private FileInputStream getRealPath(final HttpServletRequest request) {
114        final String realPath = request.getSession().getServletContext().getRealPath(request.getServletPath());
115        if (realPath == null) {
116            return null;
117        }
118        try {
119            return new FileInputStream(realPath);
120        } catch (final FileNotFoundException e) {
121            return null;
122        }
123    }
124}