001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2011 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.server.plugins; 021 022 import org.apache.commons.io.IOUtils; 023 import org.apache.commons.lang.StringUtils; 024 import org.slf4j.Logger; 025 import org.slf4j.LoggerFactory; 026 import org.sonar.server.platform.Platform; 027 028 import java.io.IOException; 029 import java.io.InputStream; 030 import java.io.OutputStream; 031 032 import javax.servlet.ServletException; 033 import javax.servlet.http.HttpServlet; 034 import javax.servlet.http.HttpServletRequest; 035 import javax.servlet.http.HttpServletResponse; 036 037 public class StaticResourcesServlet extends HttpServlet { 038 039 private static final Logger LOG = LoggerFactory.getLogger(StaticResourcesServlet.class); 040 private static final long serialVersionUID = -2577454614650178426L; 041 042 @Override 043 public void doGet(HttpServletRequest request, HttpServletResponse response) 044 throws ServletException, IOException { 045 String pluginKey = getPluginKey(request); 046 String resource = getResourcePath(request); 047 048 DefaultServerPluginRepository pluginRepository = Platform.getInstance().getContainer().getComponentByType(DefaultServerPluginRepository.class); 049 ClassLoader classLoader = pluginRepository.getClassloader(pluginKey); 050 if (classLoader == null) { 051 LOG.error("Plugin not found: " + pluginKey); 052 response.sendError(HttpServletResponse.SC_NOT_FOUND); 053 return; 054 } 055 InputStream in = null; 056 OutputStream out = null; 057 try { 058 in = classLoader.getResourceAsStream(resource); 059 if (in != null) { 060 out = response.getOutputStream(); 061 IOUtils.copy(in, out); 062 } else { 063 LOG.error("Unable to find resource '" + resource + "' in plugin '" + pluginKey + "'"); 064 response.sendError(HttpServletResponse.SC_NOT_FOUND); 065 } 066 } catch (Exception e) { 067 LOG.error("Unable to load static resource '" + resource + "' from plugin '" + pluginKey + "'", e); 068 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 069 } finally { 070 IOUtils.closeQuietly(in); 071 IOUtils.closeQuietly(out); 072 } 073 } 074 075 /** 076 * @return part of request URL after servlet path 077 */ 078 protected String getPluginKeyAndResourcePath(HttpServletRequest request) { 079 return StringUtils.substringAfter(request.getRequestURI(), request.getContextPath() + request.getServletPath() + "/"); 080 } 081 082 protected String getPluginKey(HttpServletRequest request) { 083 return StringUtils.substringBefore(getPluginKeyAndResourcePath(request), "/"); 084 } 085 086 /** 087 * Note that returned value should not have a leading "/" - see {@link Class#resolveName(String)}. 088 */ 089 protected String getResourcePath(HttpServletRequest request) { 090 return "static/" + StringUtils.substringAfter(getPluginKeyAndResourcePath(request), "/"); 091 } 092 }