PlaceMap.java 8.31 KB
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fi.insomnia.bortal.servlet;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.EJBAccessException;
import javax.ejb.EJBException;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fi.insomnia.bortal.beans.LoggingBeanLocal;
import fi.insomnia.bortal.beans.PermissionBeanLocal;
import fi.insomnia.bortal.beans.PlaceMapBeanLocal;
import fi.insomnia.bortal.beans.SecurityLogType;
import fi.insomnia.bortal.enums.apps.MapPermission;
import fi.insomnia.bortal.model.EventMap;
import fi.insomnia.bortal.model.EventUser;
import fi.insomnia.bortal.model.Place;

/**
 * 
 * @author tuukka
 */
public class PlaceMap extends HttpServlet {

	private static final Logger logger = LoggerFactory
			.getLogger(PlaceMap.class);

	private static final long serialVersionUID = 8769688627918936258L;
	@EJB
	private transient PlaceMapBeanLocal placemapBean;

	@EJB
	private transient PermissionBeanLocal permbean;

	@EJB
	private transient LoggingBeanLocal loggerbean;

	private static final String PARAMETER_EVENT_MAP_ID = "mapid";

	/**
	 * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
	 * methods.
	 * 
	 * @param request
	 *            servlet request
	 * @param response
	 *            servlet response
	 * @throws ServletException
	 *             if a servlet-specific error occurs
	 * @throws IOException
	 *             if an I/O error occurs
	 */
	protected void processRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		logger.debug("Begin processing request");
		// response.setContentType("text/html;charset=UTF-8");

		// PrintWriter out = response.getWriter();
		ServletOutputStream ostream = null;
		try {
			// Integer placeId = getIntegerParameter(request,
			// PARAMETER_SELECTED_PLACE_ID);

			Integer mapId = getIntegerParameter(request, PARAMETER_EVENT_MAP_ID);
			// Integer userId = getIntegerParameter(request,
			// PARAMETER_CURRENT_USER_ID); Tämä saadaan beaneilta.

			EventMap map = placemapBean.findMap(mapId);
			logger.debug("Mapid: {}", mapId);
			ostream = response.getOutputStream();

			if (map == null || map.getMapData() == null) {
				logger.warn("Error handling map {}!", map);
				response.setStatus(HttpServletResponse.SC_NOT_FOUND);
				ostream.print("Map error!");

			} else {
				response.setContentType("image/jpeg");
				printPlaceMapToStream(ostream, "jpg", map);
				logger.debug("Flushing ostream");
				ostream.flush();
			}
			/*
			 * TODO output your page here out.println("<html>");
			 * out.println("<head>");
			 * out.println("<title>Servlet PlaceMap</title>");
			 * out.println("</head>"); out.println("<body>");
			 * out.println("<h1>Servlet PlaceMap at " + request.getContextPath
			 * () + "</h1>"); out.println("</body>"); out.println("</html>");
			 */
		} catch (EJBException e) {
			logger.debug("Permission denied. Returning SC_FORBIDDEN!");
			response.setContentType("text/html;charset=UTF-8");
			response.setStatus(HttpServletResponse.SC_FORBIDDEN);
			ostream = response.getOutputStream();
			ostream.print("Error 403 \nPermission denied! Please login before accessing resource");
		} finally {
			if (ostream != null) {
				ostream.close();
			}
		}
	}

	private void printPlaceMapToStream(OutputStream outputStream,
			String filetype, EventMap map) throws IOException
	{

		if (!permbean.hasPermission(MapPermission.VIEW))
		{
			loggerbean.logMessage(SecurityLogType.permissionDenied, permbean.getCurrentUser(),
					"User tried to print the placemap to stream without sufficient permissions");
			throw new EJBAccessException("Not enough permissions to print placemap");
		}
		long begin = new Date().getTime();

		// List<Place> selectedPlaceList = placeBean.findPlaces(placeIds);

		// logger.debug("SelectedPlaceList: size {}, {} ",
		// selectedPlaceList.size(), selectedPlaceList);

		// map = eventMapFacade.find(eventId, mapId);

		// if (map == null) {
		// throw new PermissionDeniedException(secubean, user,
		// "Map not found with id: " + mapId + " and event id: " +
		// eventbean.getCurrentEvent());
		// }

		// logger.debug("Got map object {}", map);
		List<Place> places = map.getPlaces();

		EventUser user = permbean.getCurrentUser();
		// List<Place> selectedPlaces = placemapBean.findSelectedPlaces(map);

		BufferedImage image = ImageIO.read(new ByteArrayInputStream(map
				.getMapData()));

		Graphics2D g2d = image.createGraphics();
		for (Place place : places) {
			drawPlace(place, g2d, user);
		}

		// BufferedImage image = map.getMapWithPlaces(, selectedPlaces);

		logger.debug("Prewrite {}", new Date().getTime() - begin);
		ImageIO.write(image, filetype, outputStream);
		logger.debug("postwrite {}", new Date().getTime() - begin);

	}

	/***
	 * Convert request parameter into integer
	 * 
	 * @param request
	 * @param parameter
	 * @return
	 */
	private static Integer getIntegerParameter(HttpServletRequest request,
			String parameter) {
		try {
			String valueString = request.getParameter(parameter);
			Integer value = Integer.parseInt(valueString);
			return value;
		} catch (NumberFormatException nfe) {
		}
		return null;
	}

	// <editor-fold defaultstate="collapsed"
	// desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
	/**
	 * Handles the HTTP <code>GET</code> method.
	 * 
	 * @param request
	 *            servlet request
	 * @param response
	 *            servlet response
	 * @throws ServletException
	 *             if a servlet-specific error occurs
	 * @throws IOException
	 *             if an I/O error occurs
	 */
	@Override
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * Handles the HTTP <code>POST</code> method.
	 * 
	 * @param request
	 *            servlet request
	 * @param response
	 *            servlet response
	 * @throws ServletException
	 *             if a servlet-specific error occurs
	 * @throws IOException
	 *             if an I/O error occurs
	 */
	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * Returns a short description of the servlet.
	 * 
	 * @return a String containing servlet description
	 */
	@Override
	public String getServletInfo() {
		return "Short description";
	}// </editor-fold>

	private static final Color RESERVED_COLOR = Color.RED;
	private static final Color SELECTED_COLOR = Color.BLUE;
	private static final Color OWNED_COLOR = Color.GREEN;
	private static final Color BORDER_COLOR = Color.BLACK;
	private static final Color LOCKED_COLOR = Color.DARK_GRAY;
	private static final int BORDER_WIDTH = 2;

	private static void drawPlace(Place p, Graphics2D g, EventUser user) {
		if (p.isDisabled()) {
			return;
		}
		Color color = null;
		if (!p.isBuyable()) {
			color = LOCKED_COLOR;
		}
		if (p.isReservedFor(user)) {
			color = SELECTED_COLOR;
		} else if (user.equals(p.getCurrentUser())
				|| (p.getGroup() != null && user.equals(p.getGroup()
						.getCreator()))
				|| (p.getPlaceReserver() != null && user.equals(p
						.getPlaceReserver().getUser()))) {
			color = OWNED_COLOR;
		} else if (p.isTaken()) {
			color = RESERVED_COLOR;
		} else if (p.getProduct().getColor() != null && !p.getProduct().getColor().isEmpty()) {

			try {
				color = Color.decode(p.getProduct().getColor());
			} catch (NumberFormatException x) {
				logger.error("Cannot convert string {} to color.", p.getProduct().getColor());
			}
		}

		g.setColor(BORDER_COLOR);
		g.draw(new Rectangle(p.getMapX(), p.getMapY(), p.getWidth(), p
				.getHeight()));

		if (color != null) {
			g.setColor(color);
			g.fill(new Rectangle(p.getMapX() + BORDER_WIDTH, p.getMapY()
					+ BORDER_WIDTH, p.getWidth() - BORDER_WIDTH, p.getHeight()
					- BORDER_WIDTH));
		}
	}
}