/*
 * Licensed under MIT (https://github.com/ligoj/ligoj/blob/master/LICENSE)
 */
package org.ligoj.app.resource.plugin;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import javax.activation.FileTypeMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * This servlet enables Servlet 2.x compliant containers to serve up Webjars resources
 * </p>
 * <p>
 * Copied from org.webjars:webjars-servlet-2.x:1.5, because we need to retrieve webjars resources from Thread
 * Classloader and not only in web-inf/lib. We also removed cache management.
 * </p>
 */
@Slf4j
public class WebjarsServlet extends HttpServlet {

	/**
	 * serial version uid
	 */
	private static final long serialVersionUID = 2461047578940577569L;

	/**
	 * Additional mime types
	 */
	private final Map<String, String> mimeTypes = new HashMap<>();

	/**
	 * Constructor registering additional MIME types.
	 */
	public WebjarsServlet() {
		// Register additional MIME types
		mimeTypes.put("woff", "application/font-woff");
		mimeTypes.put("woff2", "font/woff2");
		mimeTypes.put("ttf", "application/x-font-truetype");
		mimeTypes.put("eot", "application/vnd.ms-fontobject");
		mimeTypes.put("svg", "image/svg+xml");
		mimeTypes.put("otf", "application/x-font-opentype");
	}

	@Override
	protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
		final String webjarsResourceURI = "META-INF/resources" + request.getRequestURI().replaceFirst(request.getContextPath(), "");
		log.debug("Webjars resource requested: {}", webjarsResourceURI);

		if (isDirectoryRequest(webjarsResourceURI)) {
			// Directory listing is forbidden, but act as a 404 for security purpose.
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
			return;
		}

		// Regular file
		final InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(webjarsResourceURI);
		if (inputStream == null) {
			// File not found --> 404
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
		} else {
			serveFile(response, webjarsResourceURI, inputStream);
		}
	}

	/**
	 * Copy the file stream to the response using the right mime type
	 */
	private void serveFile(final HttpServletResponse response, final String webjarsResourceURI, final InputStream inputStream) throws IOException {
		try {
			final String filename = getFileName(webjarsResourceURI);
			response.setContentType(guessMimeType(filename));
			inputStream.transferTo(response.getOutputStream());
			response.flushBuffer();
		} finally {
			inputStream.close();
		}
	}

	/**
	 * Guess the MIME type from the file name.
	 * 
	 * @param filename
	 *            The requested file name.
	 * @return The resolved MIME type. May be <code>null</code>.
	 */
	protected String guessMimeType(final String filename) {
		// First, get the mime type provided by the Servlet container
		String mimeType = this.getServletContext().getMimeType(filename);
		if (mimeType == null) {
			// Use the static extension based extension
			mimeType = mimeTypes.get(FilenameUtils.getExtension(filename));
		}
		if (mimeType == null) {
			// Use the mime type guess by JSE
			mimeType = FileTypeMap.getDefaultFileTypeMap().getContentType(filename);
		}
		return mimeType;
	}

	/**
	 * Is it a directory request ?
	 * 
	 * @param uri
	 *            Requested resource's URI.
	 * @return <code>true</code> when URI is a directory request
	 */
	private static boolean isDirectoryRequest(final String uri) {
		return uri.endsWith("/");
	}

	/**
	 * Retrieve file name from given URI.
	 * 
	 * @param webjarsResourceURI
	 *            Requested resource's URI.
	 * @return The resolved file name.
	 */
	private String getFileName(final String webjarsResourceURI) {
		return Paths.get(webjarsResourceURI).toFile().getName();
	}

}

@@ -188,21 +188,72 @@
 va.n
-io.file.Paths
+et.URL;%0Aimport java.nio.file.Paths;%0Aimport java.util.Enumeration
 ;%0Aim
@@ -2144,148 +2144,326 @@
 file
-%0A%09%09final InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(webjarsResourceURI);%0A%09%09if (inputStream
+, use the last resource instead of the first found%0A%09%09final Enumeration%3CURL%3E resources = Thread.currentThread().getContextClassLoader().getResources(webjarsResourceURI);%0A%09%09URL webjarsResourceURL = null;%0A%09%09while(resources.hasMoreElements()) %7B%0A%09%09%09webjarsResourceURL = resources.nextElement();%0A%09%09%7D%0A%09%09if (webjarsResourceURL
  == 
@@ -2610,27 +2610,47 @@
 rceURI, 
-input
+webjarsResourceURL.open
 Stream
+()
 );%0A%09%09%7D%0A%09

Support multiple versions of the same plug-in in classpath