Commit c6d5c2cc by Tuukka Kivilahti

Merge branch 'placemapRest' into 'master'

Placemap rest and new svg placemap initial

* Placemap place fetching with rest
* jsonp-support for all REST functions
* Access-Control-Allow-Origin for REST functions
* Initial skeleton implementation of javascript placemap

See merge request !132

Kattoi: @tkfftk, vilkuilin uudet kohdat van nopeasti läpi, vanht katoin ehkä vähän tarkemmin.
2 parents 608b617d cc5888fd
Showing with 1911 additions and 386 deletions
......@@ -34,6 +34,7 @@ import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.GroupMembership;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.model.PlaceGroup;
import fi.codecrew.moya.model.Product;
/**
*
......@@ -98,4 +99,20 @@ public interface PlaceBeanLocal {
public EventMap getActiveMap();
/**
* Get all maps
*
* @return
*/
List<EventMap> getMaps();
/**
* Get all products used in map;
* @param map
*
* @return
*/
List<Product> getMapProducts(EventMap map);
}
......@@ -225,11 +225,11 @@ public class BootstrapBean implements BootstrapBeanLocal {
"ALTER TABLE group_memberships ADD COLUMN place_product INTEGER",
"ALTER TABLE group_memberships ADD CONSTRAINT FK_group_memberships_place_product FOREIGN KEY (place_product) REFERENCES products (id)"
});
dbUpdates.add(new String[] {
"ALTER TABLE events ADD COLUMN ticket_sales_begin timestamp without time zone DEFAULT null;",
});
dbUpdates.add(new String[] {
"ALTER TABLE events ADD COLUMN theme varchar(255) DEFAULT null;",
});
......@@ -239,12 +239,15 @@ public class BootstrapBean implements BootstrapBeanLocal {
dbUpdates.add(new String[] {
"DELETE FROM product_productflags where productflags = 'PREPAID_INSTANT_CREATE'"
});
dbUpdates.add(new String[] {
"ALTER TABLE food_wave_templates ADD COLUMN wait_payments_minutes integer DEFAULT null;",
});
dbUpdates.add(new String[] {
"ALTER TABLE maps ADD COLUMN width integer",
"ALTER TABLE maps ADD COLUMN height integer",
});
} // start_time timestamp without time zone,
......@@ -298,16 +301,16 @@ public class BootstrapBean implements BootstrapBeanLocal {
dbModelFacade.create(dBm);
}
}
// We will never run this again with empty database
// public void saneDefaults() {
// User adminUser = userFacade.findByLogin("admin");
// if (adminUser == null) {
// adminUser = new User();
// adminUser.setLogin("admin");
// // adminUser.setSuperadmin(true);
// adminUser.resetPassword("admin");
// userFacade.create(adminUser);
// }
// }
// We will never run this again with empty database
// public void saneDefaults() {
// User adminUser = userFacade.findByLogin("admin");
// if (adminUser == null) {
// adminUser = new User();
// adminUser.setLogin("admin");
// // adminUser.setSuperadmin(true);
// adminUser.resetPassword("admin");
// userFacade.create(adminUser);
// }
// }
}
......@@ -686,4 +686,14 @@ public class PlaceBean implements PlaceBeanLocal {
return null;
}
@Override
public List<EventMap> getMaps() {
return eventMapFacade.getMaps();
}
@Override
public List<Product> getMapProducts(EventMap map) {
return placeFacade.getMapProducts(map);
}
}
......@@ -18,10 +18,18 @@
*/
package fi.codecrew.moya.facade;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.model.EventMap;
import fi.codecrew.moya.model.EventMap_;
@Stateless
@LocalBean
......@@ -31,4 +39,16 @@ public class EventMapFacade extends IntegerPkGenericFacade<EventMap> {
super(EventMap.class);
}
@EJB
private EventBeanLocal eventbean;
public List<EventMap> getMaps()
{
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<EventMap> cq = cb.createQuery(EventMap.class);
Root<EventMap> root = cq.from(EventMap.class);
cq.where(cb.equal(root.get(EventMap_.event), eventbean.getCurrentEvent()),
cb.isTrue(root.get(EventMap_.active)));
return getEm().createQuery(cq).getResultList();
}
}
......@@ -29,6 +29,7 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -41,6 +42,7 @@ import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.model.Place_;
import fi.codecrew.moya.model.Product;
import fi.codecrew.moya.model.Product_;
@Stateless
@LocalBean
......@@ -208,4 +210,21 @@ public class PlaceFacade extends IntegerPkGenericFacade<Place> {
return getSingleNullableResult(getEm().createQuery(cq));
}
public List<Product> getMapProducts(EventMap map) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<Product> cq = cb.createQuery(Product.class);
Root<Product> root = cq.from(Product.class);
Subquery<Integer> subq = cq.subquery(Integer.class);
Root<Place> subroot = subq.from(Place.class);
subq.select(subroot.get(Place_.product).get(Product_.id));
subq.distinct(true);
subq.where(cb.equal(subroot.get(Place_.map), map));
cq.where(root.get(Product_.id).in(subq));
return getEm().createQuery(cq).getResultList();
}
}
......@@ -39,103 +39,125 @@ import org.eclipse.persistence.annotations.PrivateOwned;
@Table(name = "maps")
public class EventMap extends GenericEntity {
private static final long serialVersionUID = 3411450245513673619L;
@ManyToOne()
private LanEvent event;
public LanEvent getEvent() {
return event;
}
public void setEvent(LanEvent event) {
this.event = event;
}
@Lob
@Column(name = "map_data")
private byte[] mapData;
@Column(name = "map_name")
private String name;
@OrderBy("name")
@OneToMany(cascade = CascadeType.ALL, mappedBy = "map")
@PrivateOwned
private List<Place> places = new ArrayList<Place>();
@OneToMany(mappedBy = "eventMap")
private List<Reader> readers;
@Column(nullable = false)
private boolean active = true;
@Column(name = "notes")
@Lob
private String notes;
public EventMap() {
super();
}
public EventMap(LanEvent event) {
super();
this.event = event;
}
public String getName() {
return name;
}
public void setName(String mapName) {
this.name = mapName;
}
public List<Place> getPlaces() {
return places;
}
public void setPlaces(List<Place> placeList) {
this.places = placeList;
}
/**
* @return the readers
*/
public List<Reader> getReaders() {
return readers;
}
/**
* @param readers
* the readers to set
*/
public void setReaders(List<Reader> readers) {
this.readers = readers;
}
public void setMapData(byte[] mapData) {
this.mapData = mapData;
}
public byte[] getMapData() {
return mapData;
}
public void setActive(boolean active) {
this.active = active;
}
public boolean isActive() {
return active;
}
public void setNotes(String notes) {
this.notes = notes;
}
public String getNotes() {
return notes;
}
private static final long serialVersionUID = 3411450245513673619L;
@ManyToOne()
private LanEvent event;
public LanEvent getEvent() {
return event;
}
public void setEvent(LanEvent event) {
this.event = event;
}
@Lob
@Column(name = "map_data")
private byte[] mapData;
@Column(name = "map_name")
private String name;
@OrderBy("name")
@OneToMany(cascade = CascadeType.ALL, mappedBy = "map")
@PrivateOwned
private List<Place> places = new ArrayList<Place>();
@OneToMany(mappedBy = "eventMap")
private List<Reader> readers;
@Column(nullable = false)
private boolean active = true;
@Column(name = "notes")
@Lob
private String notes;
@Column()
private Integer width;
@Column()
private Integer height;
public EventMap() {
super();
}
public EventMap(LanEvent event) {
super();
this.event = event;
}
public String getName() {
return name;
}
public void setName(String mapName) {
this.name = mapName;
}
public List<Place> getPlaces() {
return places;
}
public void setPlaces(List<Place> placeList) {
this.places = placeList;
}
/**
* @return the readers
*/
public List<Reader> getReaders() {
return readers;
}
/**
* @param readers
* the readers to set
*/
public void setReaders(List<Reader> readers) {
this.readers = readers;
}
public void setMapData(byte[] mapData) {
this.mapData = mapData;
}
public byte[] getMapData() {
return mapData;
}
public void setActive(boolean active) {
this.active = active;
}
public boolean isActive() {
return active;
}
public void setNotes(String notes) {
this.notes = notes;
}
public String getNotes() {
return notes;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}
......@@ -18,6 +18,7 @@
*/
package fi.codecrew.moya.model;
import java.awt.Color;
import java.util.Calendar;
import javax.persistence.CascadeType;
......@@ -41,260 +42,293 @@ import fi.codecrew.moya.utilities.NumericStringComparator;
@Table(name = "places")
public class Place extends GenericEntity implements Comparable<Place> {
/**
/**
*
*/
private static final long serialVersionUID = -5314851260772328611L;
@Lob
@Column(name = "place_description")
private String description;
@Column(name = "place_name")
private String name;
@Column(name = "map_x")
private int mapX = 0;
@Column(name = "map_y")
private int mapY = 0;
@Column(name = "width")
private int width = 0;
@Column(name = "height")
private int height = 0;
@Column(name = "release_time")
@Temporal(TemporalType.TIMESTAMP)
private Calendar releaseTime;
@Column(name = "place_details")
@Lob
private String details = "";
@Column(name = "place_code")
private String code = "";
@OneToOne(mappedBy = "placeReservation")
private GroupMembership placeReserver;
@Column(name = "buyable", nullable = false)
private boolean buyable = true;
@Column(nullable = false)
private boolean disabled = false;
/**
* Which group has bought the place
*/
@ManyToOne
@JoinColumn(name = "group_id", referencedColumnName = "id")
private PlaceGroup group;
@ManyToOne
@JoinColumn(name = "provided_role_id", referencedColumnName = Role.ID_COLUMN)
private Role providesRole;
@JoinColumn(name = "map_id", referencedColumnName = EventMap.ID_COLUMN, nullable = true)
@ManyToOne(optional = true, cascade = CascadeType.ALL)
private EventMap map;
/**
* Which ticket type is this place sold as
*/
@JoinColumn(name = "products_id", referencedColumnName = Product.ID_COLUMN)
@ManyToOne()
private Product product;
/**
* Who is the current currentUser (mapped with code printed on the place) of
* the place. Used in Vectorama currentUser tracking.
*/
@JoinColumn(name = "current_eventuser_id", referencedColumnName = EventUser.ID_COLUMN)
@ManyToOne
private EventUser currentUser;
public Place() {
super();
}
public Place(EventMap eventMap) {
super();
this.map = eventMap;
}
public String getDescription() {
return description;
}
public void setDescription(String placeDescription) {
this.description = placeDescription;
}
public String getName() {
return name;
}
public void setName(String placeName) {
this.name = placeName;
}
public Integer getMapX() {
return mapX;
}
public void setMapX(Integer mapX) {
this.mapX = mapX;
}
public Integer getMapY() {
return mapY;
}
public void setMapY(Integer mapY) {
this.mapY = mapY;
}
public String getDetails() {
return details;
}
public void setDetails(String placeDetails) {
this.details = placeDetails;
}
public String getCode() {
return code;
}
public void setCode(String placeCode) {
this.code = placeCode;
}
public PlaceGroup getGroup() {
return group;
}
public void setGroup(PlaceGroup group) {
if (group != null && map != null && !group.getEvent().equals(map.getEvent())) {
throw new RuntimeException("Can not set Group from different Event to Place!");
}
this.group = group;
}
public EventMap getMap() {
return map;
}
public void setMap(EventMap map) {
this.map = map;
}
public Product getProduct() {
return product;
}
public void setProduct(Product productsId) {
this.product = productsId;
}
public EventUser getCurrentUser() {
return currentUser;
}
public void setCurrentUser(EventUser usersId) {
this.currentUser = usersId;
}
public void setPlaceReserver(GroupMembership placeReserver) {
this.placeReserver = placeReserver;
}
public GroupMembership getPlaceReserver() {
return placeReserver;
}
private static final long serialVersionUID = -5314851260772328611L;
@Lob
@Column(name = "place_description")
private String description;
@Column(name = "place_name")
private String name;
@Column(name = "map_x")
private int mapX = 0;
@Column(name = "map_y")
private int mapY = 0;
@Column(name = "width")
private int width = 0;
@Column(name = "height")
private int height = 0;
@Column(name = "release_time")
@Temporal(TemporalType.TIMESTAMP)
private Calendar releaseTime;
@Column(name = "place_details")
@Lob
private String details = "";
@Column(name = "place_code")
private String code = "";
@OneToOne(mappedBy = "placeReservation")
private GroupMembership placeReserver;
@Column(name = "buyable", nullable = false)
private boolean buyable = true;
@Column(nullable = false)
private boolean disabled = false;
/**
* Which group has bought the place
*/
@ManyToOne
@JoinColumn(name = "group_id", referencedColumnName = "id")
private PlaceGroup group;
/**
* @return the height
*/
public Integer getHeight() {
return height;
}
@ManyToOne
@JoinColumn(name = "provided_role_id", referencedColumnName = Role.ID_COLUMN)
private Role providesRole;
/**
* @param height
* the height to set
*/
public void setHeight(Integer height) {
this.height = height;
}
@JoinColumn(name = "map_id", referencedColumnName = EventMap.ID_COLUMN, nullable = true)
@ManyToOne(optional = true, cascade = CascadeType.ALL)
private EventMap map;
/**
* Which ticket type is this place sold as
*/
@JoinColumn(name = "products_id", referencedColumnName = Product.ID_COLUMN)
@ManyToOne()
private Product product;
/**
* Who is the current currentUser (mapped with code printed on the place) of
* the place. Used in Vectorama currentUser tracking.
*/
@JoinColumn(name = "current_eventuser_id", referencedColumnName = EventUser.ID_COLUMN)
@ManyToOne
private EventUser currentUser;
/**
* @return the width
*/
public Integer getWidth() {
return width;
}
public static enum PlaceState {
FREE, DISABLED, LOCKED, TEMP_RESERVED_FORME,
MY_PLACE, RESERVED
}
/**
* @param width
* the width to set
*/
public void setWidth(Integer width) {
this.width = width;
}
public PlaceState getState(EventUser user)
{
PlaceState ret = PlaceState.FREE;
if (isDisabled()) {
ret = PlaceState.DISABLED;
} else {
public boolean isTaken() {
if (!isBuyable()) {
ret = PlaceState.LOCKED;
}
if (isTaken()) {
ret = PlaceState.RESERVED;
// logger.debug("Setting place Reserved {}", p);
}
}
if (user != null) {
if (isReservedFor(user)) {
ret = PlaceState.TEMP_RESERVED_FORME;
} else if (user.equals(getCurrentUser())
|| (getGroup() != null && user.equals(getGroup().getCreator()))
|| (getPlaceReserver() != null && user.equals(getPlaceReserver().getUser()))) {
ret = PlaceState.MY_PLACE;
return (getReleaseTime() != null || getGroup() != null);
}
}
}
/**
*
* @return Is the place reserved ( not bought for user)
*/
public boolean isReservedFor(EventUser u) {
return (u.equals(getCurrentUser()) && getGroup() == null);
}
return ret;
}
/**
* Check if the places releasetime has expired and it should be released for
* shopping
*
* @return If the status of thie entity changed and it should be merged.
*/
public boolean checkReleased() {
boolean ret = false;
if (getGroup() == null && getReleaseTime() != null && Calendar.getInstance().after(getReleaseTime())) {
setCurrentUser(null);
setReleaseTime(null);
ret = true;
}
return ret;
}
public void setBuyable(boolean buyable) {
this.buyable = buyable;
}
public boolean isBuyable() {
return buyable;
}
public void setReleaseTime(Calendar releaseTime) {
this.releaseTime = releaseTime;
}
public Calendar getReleaseTime() {
return releaseTime;
}
public void setProvidesRole(Role providesRole) {
this.providesRole = providesRole;
}
public Role getProvidesRole() {
return providesRole;
}
public boolean isDisabled() {
return disabled;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
public Place() {
super();
}
public Place(EventMap eventMap) {
super();
this.map = eventMap;
}
public String getDescription() {
return description;
}
public void setDescription(String placeDescription) {
this.description = placeDescription;
}
public String getName() {
return name;
}
public void setName(String placeName) {
this.name = placeName;
}
public Integer getMapX() {
return mapX;
}
public void setMapX(Integer mapX) {
this.mapX = mapX;
}
public Integer getMapY() {
return mapY;
}
public void setMapY(Integer mapY) {
this.mapY = mapY;
}
public String getDetails() {
return details;
}
public void setDetails(String placeDetails) {
this.details = placeDetails;
}
public String getCode() {
return code;
}
public void setCode(String placeCode) {
this.code = placeCode;
}
public PlaceGroup getGroup() {
return group;
}
public void setGroup(PlaceGroup group) {
if (group != null && map != null && !group.getEvent().equals(map.getEvent())) {
throw new RuntimeException("Can not set Group from different Event to Place!");
}
this.group = group;
}
public EventMap getMap() {
return map;
}
public void setMap(EventMap map) {
this.map = map;
}
public Product getProduct() {
return product;
}
public void setProduct(Product productsId) {
this.product = productsId;
}
public EventUser getCurrentUser() {
return currentUser;
}
public void setCurrentUser(EventUser usersId) {
this.currentUser = usersId;
}
public void setPlaceReserver(GroupMembership placeReserver) {
this.placeReserver = placeReserver;
}
public GroupMembership getPlaceReserver() {
return placeReserver;
}
/**
* @return the height
*/
public Integer getHeight() {
return height;
}
/**
* @param height
* the height to set
*/
public void setHeight(Integer height) {
this.height = height;
}
/**
* @return the width
*/
public Integer getWidth() {
return width;
}
/**
* @param width
* the width to set
*/
public void setWidth(Integer width) {
this.width = width;
}
public boolean isTaken() {
return (getReleaseTime() != null || getGroup() != null);
}
/**
*
* @return Is the place reserved ( not bought for user)
*/
public boolean isReservedFor(EventUser u) {
return (u.equals(getCurrentUser()) && getGroup() == null);
}
/**
* Check if the places releasetime has expired and it should be released for
* shopping
*
* @return If the status of thie entity changed and it should be merged.
*/
public boolean checkReleased() {
boolean ret = false;
if (getGroup() == null && getReleaseTime() != null && Calendar.getInstance().after(getReleaseTime())) {
setCurrentUser(null);
setReleaseTime(null);
ret = true;
}
return ret;
}
public void setBuyable(boolean buyable) {
this.buyable = buyable;
}
public boolean isBuyable() {
return buyable;
}
public void setReleaseTime(Calendar releaseTime) {
this.releaseTime = releaseTime;
}
public Calendar getReleaseTime() {
return releaseTime;
}
public void setProvidesRole(Role providesRole) {
this.providesRole = providesRole;
}
public Role getProvidesRole() {
return providesRole;
}
public boolean isDisabled() {
return disabled;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
/**
* Note: this class has a natural ordering that is inconsistent with equals.
......
......@@ -18,7 +18,12 @@
<res-ref-name>jsf/ProjectStage</res-ref-name>
<res-type>java.lang.String</res-type>
</resource-ref>
<!-- Handle hostname filter BEFORE jsonp so errors are transmitted correctly -->
<absolute-ordering>
<name>jsonpFilter</name>
<name>hostnameFilter</name>
</absolute-ordering>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
......@@ -28,7 +33,8 @@
req.queryString and req.userAgent to logger MDC -->
<filter>
<filter-name>MDCInsertingServletFilter</filter-name>
<filter-class>ch.qos.logback.classic.helpers.MDCInsertingServletFilter</filter-class>
<filter-class>ch.qos.logback.classic.helpers.MDCInsertingServletFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>MDCInsertingServletFilter</filter-name>
......@@ -41,20 +47,14 @@
<filter-class>org.primefaces.webapp.filter.FileUploadFilter
</filter-class>
</filter>
<filter>
<display-name>HostnameFilter</display-name>
<filter-name>HostnameFilter</filter-name>
<filter-class>fi.codecrew.moya.HostnameFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimefacesFileupload</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>HostnameFilter</filter-name>
<servlet-name>*</servlet-name>
</filter-mapping>
<!-- <filter> <display-name>HostnameFilter</display-name> <filter-name>HostnameFilter</filter-name>
<filter-class>fi.codecrew.moya.HostnameFilter</filter-class> </filter> <filter-mapping>
<filter-name>HostnameFilter</filter-name> <servlet-name>*</servlet-name>
</filter-mapping> -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
......@@ -115,5 +115,5 @@
<persistence-unit-ref>
<persistence-unit-ref-name>BortalEMF</persistence-unit-ref-name>
</persistence-unit-ref>
</web-app>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:map="http://java.sun.com/jsf/composite/cditools/map"
xmlns:tools="http://java.sun.com/jsf/composite/cditools"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<h:body>
<ui:composition template="#{sessionHandler.template}">
<f:metadata>
<f:event type="preRenderView" listener="#{ajaxMapView.initMap()}" />
<f:viewParam name="userid" value="#{userView.userid}" />
</f:metadata>
<ui:param name="thispage" value="page.place.placemap" />
<ui:define name="content">
<button
onclick="alert('pre');placeClicker([{name:'placeId', value:1}]);alert('post');">button</button>
<h:form>
<p:remoteCommand name="placeClicker" update=":fbdiag"
action="#{ajaxMapView.placeClicked()}" />
</h:form>
<p:dialog visible="#{!empty ajaxMapView.place}" id="fbdiag">
Clicked place name : #{ajaxMapView.place.name};
<h:link rendered="#{!empty ajaxMapView.place}" outcome="/place/edit">
<f:param name="placeid" value="#{ajaxMapView.place.id}" />
Muokkaa
</h:link>
</p:dialog>
<h:outputScript target="head" library="seatjs" name="d3.min.js" />
<h:outputScript target="head" library="seatjs" name="d3-tip.js" />
<h:outputScript target="head" library="seatjs" name="seatmap.js" />
<h:outputStylesheet library="seatjs" name="placemap.css" />
<svg id="seatmap" style="margin: auto; border: 1px solid black;"
width="1200px" height="800px" />
<script type="text/javascript">
px = placemap({
element : document.getElementById("seatmap"),
moyaurl : "#{request.contextPath}",
map_id : #{ajaxMapView.map.id},
onclick : function(d) {
alert(d);
placeClicker([{name: 'placeId', value: d}])
return true;
}
});
// document.getElementById("editbutton").addEventListener("click",
// function() {
// px.enable_edit();
// });
//px.enable_edit();
</script>
</ui:define>
</ui:composition>
</h:body>
</html>
\ No newline at end of file
// d3.tip
// Copyright (c) 2013 Justin Palmer
//
// Tooltips for d3.js SVG visualizations
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module with d3 as a dependency.
define(['d3'], factory)
} else if (typeof module === 'object' && module.exports) {
// CommonJS
module.exports = function(d3) {
d3.tip = factory(d3)
return d3.tip
}
} else {
// Browser global.
root.d3.tip = factory(root.d3)
}
}(this, function (d3) {
// Public - contructs a new tooltip
//
// Returns a tip
return function() {
var direction = d3_tip_direction,
offset = d3_tip_offset,
html = d3_tip_html,
node = initNode(),
svg = null,
point = null,
target = null
function tip(vis) {
svg = getSVGNode(vis)
point = svg.createSVGPoint()
document.body.appendChild(node)
}
// Public - show the tooltip on the screen
//
// Returns a tip
tip.show = function() {
var args = Array.prototype.slice.call(arguments)
if(args[args.length - 1] instanceof SVGElement) target = args.pop()
var content = html.apply(this, args),
poffset = offset.apply(this, args),
dir = direction.apply(this, args),
nodel = d3.select(node),
i = directions.length,
coords,
scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
nodel.html(content)
.style({ opacity: 1, 'pointer-events': 'all' })
while(i--) nodel.classed(directions[i], false)
coords = direction_callbacks.get(dir).apply(this)
nodel.classed(dir, true).style({
top: (coords.top + poffset[0]) + scrollTop + 'px',
left: (coords.left + poffset[1]) + scrollLeft + 'px'
})
return tip
}
// Public - hide the tooltip
//
// Returns a tip
tip.hide = function() {
var nodel = d3.select(node)
nodel.style({ opacity: 0, 'pointer-events': 'none' })
return tip
}
// Public: Proxy attr calls to the d3 tip container. Sets or gets attribute value.
//
// n - name of the attribute
// v - value of the attribute
//
// Returns tip or attribute value
tip.attr = function(n, v) {
if (arguments.length < 2 && typeof n === 'string') {
return d3.select(node).attr(n)
} else {
var args = Array.prototype.slice.call(arguments)
d3.selection.prototype.attr.apply(d3.select(node), args)
}
return tip
}
// Public: Proxy style calls to the d3 tip container. Sets or gets a style value.
//
// n - name of the property
// v - value of the property
//
// Returns tip or style property value
tip.style = function(n, v) {
if (arguments.length < 2 && typeof n === 'string') {
return d3.select(node).style(n)
} else {
var args = Array.prototype.slice.call(arguments)
d3.selection.prototype.style.apply(d3.select(node), args)
}
return tip
}
// Public: Set or get the direction of the tooltip
//
// v - One of n(north), s(south), e(east), or w(west), nw(northwest),
// sw(southwest), ne(northeast) or se(southeast)
//
// Returns tip or direction
tip.direction = function(v) {
if (!arguments.length) return direction
direction = v == null ? v : d3.functor(v)
return tip
}
// Public: Sets or gets the offset of the tip
//
// v - Array of [x, y] offset
//
// Returns offset or
tip.offset = function(v) {
if (!arguments.length) return offset
offset = v == null ? v : d3.functor(v)
return tip
}
// Public: sets or gets the html value of the tooltip
//
// v - String value of the tip
//
// Returns html value or tip
tip.html = function(v) {
if (!arguments.length) return html
html = v == null ? v : d3.functor(v)
return tip
}
function d3_tip_direction() { return 'n' }
function d3_tip_offset() { return [0, 0] }
function d3_tip_html() { return ' ' }
var direction_callbacks = d3.map({
n: direction_n,
s: direction_s,
e: direction_e,
w: direction_w,
nw: direction_nw,
ne: direction_ne,
sw: direction_sw,
se: direction_se
}),
directions = direction_callbacks.keys()
function direction_n() {
var bbox = getScreenBBox()
return {
top: bbox.n.y - node.offsetHeight,
left: bbox.n.x - node.offsetWidth / 2
}
}
function direction_s() {
var bbox = getScreenBBox()
return {
top: bbox.s.y,
left: bbox.s.x - node.offsetWidth / 2
}
}
function direction_e() {
var bbox = getScreenBBox()
return {
top: bbox.e.y - node.offsetHeight / 2,
left: bbox.e.x
}
}
function direction_w() {
var bbox = getScreenBBox()
return {
top: bbox.w.y - node.offsetHeight / 2,
left: bbox.w.x - node.offsetWidth
}
}
function direction_nw() {
var bbox = getScreenBBox()
return {
top: bbox.nw.y - node.offsetHeight,
left: bbox.nw.x - node.offsetWidth
}
}
function direction_ne() {
var bbox = getScreenBBox()
return {
top: bbox.ne.y - node.offsetHeight,
left: bbox.ne.x
}
}
function direction_sw() {
var bbox = getScreenBBox()
return {
top: bbox.sw.y,
left: bbox.sw.x - node.offsetWidth
}
}
function direction_se() {
var bbox = getScreenBBox()
return {
top: bbox.se.y,
left: bbox.e.x
}
}
function initNode() {
var node = d3.select(document.createElement('div'))
node.style({
position: 'absolute',
top: 0,
opacity: 0,
'pointer-events': 'none',
'box-sizing': 'border-box'
})
return node.node()
}
function getSVGNode(el) {
el = el.node()
if(el.tagName.toLowerCase() === 'svg')
return el
return el.ownerSVGElement
}
// Private - gets the screen coordinates of a shape
//
// Given a shape on the screen, will return an SVGPoint for the directions
// n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
// sw(southwest).
//
// +-+-+
// | |
// + +
// | |
// +-+-+
//
// Returns an Object {n, s, e, w, nw, sw, ne, se}
function getScreenBBox() {
var targetel = target || d3.event.target,
bbox = {},
matrix = targetel.getScreenCTM(),
tbbox = targetel.getBBox(),
width = tbbox.width,
height = tbbox.height,
x = tbbox.x,
y = tbbox.y
point.x = x
point.y = y
bbox.nw = point.matrixTransform(matrix)
point.x += width
bbox.ne = point.matrixTransform(matrix)
point.y += height
bbox.se = point.matrixTransform(matrix)
point.x -= width
bbox.sw = point.matrixTransform(matrix)
point.y -= height / 2
bbox.w = point.matrixTransform(matrix)
point.x += width
bbox.e = point.matrixTransform(matrix)
point.x -= width / 2
point.y -= height / 2
bbox.n = point.matrixTransform(matrix)
point.y += height
bbox.s = point.matrixTransform(matrix)
return bbox
}
return tip
};
}));
This diff could not be displayed because it is too large.
/*
Placemap css for Moya
*/
.place-tooltip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
/* Creates a small triangle extender for the tooltip */
.place-tooltip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "\25BC";
position: absolute;
text-align: center;
}
/* Style northward tooltips differently */
.place-tooltip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
.place-tooltip-upside {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
/*
.place-tooltip-upside:before {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "\25B2";
position: absolute;
text-align: center;
}
.place-tooltip-upside.n:before {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
*/
.place-edit-tooltip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 10px;
}
.place-edit-tooltip fieldset li {
list-style: none;
padding: 5px;
margin: 0;
}
.place-edit-tooltip fieldset ol {
margin: 0;
padding: 0;
}
.place-edit-tooltip label {
display: inline-block;
line-height: 0.9;
vertical-align: top;
}
.place-edit-tooltip fieldset {
border: none;
margin: 3px 0 0;
}
.place-edit-tooltip label {
width: 70px;
}
.place-edit-tooltip input.numeric {
width: 30px;
}
.place-edit-tooltip fieldset fieldset label {
display: block;
width: auto;
margin-left: 120px;
}
#place_close_popup {
font-size: small;
font-weight: bold;
float: right;
color: #eee;
display: block;
text-decoration: none;
border: 2px solid #666;
padding: 0px 3px 0px 3px;
}
/*
Seatmap javascript library for Moya
*/
function placemap(opts)
{
if ( opts.element === undefined )
{
throw "element is mandatory argument";
}
if ( opts.moyaurl === undefined )
{
throw "moyaurl is mandatory argument";
}
if ( opts.map_id === undefined )
{
throw "map_id is mandatory argument";
}
if (opts.onclick === undefined )
{
throw "onclick is mandatory argument";
}
// px is returned object
var px = {
element: d3.select(opts.element),
moyaurl: opts.moyaurl,
map_id: opts.map_id,
onclick: opts.onclick
};
var guide_layer = map_layer = px.element.append("g").attr("id", "guides");
// Create background
var background = px.element.append("rect")
.attr("class", "background_2")
.attr("width", px.element.attr('width'))
.attr("height", px.element.attr('width'))
.attr("opacity", 0);
// Define layers to use
var map_layer = px.element.append("g").attr("id", "places");
var edit_layer = map_layer = px.element.append("g").attr("id", "edit");
var clicked = false;
px.place_colors = {
"F": "#cccccc",
"L": "#535353",
"R": "#B40100",
"P": "#2FA525",
"T": "#4342C1"
};
px.snap_threshold = {x: 5, y: 5};
var clickpos = {x: 0, y: 0};
var tip = d3.tip()
.attr('class', 'place-tooltip')
.offset([-10, 0])
.html(function(d) {
return "<strong>" + d.name + "</strong>";
});
// TODO: Fix this tip layout
var tip_updown = d3.tip().direction("s")
.attr('class', 'place-tooltip-upside')
.offset([10, 0])
.html(function(d) {
return "<strong>" + d.name + "</strong>";
});
function draw_guides(x1, y1, x2, y2, fade)
{
var guide = guide_layer.append('line')
.attr('x1', x1)
.attr('y1', y1)
.attr('x2', x2)
.attr('y2', y2)
.attr("stroke-width", 1)
.attr("stroke", "#666")
if (fade == true)
{
guide.transition()
.duration(500)
.remove();
}
}
function clear_guides()
{
guide_layer.selectAll('line').remove();
}
function snap_to_edges(x, y, fade)
{
// TODO: if there is node in range, snap coordinates next to it
if (clicked == true) return;
var xmin = x - px.snap_threshold.x;
var xmax = x + px.snap_threshold.x;
var ymin = y - px.snap_threshold.y;
var ymax = y + px.snap_threshold.y;
var xnode, ynode;
var left, top, right, bottom;
map_layer.selectAll('rect').each(function(d) {
left = d.x;
top = d.y;
right = d.x + d.w;
bottom = d.y + d.h;
if (d.x > xmin && d.x < xmax)
{
if (xnode === undefined || Math.abs(x - d.x) < Math.abs(x - xnode.x))
{
x = d.x;
xnode = d;
}
}
if (right > xmin && right < xmax)
{
if (xnode === undefined || Math.abs(x - right) < Math.abs(x - xnode.x - xnode.w))
{
x = right;
xnode = d;
}
}
if (d.y > ymin && d.y < ymax)
{
if (ynode === undefined || Math.abs(y - top) < Math.abs(y - ynode.y)) {
y = d.y;
ynode = d;
}
}
if (bottom > ymin && bottom < ymax)
{
if (ynode === undefined || Math.abs(y - bottom) < Math.abs(y - ynode.y - ynode.h)) {
y = bottom;
ynode = d;
}
}
});
clear_guides();
if (ynode !== undefined)
{
if (ynode.y == y) draw_guides(ynode.x, ynode.y, x, y, fade);
else draw_guides(ynode.x, ynode.y + ynode.h, x, y, fade);
}
if (xnode !== undefined)
{
if (xnode.x == x) draw_guides(xnode.x, xnode.y, x, y, fade);
else draw_guides(xnode.x + xnode.w, xnode.y, x, y, fade);
}
return [x, y]
}
function show_tooltip(d, i) {
var object = {
x: d3.select(this).attr('x'),
y: d3.select(this).attr('y'),
width: d3.select(this).attr('width'),
height: d3.select(this).attr('height')
};
if (object.y >= 40)
{
return tip.show(d, i);
}
else {
return tip_updown.show(d, i);
}
}
function hide_tooltip(d, i)
{
tip.hide(d, i);
tip_updown.hide(d, i);
}
function toggle_clicked(element)
{
// TODO: reserve place from rest first!
data = element.data()[0];
if (px.onclick(data.id) != true) return;
if (data.state == "F")
{
element.transition().duration(100).style("fill", px.place_colors["P"]);
data.state = "P";
}
else if (data.state == "P")
{
element.transition()
.duration(100).style("fill", px.place_colors["F"]);
data.state = "F";
}
}
function place_color(d, i)
{
if (Object.keys(px.place_colors).indexOf(d.state) != -1) return px.place_colors[d.state];
return "#888";
}
function draw_places(data)
{
// TODO: update functionality!
var places = map_layer.selectAll("rect")
.data(data, function(d) { return d.id; }).enter()
.append("rect")
.filter(function(d,i){ return d.state != "D"; })
.attr("x", function(d, i) { return d.x; })
.attr("y", function(d, i) { return d.y; })
.attr("width", function(d, i) { return d.w;})
.attr("height", function(d, i) { return d.h; })
.attr("id", function(d) {return d.id })
.style("fill", place_color)
.style('stroke', '#101010')
.style('stroke-width', '1');
places.append("title", function(d, i) { return d.name; });
if (px.edit_enabled == false)
{
places
.on('mouseover', show_tooltip)
.on('mouseout', hide_tooltip)
.on('click', function (d, i) {
toggle_clicked(d3.select(this));
});
}
}
function edit_clicked(d, i) {
c = d3.mouse(this);
var pos = {x: c[0], y: c[1]};
// Begin click action
if (clicked == false)
{
//coords = snap_to_edges(pos.x, pos.y, true);
clicked = true;
pos.x = coords[0];
pos.y = coords[1];
clickpos = pos;
edit_layer.append("circle")
.attr("cx", pos.x)
.attr("cy", pos.y)
.attr("r", 2)
.attr("width", 10)
.attr("height", 10)
.attr("fill", "#111");
tip_add_places.show(pos.x, pos.y);
}
else {
edit_layer.selectAll("circle").remove();
clicked = false;
tip_add_places.hide(d, i);
}
}
px.edit_enabled = false;
px.enable_edit = function()
{
map_layer.selectAll('rect')
.on('click', null);
background.on("click", edit_clicked);
background.on("mousemove", function(){
c = d3.mouse(this);
var pos = {x: c[0], y: c[1]};
coords = snap_to_edges(pos.x, pos.y, false);
});
px.edit_enabled = true;
};
function gen_row(x,y, width, height, direction, count)
{
var places = [];
place = 1;
for (var i = 0; i < count; i++)
{
places.push({x: x, y: y, w: width, h: height, name: "foo" + i + x + y, id: i*1000+y*100+x, state: "F"});
place += 1;
if (direction == "horizontal")
{
x += width;
}
else {
y += height;
}
}
return places;
}
px.update = function() {
d3.json(px.moyaurl + "/rest/placemap/v1/" + px.map_id + "/places", function(data) {
draw_places(data.places);
});
};
px.init = function() {
d3.json(px.moyaurl + "/rest/placemap/v1/" + px.map_id + "/", function(data){
px.element.attr("id", data.map.id).attr("name", data.map.name);
px.update()
});
};
px.init();
px.element.call(tip);
px.element.call(tip_updown);
// Add tooltip
// TODO: Make this less ugly!
function create_tooltip()
{
var mytip = {};
mytip.node = d3.select(document.createElement('div'));
mytip.offset = [20, 10]
mytip.node.attr("class", 'place-edit-tooltip');
mytip.node.style({
position: 'absolute',
top: 0,
opacity: 0,
'pointer-events': 'none',
'box-sizing': 'border-box'
});
document.body.appendChild(mytip.node.node())
mytip.node.html('<span id="place_close_popup">X</span>'+
'<form><fieldset><ol>'+
'<li><label for="place_add_count">Count:</label><input name="count" id="place_add_count" value=1 class="numeric", min=1, max=999999><span id="place_add_count_error"></span></li>'+
'<li><label for="place_add_width">Width:</label><input name="width" id="place_add_width" value=10 class="numeric", min=1, max=999999> px <span id="place_add_width_error"></span></li>'+
'<li><label for="place_add_height">Height:</label><input name="height" id="place_add_height" value=10 class="numeric", min=1, max=999999> px <span id="place_add_height_error"></span></li>'+
'<li><label for="place_add_direction">Direction:</label>'+
'<select name="place_add_direction" id="place_add_direction"><option value="horizontal">Horizontal &rarr;</option><option value="vertical">Vertical &darr;</option></select></li>'+
'<li><input type="button" name="place_add_rows" id="place_add_rows" value="Add places"></li>'+
'</fieldset></form>');
function number_validator(f, ef) {
return function() {
var field = f;
var errorfield = ef;
var derrorfield = d3.select(ef);
var dfield = d3.select(f);
var min = parseInt(field.min);
var max = parseInt(field.max);
var num = -1;
try {
num = parseInt(field.value)
}
catch(err) {
console.log(err);
}
if (num < min)
{
dfield.style({"border": "2px solid #e22"});
derrorfield.html(" " + field.name + " must be &gt; " + min);
}
else if (num > max)
{
dfield.style({"border": "2px solid #e22"});
derrorfield.html(" " + field.name + " must be &lt; " + max);
}
else if (isNaN(num))
{
dfield.style({"border": "2px solid #e22"});
derrorfield.html(" " + field.name + " must be number");
}
else {
dfield.style({"border": "none"});
derrorfield.html("");
}
}
}
document.getElementById("place_add_count").addEventListener("change",
number_validator(document.getElementById("place_add_count"),
document.getElementById("place_add_count_error")
));
document.getElementById("place_add_width").addEventListener("change",
number_validator(document.getElementById("place_add_width"),
document.getElementById("place_add_width_error")
));
document.getElementById("place_add_height").addEventListener("change",
number_validator(document.getElementById("place_add_height"),
document.getElementById("place_add_height_error")
));
document.getElementById("place_close_popup").addEventListener("click", function(){
edit_layer.selectAll("circle").remove();
clicked = false;
mytip.hide();
});
mytip.show = function (x, y)
{
mytip.node.style ({
top: y + mytip.offset[1] + "px",
left: x + mytip.offset[0] + "px",
opacity: 1,
'pointer-events': 'all'
});
};
mytip.hide = function ()
{
mytip.node.style ({
opacity: 0,
'pointer-events': 'none'
});
};
return mytip;
}
var tip_add_places = create_tooltip();
function add_places(){
var width = parseInt(document.getElementById("place_add_width").value);
var height = parseInt(document.getElementById("place_add_height").value);
var count = parseInt(document.getElementById("place_add_count").value);
var direction = document.getElementById("place_add_direction").value;
draw_places(gen_row(clickpos.x,clickpos.y, width, height, direction, count));
edit_layer.selectAll("circle").remove();
clicked = false;
tip_add_places.hide();
clear_guides();
}
document.getElementById("place_add_rows").addEventListener("click", add_places);
return px;
}
......@@ -21,6 +21,7 @@ package fi.codecrew.moya;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.Principal;
import java.nio.charset.Charset;
import javax.ejb.EJB;
import javax.faces.application.ProjectStage;
......@@ -31,9 +32,11 @@ import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
......@@ -47,6 +50,7 @@ import fi.codecrew.moya.rest.RestApplicationEntrypoint;
/**
* Servlet Filter implementation class HostnameFilter
*/
@WebFilter(filterName = "hostnameFilter", displayName = "hostname and authentication filter", urlPatterns = { "/*" })
public class HostnameFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(HostnameFilter.class);
......@@ -70,6 +74,7 @@ public class HostnameFilter implements Filter {
@EJB
private SessionMgmtBeanLocal sessionmgmt;
public static final String HTTP_TRAIL_NAME = "moya_http_trail";
private static final Charset UTF8 = Charset.forName("UTF-8");
/**
* Default constructor.
......@@ -90,7 +95,6 @@ public class HostnameFilter implements Filter {
UNKNOWN, ANON, REST, USER
}
/**
* Add user information to SLF4J MDC context, so current user can be shown
* in logs.
......@@ -102,12 +106,12 @@ public class HostnameFilter implements Filter {
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null) {
String userString = userPrincipal.getName();
MDC.put("user", userString);
MDC.put("user", userString);
MDC.put("authtype", authType != null ? authType.name() : "null");
} else {
MDC.put("user", "null");
MDC.put("authtype", "null");
}
}
}
/**
......@@ -135,7 +139,9 @@ public class HostnameFilter implements Filter {
if (RestApplicationEntrypoint.REST_PATH.equals(httpRequest.getServletPath())) {
authtype = AuthType.REST;
if (!restAuth(httpRequest, response)) {
response.getWriter().write("REST authentication failed!");
response.reset();
response.getOutputStream().write("Rest auth failed! ".getBytes(UTF8));
if (response instanceof HttpServletResponse) {
HttpServletResponse httpResp = (HttpServletResponse) response;
httpResp.setStatus(HttpServletResponse.SC_FORBIDDEN);
......@@ -205,14 +211,6 @@ public class HostnameFilter implements Filter {
{
HttpServletResponse httpResp = ((HttpServletResponse) response);
httpResp.setStatus(HttpServletResponse.SC_FORBIDDEN);
try {
PrintWriter w = httpResp.getWriter();
w.write("Rest auth failed! ");
w.flush();
} catch (IOException e) {
logger.info("Error writing error message from restauth failure to ostream", e);
}
}
} finally {
......@@ -223,9 +221,9 @@ public class HostnameFilter implements Filter {
protected void parseHostname(HttpServletRequest httpRequest)
{
// logger.info("Path info {}", httpRequest.getPathInfo()); // null
// logger.info("Path info {}", httpRequest.getPathInfo()); // null
// logger.info("querystring {}", httpRequest.getQueryString()); // ln=primefaces&amp;v=4.0
// logger.info("ctxpath {}", httpRequest.getContextPath()); // /MoyaWeb
// logger.info("ctxpath {}", httpRequest.getContextPath()); // /MoyaWeb
// logger.info("pathTranslated {}", httpRequest.getPathTranslated()); // null
// logger.info("requestUri {}", httpRequest.getRequestURI()); // /MoyaWeb/javax.faces.resource/jquery/jquery.js.jsf
// logger.info("URL {}", httpRequest.getRequestURL().toString()); // http://localhost:8080/MoyaWeb/javax.faces.resource/jquery/jquery.js.jsf
......
package fi.codecrew.moya.rest;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@WebFilter(filterName = "jsonpFilter", displayName = "Rest JsonP filter", urlPatterns = { RestApplicationEntrypoint.REST_PATH + "/*" })
public class JsonpRestFilter implements Filter {
private static final String JSONP_PARAMETER = "jsonp";
private static final Logger logger = LoggerFactory.getLogger(JsonpRestFilter.class);
private static final Charset UTF8 = Charset.forName("UTF-8");
@Override
public void init(FilterConfig filterConfig) throws ServletException {
logger.info("Jsonp filter started");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpResp = (HttpServletResponse) response;
HttpServletRequest httpRequest = (HttpServletRequest) request;
httpResp.setHeader("Access-Control-Allow-Origin", "*");
String jsonpFunc = request.getParameter(JSONP_PARAMETER);
boolean useJsonp = "GET".equals(httpRequest.getMethod()) && jsonpFunc != null && !jsonpFunc.isEmpty();
ServletOutputStream ostream = response.getOutputStream();
if (useJsonp) {
//.... Älä käytä response.getWriter():ä... Räjähtää.
//..... Älä käytä ostream.print():ä... Tulee writellä kirjoitettujen bytejen jälkeen...
ostream.write(jsonpFunc.getBytes(UTF8));
ostream.write("(".getBytes(UTF8));
}
chain.doFilter(request, response);
if (HttpServletResponse.SC_FORBIDDEN != httpResp.getStatus() && useJsonp) {
ostream.write(");".getBytes(UTF8));
}
}
@Override
public void destroy() {
logger.info("Jsonp filter destroyed");
}
}
package fi.codecrew.moya.rest.placemap.v1;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.beans.PlaceBeanLocal;
import fi.codecrew.moya.model.EventMap;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.rest.pojo.placemap.PlacemapMapRootPojo;
import fi.codecrew.moya.rest.pojo.placemap.SimplePlacePojo;
import fi.codecrew.moya.rest.pojo.placemap.SimplePlacelistRoot;
@RequestScoped
@Path("/placemap/v1")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON + "; charset=UTF-8" })
public class PlacemapRestViewV1 {
@EJB
private PlaceBeanLocal placebean;
private static final Logger logger = LoggerFactory.getLogger(PlacemapRestViewV1.class);
// @GET
// @Path("/maps")
// public PlacemapMapRootPojo getMaps()
// {
// List<EventMap> maps = placebean.getMaps();
// placebean.getAllMapProducts();
// new PlacemapMapRootPojo();
// }
@POST
@Path("/place/{id}/reserve")
public void reservePlace() {
logger .warn("Reserving not yet implemented");
}
@GET
@Path("/{id}")
public PlacemapMapRootPojo getMap(@PathParam("id") Integer id) {
PlacemapMapRootPojo ret = new PlacemapMapRootPojo();
EventMap map = placebean.findMap(id);
ret.setMap(map);
ret.setRawProducts(placebean.getMapProducts(map));
return ret;
}
@GET
@Path("{id}/places")
public SimplePlacelistRoot getPlaces(@PathParam("id") Integer mapId)
{
EventMap map = placebean.findMap(mapId);
return SimplePlacelistRoot.wrap(map.getPlaces(), null);
}
}
package fi.codecrew.moya.rest.pojo;
import java.math.BigDecimal;
import javax.xml.bind.annotation.XmlElement;
import fi.codecrew.moya.model.Product;
public class ProductRestPojo {
private Product prod;
public ProductRestPojo() {
}
public ProductRestPojo(Product p) {
this.prod = p;
}
@XmlElement(name = "id")
public Integer getId() {
return prod.getId();
}
@XmlElement(name = "name")
public String getName() {
return prod.getName();
}
@XmlElement(name = "price")
public String getPrice() {
return prod.getPrice().setScale(2, BigDecimal.ROUND_HALF_UP).toString();
}
@XmlElement(name = "description")
public String getDescription() {
return prod.getDescription();
}
}
package fi.codecrew.moya.rest.pojo.placemap;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.model.EventMap;
import fi.codecrew.moya.model.Product;
import fi.codecrew.moya.rest.pojo.ProductRestPojo;
@XmlRootElement
public class PlacemapMapRootPojo {
private MapPojo map;
private List<ProductRestPojo> products;
private static final Logger logger = LoggerFactory.getLogger(PlacemapMapRootPojo.class);
public PlacemapMapRootPojo() {
}
public static class MapPojo {
private EventMap map;
public MapPojo() {
}
public MapPojo(EventMap map2) {
this.map = map2;
}
@XmlElement(name = "name")
public String getName() {
return map.getName();
}
@XmlElement(name = "id")
public Integer getId() {
return map.getId();
}
@XmlElement(name = "width")
public Integer getWidth() {
return map.getWidth();
}
@XmlElement(name = "height")
public Integer getHeight() {
return map.getHeight();
}
}
public List<ProductRestPojo> getProducts() {
return products;
}
public void setProducts(List<ProductRestPojo> products) {
this.products = products;
}
public void setMap(EventMap map2) {
logger.info("Adding map {} to placemapMap", map2);
map = new MapPojo(map2);
}
public void setRawProducts(List<Product> mapProducts) {
products = new ArrayList<>();
for (Product p : mapProducts) {
logger.warn("Adding product {}", p);
products.add(new ProductRestPojo(p));
}
}
public MapPojo getMap() {
return map;
}
public void setMap(MapPojo map) {
this.map = map;
}
}
package fi.codecrew.moya.rest.pojo.placemap;
import javax.xml.bind.annotation.XmlElement;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.Place;
public class SimplePlacePojo {
private Place place;
private EventUser user;
public SimplePlacePojo(Place place, EventUser user) {
super();
this.place = place;
this.user = user;
}
public SimplePlacePojo() {
super();
}
@XmlElement(name = "id")
public Integer getId() {
return place.getId();
}
@XmlElement(name = "name")
public String getName() {
return place.getName();
}
@XmlElement(name = "state")
public String getState() {
String ret = null;
switch (place.getState(user))
{
case DISABLED:
ret = "D";
break;
case FREE:
ret = "F";
break;
case LOCKED:
ret = "L";
break;
case MY_PLACE:
ret = "P";
break;
case RESERVED:
ret = "R";
break;
case TEMP_RESERVED_FORME:
ret = "T";
break;
default:
break;
}
return ret;
}
@XmlElement(name = "x")
public Integer getX() {
return place.getMapX();
}
@XmlElement(name = "y")
public Integer getY() {
return place.getMapY();
}
@XmlElement(name = "w")
public Integer getWidth() {
return place.getWidth();
}
@XmlElement(name = "h")
public Integer getHeight() {
return place.getHeight();
}
}
package fi.codecrew.moya.rest.pojo.placemap;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.Place;
@XmlRootElement
public class SimplePlacelistRoot {
private List<SimplePlacePojo> places;
public List<SimplePlacePojo> getPlaces() {
return places;
}
public void setPlaces(List<SimplePlacePojo> places) {
this.places = places;
}
public static SimplePlacelistRoot wrap(List<Place> places, EventUser user)
{
SimplePlacelistRoot ret = new SimplePlacelistRoot();
ArrayList<SimplePlacePojo> placeList = new ArrayList<SimplePlacePojo>();
ret.setPlaces(placeList);
for (Place p : places) {
placeList.add(new SimplePlacePojo(p, user));
}
return ret;
}
}
......@@ -60,10 +60,9 @@ import fi.codecrew.moya.model.Place;
* @author tuukka
*/
@WebServlet("/PlaceMap")
public class PlaceMap extends HttpServlet {
public class PlaceMapServlet extends HttpServlet {
private static final Logger logger = LoggerFactory
.getLogger(PlaceMap.class);
private static final Logger logger = LoggerFactory.getLogger(PlaceMapServlet.class);
private static final long serialVersionUID = 8769688627918936258L;
@EJB
......
package fi.codecrew.moya.web.cdiview.map;
import java.util.Map;
import javax.ejb.EJB;
import javax.enterprise.context.ConversationScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.beans.PlaceBeanLocal;
import fi.codecrew.moya.model.EventMap;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.web.cdiview.GenericCDIView;
@Named
@ConversationScoped
public class AjaxMapView extends GenericCDIView {
@Inject
private PlaceView placeview;
private static final Logger logger = LoggerFactory.getLogger(AjaxMapView.class);;
private String testVal = "Testval1";
@EJB
private EventBeanLocal eventbean;
@EJB
private PlaceBeanLocal placebean;
private EventMap map;
private Place place;
public void initMap() {
LanEvent e = eventbean.getCurrentEvent();
setMap(e.getEventMaps().get(0));
}
public void placeClicked()
{
FacesContext context = FacesContext.getCurrentInstance();
Map<String, String> vmap = context.getExternalContext().getRequestParameterMap();
logger.info("placeid {}", vmap.get("pl aceId"));
int placeId = Integer.parseInt(vmap.get("placeId"));
place = placebean.find(placeId);
logger.info("Found place {} with placeid {}", place, placeId);
}
public String getTestVal() {
return testVal;
}
public void setTestVal(String testVal) {
this.testVal = testVal;
}
public EventMap getMap() {
return map;
}
public void setMap(EventMap map) {
this.map = map;
}
public Place getPlace() {
return place;
}
public void setPlace(Place place) {
this.place = place;
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!