package org.ff4j.web.controller; /* * #%L * ff4j-sample-web * %% * Copyright (C) 2013 - 2016 FF4J * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import static org.ff4j.web.bean.WebConstants.CONTENT_TYPE_CSS; import static org.ff4j.web.bean.WebConstants.CONTENT_TYPE_JS; import static org.ff4j.web.bean.WebConstants.CONTENT_TYPE_TEXT; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.activation.MimetypesFileTypeMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.ff4j.FF4j; import org.ff4j.web.utils.FileUtils; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.WebContext; /** * Load static resource and create response, overriding content type. * * @author Cedrick LUNVEN (@clunven) */ public class StaticResourceController extends AbstractController { /** Eternal cache for css. */ private Map < String, String > cssFiles = new HashMap< String, String >(); /** Eternal cache for js. */ private Map < String, String > jsFiles = new HashMap< String, String >(); /** Eternal cache for js. */ private Map < String, byte[] > fontFiles = new HashMap< String, byte[] >(); /** Eternal cache for images. */ private Map < String, byte[] > images = new HashMap< String, byte[] >(); /** {@inheritDoc} */ public StaticResourceController(FF4j ff4j, TemplateEngine te) { super(ff4j, null, te); } /** {@inheritDoc} */ public void post(HttpServletRequest req, HttpServletResponse res, WebContext ctx) throws IOException { LOGGER.warn("Nothing to implement in POST"); } /** {@inheritDoc} */ public void get(HttpServletRequest req, HttpServletResponse res, WebContext ctx) throws IOException { // static/{type}/{fileName} String pathInfo = req.getPathInfo(); if (pathInfo == null) { pathInfo = "/"; } String[] pathParts = pathInfo.split("/"); // By Convention the fileSystem will follow the same pattern if (pathParts.length >=3) { String resourceType = pathParts[2]; String resourceName = pathParts[pathParts.length - 1]; if ("css".equalsIgnoreCase(resourceType)) { serveCss(res, pathInfo, resourceName); } else if ("js".equalsIgnoreCase(resourceType)) { serveJs(res, pathInfo, resourceName); } else if ("font".equalsIgnoreCase(resourceType)) { serveFont(res, pathInfo, resourceName); } else if ("img".equalsIgnoreCase(resourceType)) { serveImage(res, pathInfo, resourceName); } else { notFound(res, pathInfo); } } else { notFound(res, pathInfo); } } /* * Load CSS Files */ private void serveCss(HttpServletResponse res, String pathInfo, String resourceName) throws IOException { try { if (!cssFiles.containsKey(resourceName)) { cssFiles.put(resourceName, FileUtils.loadFileAsString(pathInfo)); } res.setContentType(CONTENT_TYPE_CSS); res.getWriter().println(cssFiles.get(resourceName)); } catch (FileNotFoundException fnf) { notFound(res, "CSS File " + pathInfo + "(" + resourceName + ")"); } } /* * Load font files */ private void serveFont(HttpServletResponse res, String pathInfo, String resourceName) throws IOException { try { if (!fontFiles.containsKey(resourceName)) { fontFiles.put(resourceName, FileUtils.loadFileAsByteArray(pathInfo)); } MimetypesFileTypeMap mimetypesFileTypeMap=new MimetypesFileTypeMap(); res.setContentType(mimetypesFileTypeMap.getContentType(resourceName)); res.getOutputStream().write(fontFiles.get(resourceName)); } catch (FileNotFoundException fnf) { notFound(res, "fontFiles " + pathInfo + "(" + resourceName + ")"); } } /* * Load Js files */ private void serveJs(HttpServletResponse res, String pathInfo, String resourceName) throws IOException { try { if (!jsFiles.containsKey(resourceName)) { jsFiles.put(resourceName, FileUtils.loadFileAsString(pathInfo)); } res.setContentType(CONTENT_TYPE_JS); res.getWriter().println(jsFiles.get(resourceName)); } catch (FileNotFoundException fnf) { notFound(res, "CSS File " + pathInfo + "(" + resourceName + ")"); } } /* * Load Images */ private void serveImage(HttpServletResponse res, String pathInfo, String resourceName) throws IOException { try { if (!images.containsKey(resourceName)) { images.put(resourceName, FileUtils.loadFileAsByteArray(pathInfo)); } MimetypesFileTypeMap mimetypesFileTypeMap=new MimetypesFileTypeMap(); res.setContentType(mimetypesFileTypeMap.getContentType(resourceName)); res.getOutputStream().write(images.get(resourceName)); } catch(FileNotFoundException fnf) { notFound(res, pathInfo); } } private void notFound(HttpServletResponse res, String pathInfo) throws IOException { res.setContentType(CONTENT_TYPE_TEXT); res.getWriter().println("Ressource [" + pathInfo + "] not found"); } }