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 1177 additions and 143 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,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;
}
......@@ -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!