package com.qcadoo.view; import com.google.common.collect.Sets; import org.apache.commons.io.IOUtils; import com.qcadoo.localization.internal.ConfigUtil; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.net.URLConnection; import java.nio.file.DirectoryStream; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.List; import java.util.Set; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.support.SpringBeanAutowiringSupport; public class FilesystemResourcesFilter implements Filter { private final Set EXTENSIONS = Sets.newHashSet("js", "css"); @Autowired private ConfigUtil configUtil; @Override public void init(FilterConfig conf) { SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, conf.getServletContext()); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (configUtil.isHotDeploy() && request instanceof HttpServletRequest) { HttpServletRequest httpRequest = (HttpServletRequest) request; if (!serveResource(httpRequest, (HttpServletResponse) response)) { chain.doFilter(request, response); } } else { chain.doFilter(request, response); } } public boolean serveResource(final HttpServletRequest request, final HttpServletResponse response) { InputStream resource = getResourceFromURI(request.getRequestURI()); if (resource != null) { response.setContentType(getContentTypeFromURI(request)); try { IOUtils.copy(resource, response.getOutputStream()); } catch (IOException e) { throw new IllegalStateException(e.getMessage(), e); } finally { try { resource.close(); } catch (IOException ignore) { } } return true; } return false; } private InputStream getResourceFromURI(final String uri) { int dotIndex = uri.lastIndexOf('.'); if (dotIndex != -1) { String extension = uri.substring(dotIndex + 1); if (EXTENSIONS.contains(extension)) { List<String> prefixes = Arrays.asList("/mes/mes-plugins/", "/mes-commercial/", "/qcadoo/"); for (String prefix : prefixes) { Path dir = FileSystems.getDefault().getPath(configUtil.getSourceBasePath() + prefix); try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) { for (Path pluginMainDir : stream) { Path file = pluginMainDir.resolve("src/main/resources/").resolve(uri.substring(1)); if (Files.exists(file)) { return file.toUri().toURL().openStream(); } } } catch (IOException e) { throw new RuntimeException(e); } } } } return null; } private String getContentTypeFromURI(final HttpServletRequest request) { String[] arr = request.getRequestURI().split("\\."); String ext = arr[arr.length - 1]; if ("js".equals(ext)) { return "text/javascript"; } else if ("css".equals(ext)) { return "text/css"; } else { return URLConnection.guessContentTypeFromName(request.getRequestURL().toString()); } } @Override public void destroy() { } }