~ refactor web
Signed-off-by: Johannes Theiner <j.theiner@live.de> #SPM-32: add work 2h development
This commit is contained in:
parent
5d898338ee
commit
c19bb535f4
|
@ -12,7 +12,7 @@ import java.io.IOException;
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
* @param <T> Type the chosen analysis returns as a result
|
* @param <T> Type the chosen analysis returns as a result
|
||||||
*/
|
*/
|
||||||
public interface Analysis<T> {
|
public interface Analysis<T> {
|
||||||
|
|
|
@ -5,7 +5,7 @@ package de.hsel.spm.baudas.analysis;
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
**/
|
**/
|
||||||
class Attribute {
|
class Attribute {
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import java.util.Map;
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.4
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public class Cluster implements Analysis<Map<Integer, Map<String, String>>> {
|
public class Cluster implements Analysis<Map<Integer, Map<String, String>>> {
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,14 @@ import java.util.stream.Stream;
|
||||||
*
|
*
|
||||||
* @author Karsten Eden
|
* @author Karsten Eden
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.2
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public class TopFlopArticle implements Analysis<Map<String, Integer>> {
|
public class SalesNumbers implements Analysis<Map<String, Integer>> {
|
||||||
|
|
||||||
private Instances instances;
|
private Instances instances;
|
||||||
private Map<String, Integer> results;
|
private Map<String, Integer> results;
|
||||||
|
|
||||||
public TopFlopArticle(File file) {
|
public SalesNumbers(File file) {
|
||||||
|
|
||||||
instances = load(file);
|
instances = load(file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import java.util.Map;
|
||||||
* The shopping-cart analysis.
|
* The shopping-cart analysis.
|
||||||
*
|
*
|
||||||
* @author Julian Hinxlage
|
* @author Julian Hinxlage
|
||||||
* @version 0.4
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public class ShoppingCart implements Analysis<Map<List<String>, List<String>>> {
|
public class ShoppingCart implements Analysis<Map<List<String>, List<String>>> {
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import java.util.Map;
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
**/
|
**/
|
||||||
public class ShoppingTimes implements Analysis<Map<Map.Entry<String, String>, Integer>> {
|
public class ShoppingTimes implements Analysis<Map<Map.Entry<String, String>, Integer>> {
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import java.util.Map;
|
||||||
*
|
*
|
||||||
* @author Julian Hinxlage
|
* @author Julian Hinxlage
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
**/
|
**/
|
||||||
public class WeekOverview implements Analysis<Map<String, Map.Entry<Double, Integer>>> {
|
public class WeekOverview implements Analysis<Map<String, Map.Entry<Double, Integer>>> {
|
||||||
|
|
||||||
|
@ -45,14 +45,13 @@ public class WeekOverview implements Analysis<Map<String, Map.Entry<Double, Inte
|
||||||
|
|
||||||
if (!result.containsKey(day)) {
|
if (!result.containsKey(day)) {
|
||||||
result.put(day, new AbstractMap.SimpleEntry<>(0.0, 0));
|
result.put(day, new AbstractMap.SimpleEntry<>(0.0, 0));
|
||||||
} else {
|
|
||||||
result.put(day,
|
|
||||||
new AbstractMap.SimpleEntry<>(
|
|
||||||
result.get(day).getKey() + amount,
|
|
||||||
result.get(day).getValue() + 1
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
result.put(day,
|
||||||
|
new AbstractMap.SimpleEntry<>(
|
||||||
|
result.get(day).getKey() + amount,
|
||||||
|
result.get(day).getValue() + 1
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
package de.hsel.spm.baudas.web;
|
|
||||||
|
|
||||||
import javax.servlet.Filter;
|
|
||||||
import javax.servlet.FilterChain;
|
|
||||||
import javax.servlet.FilterConfig;
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
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 javax.servlet.http.HttpSession;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter implementation class AuthenticationFilter.
|
|
||||||
*
|
|
||||||
* @author Edgar Schkrob
|
|
||||||
*/
|
|
||||||
|
|
||||||
@WebFilter(urlPatterns = {"/*"})
|
|
||||||
public class AuthenticationFilter implements Filter {
|
|
||||||
private ServletContext context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by the web container to indicate to a filter that it is being placed into service. This filter manages the authentication.
|
|
||||||
*
|
|
||||||
* @param filterConfig This parameter provides access to everything the code needs to work.
|
|
||||||
* @throws ServletException Defines a general exception a servlet can throw when it encounters difficulty.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void init(FilterConfig filterConfig) throws ServletException {
|
|
||||||
this.context = filterConfig.getServletContext();
|
|
||||||
this.context.log("AuthenticationFilter initialized");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.
|
|
||||||
*
|
|
||||||
* @param request This parameter provides access to everything the code needs to work.
|
|
||||||
* @param response This parameter provides access to everything the code needs to issue a response.
|
|
||||||
* @param chain This parameter allows passing request along the chain of potential handlers until one of them handles the request.
|
|
||||||
* @throws ServletException Defines a general exception a servlet can throw when it encounters difficulty.
|
|
||||||
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
|
||||||
HttpServletRequest req = (HttpServletRequest) request;
|
|
||||||
HttpServletResponse res = (HttpServletResponse) response;
|
|
||||||
HttpSession session = req.getSession(false);
|
|
||||||
String url = req.getRequestURI();
|
|
||||||
if (url.contains("login") || url.contains("logo") || url.contains("js/")) {
|
|
||||||
chain.doFilter(request, response);
|
|
||||||
} else if (session == null || !((boolean) session.getAttribute("authentication"))) { //checking whether the session exists and if authentication succeed
|
|
||||||
this.context.log("Unauthorized access request");
|
|
||||||
res.sendRedirect(req.getContextPath() + "/login.html");
|
|
||||||
} else {
|
|
||||||
chain.doFilter(request, response);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
//close any resources here
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
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 javax.servlet.http.HttpSession;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handles all authorisation filtering.
|
||||||
|
*
|
||||||
|
* @author Edgar Schkrob
|
||||||
|
* @version 0.1
|
||||||
|
* @since 0.4
|
||||||
|
*/
|
||||||
|
|
||||||
|
@WebFilter(urlPatterns = {"/*"})
|
||||||
|
public class AuthorizationFilter implements Filter {
|
||||||
|
|
||||||
|
private ServletContext context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialize this filter.
|
||||||
|
*
|
||||||
|
* @param filterConfig configuration
|
||||||
|
* @throws ServletException failed to initialize filter
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void init(@NotNull FilterConfig filterConfig) throws ServletException {
|
||||||
|
this.context = filterConfig.getServletContext();
|
||||||
|
this.context.log("AuthorizationFilter initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* filter all unauthorized requests.
|
||||||
|
*
|
||||||
|
* @param request request object
|
||||||
|
* @param response response object
|
||||||
|
* @param chain filter chain
|
||||||
|
* @throws ServletException something failed inside the filter chain
|
||||||
|
* @throws IOException failed to redirect
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doFilter(@NotNull ServletRequest request, @NotNull ServletResponse response, @NotNull FilterChain chain) throws IOException, ServletException {
|
||||||
|
HttpServletRequest req = (HttpServletRequest) request;
|
||||||
|
HttpServletResponse res = (HttpServletResponse) response;
|
||||||
|
HttpSession session = req.getSession(false);
|
||||||
|
String url = req.getRequestURI();
|
||||||
|
if (url.contains("login") || url.contains("logo") || url.contains("js/")) {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
} else if (session == null || !((boolean) session.getAttribute("authentication"))) { //checking whether the session exists and if authentication succeed
|
||||||
|
this.context.log("Unauthorized access request");
|
||||||
|
res.sendRedirect(req.getContextPath() + "/login.jsp");
|
||||||
|
} else {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,9 +22,9 @@ import java.util.concurrent.ConcurrentMap;
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
**/
|
**/
|
||||||
public class Data {
|
public class DatasetManagement {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static ConcurrentMap<String, List<SavedFile>> files = new ConcurrentHashMap<>();
|
private static ConcurrentMap<String, List<SavedFile>> files = new ConcurrentHashMap<>();
|
||||||
|
@ -46,7 +46,7 @@ public class Data {
|
||||||
if (files.get(session).size() >= 5) {
|
if (files.get(session).size() >= 5) {
|
||||||
SavedFile file = files.get(session).iterator().next();
|
SavedFile file = files.get(session).iterator().next();
|
||||||
if (!get(file.getUuid()).delete()) {
|
if (!get(file.getUuid()).delete()) {
|
||||||
System.err.println("failed to delete file..." + file);
|
System.err.println("failed to delete file " + file);
|
||||||
}
|
}
|
||||||
files.get(session).remove(file);
|
files.get(session).remove(file);
|
||||||
}
|
}
|
||||||
|
@ -59,10 +59,12 @@ public class Data {
|
||||||
*
|
*
|
||||||
* @param session session id
|
* @param session session id
|
||||||
*/
|
*/
|
||||||
static void delete(String session) {
|
static void delete(@NotNull String session) {
|
||||||
|
if (!files.containsKey(session)) return;
|
||||||
|
|
||||||
for (SavedFile file : files.get(session)) {
|
for (SavedFile file : files.get(session)) {
|
||||||
if (!get(file.getUuid()).delete())
|
if (!get(file.getUuid()).delete())
|
||||||
System.err.println("failed to delete file..." + file);
|
System.err.println("failed to delete file " + file);
|
||||||
}
|
}
|
||||||
files.remove(session);
|
files.remove(session);
|
||||||
|
|
|
@ -12,18 +12,26 @@ import java.io.PrintWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list all currently available files.
|
* list all currently available datasets.
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@WebServlet("/files")
|
@WebServlet("/datasets")
|
||||||
public class Files extends HttpServlet {
|
public class DatasetsServlet extends HttpServlet {
|
||||||
|
|
||||||
private static final long serialVersionUID = 148451844848L;
|
private static final long serialVersionUID = 148451844848L;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns all available datasets for session.
|
||||||
|
*
|
||||||
|
* @param req request object
|
||||||
|
* @param resp response object
|
||||||
|
* @throws IOException failed to initialize print writer
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp)
|
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
@ -31,6 +39,6 @@ public class Files extends HttpServlet {
|
||||||
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
PrintWriter out = resp.getWriter();
|
PrintWriter out = resp.getWriter();
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
out.print(gson.toJson(Data.getFiles().get(req.getSession().getId())));
|
out.print(gson.toJson(DatasetManagement.getFiles().get(req.getSession().getId())));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,6 +8,7 @@ import lombok.Getter;
|
||||||
*
|
*
|
||||||
* @author Julian Hinxlage
|
* @author Julian Hinxlage
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package de.hsel.spm.baudas.web;
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
@ -11,9 +13,11 @@ import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Servlet implementation class LoginServlet.
|
* authenticates users.
|
||||||
*
|
*
|
||||||
* @author Edgar Schkrob
|
* @author Edgar Schkrob
|
||||||
|
* @version 0.1
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@WebServlet("/login")
|
@WebServlet("/login")
|
||||||
|
@ -22,25 +26,23 @@ public class LoginServlet extends HttpServlet {
|
||||||
private final String password = "SPM2019SS";
|
private final String password = "SPM2019SS";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a Servlet that manages the Login and creates Sessions.
|
* reads from HTTP POST parameter 'password' and compares it.
|
||||||
*
|
*
|
||||||
* @param request This parameter provides access to everything the code needs to work.
|
* @param request request object
|
||||||
* @param response This parameter provides access to everything the code needs to issue a response.
|
* @param response response object
|
||||||
* @throws ServletException Defines a general exception a servlet can throw when it encounters difficulty.
|
* @throws IOException failed to initialize print writer
|
||||||
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
|
|
||||||
*/
|
*/
|
||||||
|
protected void doPost(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws ServletException, IOException {
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
String password = request.getParameter("password");
|
String password = request.getParameter("password");
|
||||||
if (this.password.equals(password)) {
|
if (this.password.equals(password)) {
|
||||||
HttpSession newSession = request.getSession(true);
|
HttpSession newSession = request.getSession(true);
|
||||||
newSession.setAttribute("authentication", true);
|
newSession.setAttribute("authentication", true);
|
||||||
newSession.setMaxInactiveInterval(5 * 60 * 60); //setting session to expiry in 5 hours
|
newSession.setMaxInactiveInterval(5 * 60 * 60); //setting session to expiry in 5 hours
|
||||||
response.sendRedirect("index.jsp");
|
response.sendRedirect("/");
|
||||||
} else {
|
} else {
|
||||||
RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html");
|
RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.jsp");
|
||||||
PrintWriter out = response.getWriter();
|
PrintWriter out = response.getWriter();
|
||||||
out.println("<font color=red>Das eingegebene Passwort ist falsch.</font>");
|
out.println("<font color='red' class='align-center'>Das eingegebene Passwort ist falsch.</font>");
|
||||||
rd.include(request, response);
|
rd.include(request, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package de.hsel.spm.baudas.web;
|
package de.hsel.spm.baudas.web;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -8,26 +10,27 @@ import javax.servlet.http.HttpSession;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Servlet implementation class LogoutServlet.
|
* logs out user if they request this.
|
||||||
*
|
*
|
||||||
* @author Edgar Schkrob
|
* @author Edgar Schkrob
|
||||||
|
* @version 0.1
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@WebServlet("/logout")
|
@WebServlet("/logout")
|
||||||
public class LogoutServlet extends HttpServlet {
|
public class LogoutServlet extends HttpServlet {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a Servlet that manages the Logout and deletes Sessions.
|
* if this servlet is request logout the user.
|
||||||
*
|
*
|
||||||
* @param request This parameter provides access to everything the code needs to work.
|
* @param request request object
|
||||||
* @param response This parameter provides access to everything the code needs to issue a response.
|
* @param response response object
|
||||||
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
|
* @throws IOException failed to initialize print writer
|
||||||
*/
|
*/
|
||||||
|
protected void doGet(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws IOException {
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
|
||||||
HttpSession session = request.getSession();
|
HttpSession session = request.getSession();
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
Data.delete(session.getId());
|
DatasetManagement.delete(session.getId());
|
||||||
session.invalidate();
|
session.invalidate();
|
||||||
}
|
}
|
||||||
response.sendRedirect(request.getContextPath() + "/");
|
response.sendRedirect(request.getContextPath() + "/");
|
||||||
|
|
|
@ -12,7 +12,7 @@ import java.util.UUID;
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
package de.hsel.spm.baudas.web;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import de.hsel.spm.baudas.analysis.ShoppingCart;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes data to readable format for table
|
|
||||||
*
|
|
||||||
* @author Karsten Eden
|
|
||||||
* @version 0.1
|
|
||||||
* @since 0.1
|
|
||||||
*/
|
|
||||||
@WebServlet("/shopping_cart")
|
|
||||||
public class ShoppingCartDiagram extends HttpServlet {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 5026732432605473505L;
|
|
||||||
|
|
||||||
private static List<Map.Entry<String, String>> cache;
|
|
||||||
|
|
||||||
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
|
||||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
|
||||||
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
|
||||||
resp.setContentType("application/json");
|
|
||||||
PrintWriter out = resp.getWriter();
|
|
||||||
Gson gson = new Gson();
|
|
||||||
|
|
||||||
if(cache != null) {
|
|
||||||
out.println(gson.toJson(cache));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Map.Entry<String, String>> result = new ArrayList<>();
|
|
||||||
|
|
||||||
if (req.getParameter("id") == null) {
|
|
||||||
out.print(gson.toJson(result));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID uuid = UUID.fromString(req.getParameter("id"));
|
|
||||||
File file = Data.get(uuid);
|
|
||||||
|
|
||||||
ShoppingCart cart = new ShoppingCart(file);
|
|
||||||
Map<List<String>, List<String>> map = cart.getResult();
|
|
||||||
|
|
||||||
List<String> col1 = new ArrayList<>();
|
|
||||||
List<String> col2 = new ArrayList<>();
|
|
||||||
|
|
||||||
for(Map.Entry<List<String>, List<String>> entry : map.entrySet()){
|
|
||||||
col1.add(String.join(", ", entry.getKey()));
|
|
||||||
col2.add(String.join(", ", entry.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < col1.size(); i++ ){
|
|
||||||
result.add(new AbstractMap.SimpleEntry<>(col1.get(i), col2.get(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
out.print(gson.toJson(result));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -28,7 +28,7 @@ import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
@WebServlet("/upload")
|
@WebServlet("/upload")
|
||||||
@MultipartConfig
|
@MultipartConfig
|
||||||
public class Upload extends HttpServlet {
|
public class UploadServlet extends HttpServlet {
|
||||||
|
|
||||||
private static final long serialVersionUID = 14144111845151L;
|
private static final long serialVersionUID = 14144111845151L;
|
||||||
|
|
||||||
|
@ -48,6 +48,13 @@ public class Upload extends HttpServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validates file and saves it.
|
||||||
|
*
|
||||||
|
* @param req request object
|
||||||
|
* @param resp response object
|
||||||
|
* @throws IOException failed to initialize print writer
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(@NotNull HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(@NotNull HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
@ -89,7 +96,7 @@ public class Upload extends HttpServlet {
|
||||||
inputStream = filePart.getInputStream();
|
inputStream = filePart.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
Path path = Data.add(fileName, req.getSession().getId());
|
Path path = DatasetManagement.add(fileName, req.getSession().getId());
|
||||||
if (!Files.exists(path)) {
|
if (!Files.exists(path)) {
|
||||||
Files.createFile(path);
|
Files.createFile(path);
|
||||||
}
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
package de.hsel.spm.baudas.web;
|
package de.hsel.spm.baudas.web.depiction;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import de.hsel.spm.baudas.analysis.Cluster;
|
import de.hsel.spm.baudas.analysis.Cluster;
|
||||||
|
import de.hsel.spm.baudas.web.DatasetManagement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
@ -11,45 +12,45 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.util.HashMap;
|
||||||
import java.util.*;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* changes data from cluster analysis into a readable format
|
* changes data from cluster analysis into a readable format.
|
||||||
*
|
*
|
||||||
* @author Julian Hinxlage
|
* @author Julian Hinxlage
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
**/
|
**/
|
||||||
@WebServlet("/clusters")
|
@WebServlet("/clusters")
|
||||||
public class ClusterDiagram extends HttpServlet {
|
public class ClusterTable extends HttpServlet implements Depiction {
|
||||||
|
|
||||||
private static Map<Integer, Map<String, String>> cache;
|
private static Map<UUID, Map> cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns formatted analysis result to HTTP GET request from supplied id.
|
||||||
|
*
|
||||||
|
* @param req request object
|
||||||
|
* @param resp response object
|
||||||
|
* @throws IOException failed to initialize print writer
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
||||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
UUID uuid = setup(req, resp, cache);
|
||||||
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
if (uuid == null) return;
|
||||||
resp.setContentType("application/json");
|
|
||||||
PrintWriter out = resp.getWriter();
|
|
||||||
Gson gson = new Gson();
|
|
||||||
|
|
||||||
if(cache != null) {
|
|
||||||
out.println(gson.toJson(cache));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<Integer, Map<String, String>> result = new HashMap<>();
|
Map<Integer, Map<String, String>> result = new HashMap<>();
|
||||||
|
File file = DatasetManagement.get(uuid);
|
||||||
if (req.getParameter("id") == null) {
|
|
||||||
out.print(gson.toJson(result));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
UUID uuid = UUID.fromString(req.getParameter("id"));
|
|
||||||
File file = Data.get(uuid);
|
|
||||||
|
|
||||||
Cluster cluster = new Cluster(file);
|
Cluster cluster = new Cluster(file);
|
||||||
result = cluster.getResult();
|
result = cluster.getResult();
|
||||||
|
|
||||||
|
PrintWriter out = resp.getWriter();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
|
cache.put(uuid, result);
|
||||||
out.print(gson.toJson(result));
|
out.print(gson.toJson(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package de.hsel.spm.baudas.web.depiction;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle all common methods for depictions.
|
||||||
|
*
|
||||||
|
* @author Johannes Theiner
|
||||||
|
* @version 0.1
|
||||||
|
* @since 1.0
|
||||||
|
**/
|
||||||
|
interface Depiction {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set all default values and handle caching.
|
||||||
|
*
|
||||||
|
* @param request request object
|
||||||
|
* @param response response object
|
||||||
|
* @param cache cached results
|
||||||
|
* @return validated uuid
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default UUID setup(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Map<UUID, Map> cache) {
|
||||||
|
try {
|
||||||
|
request.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
response.setContentType("application/json");
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
|
||||||
|
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
|
UUID uuid = validateAndConvert(request.getParameter("id"));
|
||||||
|
if (uuid == null) return null;
|
||||||
|
|
||||||
|
if (cache.containsKey(uuid)) {
|
||||||
|
out.println(gson.toJson(cache.get(uuid)));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return uuid;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validates and converts uuid.
|
||||||
|
*
|
||||||
|
* @param id potential uuid
|
||||||
|
* @return UUID object
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default UUID validateAndConvert(String id) {
|
||||||
|
boolean match = Pattern.matches("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", id);
|
||||||
|
if (id == null || !match) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UUID.fromString(id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
package de.hsel.spm.baudas.web;
|
package de.hsel.spm.baudas.web.depiction;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import de.hsel.spm.baudas.analysis.TopFlopArticle;
|
import de.hsel.spm.baudas.analysis.SalesNumbers;
|
||||||
|
import de.hsel.spm.baudas.web.DatasetManagement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
@ -11,13 +12,11 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* top/flop articles list diagram.
|
* top/flop articles list diagram.
|
||||||
|
@ -27,38 +26,28 @@ import java.util.regex.Pattern;
|
||||||
* @since 0.1
|
* @since 0.1
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@WebServlet("/top_flop")
|
@WebServlet("/sales")
|
||||||
public class TopFlopArticleDiagram extends HttpServlet {
|
public class SalesNumberChart extends HttpServlet implements Depiction {
|
||||||
|
|
||||||
private static Map<UUID, Map> cache = new HashMap<>();
|
private static Map<UUID, Map> cache = new HashMap<>();
|
||||||
|
|
||||||
private static final long serialVersionUID = 6567531464214L;
|
private static final long serialVersionUID = 6567531464214L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns formatted analysis result to HTTP GET request from supplied id.
|
||||||
|
*
|
||||||
|
* @param req request object
|
||||||
|
* @param resp response object
|
||||||
|
* @throws IOException failed to initialize print writer
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
||||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
UUID uuid = setup(req, resp, cache);
|
||||||
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
if (uuid == null) return;
|
||||||
resp.setContentType("application/json");
|
|
||||||
PrintWriter out = resp.getWriter();
|
|
||||||
|
|
||||||
Gson gson = new Gson();
|
File file = DatasetManagement.get(uuid);
|
||||||
|
|
||||||
String id = req.getParameter("id");
|
SalesNumbers articles = new SalesNumbers(file);
|
||||||
boolean match = Pattern.matches("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", id);
|
|
||||||
if (id == null || !match) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID uuid = UUID.fromString(id);
|
|
||||||
|
|
||||||
if (cache.containsKey(uuid)) {
|
|
||||||
out.println(gson.toJson(cache.get(uuid)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File file = Data.get(uuid);
|
|
||||||
|
|
||||||
TopFlopArticle articles = new TopFlopArticle(file);
|
|
||||||
Map<String, Integer> map = articles.getResult();
|
Map<String, Integer> map = articles.getResult();
|
||||||
|
|
||||||
Map<String, List<String>> result = new HashMap<>();
|
Map<String, List<String>> result = new HashMap<>();
|
||||||
|
@ -74,6 +63,8 @@ public class TopFlopArticleDiagram extends HttpServlet {
|
||||||
result.put("labels", labels);
|
result.put("labels", labels);
|
||||||
result.put("data", data);
|
result.put("data", data);
|
||||||
|
|
||||||
|
PrintWriter out = resp.getWriter();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
cache.put(uuid, result);
|
cache.put(uuid, result);
|
||||||
out.print(gson.toJson(result));
|
out.print(gson.toJson(result));
|
|
@ -0,0 +1,80 @@
|
||||||
|
package de.hsel.spm.baudas.web.depiction;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import de.hsel.spm.baudas.analysis.ShoppingCart;
|
||||||
|
import de.hsel.spm.baudas.web.DatasetManagement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes data to readable format for table.
|
||||||
|
*
|
||||||
|
* @author Karsten Eden
|
||||||
|
* @version 0.1
|
||||||
|
* @since 0.1
|
||||||
|
*/
|
||||||
|
@WebServlet("/shopping_cart")
|
||||||
|
public class ShoppingCartTable extends HttpServlet implements Depiction {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5026732432605473505L;
|
||||||
|
|
||||||
|
private static Map<UUID, Map> cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns formatted analysis result to HTTP GET request from supplied id.
|
||||||
|
*
|
||||||
|
* @param req request object
|
||||||
|
* @param resp response object
|
||||||
|
* @throws IOException failed to initialize print writer
|
||||||
|
*/
|
||||||
|
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
||||||
|
UUID uuid = setup(req, resp, cache);
|
||||||
|
if (uuid == null) return;
|
||||||
|
|
||||||
|
|
||||||
|
List<Map.Entry<String, String>> tmp = new ArrayList<>();
|
||||||
|
|
||||||
|
File file = DatasetManagement.get(uuid);
|
||||||
|
|
||||||
|
ShoppingCart cart = new ShoppingCart(file);
|
||||||
|
Map<List<String>, List<String>> map = cart.getResult();
|
||||||
|
|
||||||
|
List<String> premises = new ArrayList<>();
|
||||||
|
List<String> consequences = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Map.Entry<List<String>, List<String>> entry : map.entrySet()) {
|
||||||
|
premises.add(String.join(", ", entry.getKey()));
|
||||||
|
consequences.add(String.join(", ", entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < premises.size(); i++) {
|
||||||
|
tmp.add(new AbstractMap.SimpleEntry<>(premises.get(i), consequences.get(i)));
|
||||||
|
}
|
||||||
|
Map<Integer, Map.Entry<String, String>> result = new HashMap<>();
|
||||||
|
int i = 0;
|
||||||
|
for (Map.Entry<String, String> entry : tmp) {
|
||||||
|
result.put(i, entry);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.put(uuid, result);
|
||||||
|
|
||||||
|
PrintWriter out = resp.getWriter();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
|
out.print(gson.toJson(result));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
package de.hsel.spm.baudas.web;
|
package de.hsel.spm.baudas.web.depiction;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import de.hsel.spm.baudas.analysis.ShoppingTimes;
|
import de.hsel.spm.baudas.analysis.ShoppingTimes;
|
||||||
|
import de.hsel.spm.baudas.web.DatasetManagement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
@ -11,54 +12,51 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.util.AbstractMap;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
import java.util.regex.Pattern;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* changes data from shopping times diagram into a readable format for chart.js
|
* changes data from shopping times diagram into a readable format for chart.js
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
**/
|
**/
|
||||||
@WebServlet("/shopping_times")
|
@WebServlet("/shopping_times")
|
||||||
public class ShoppingTimesDiagram extends HttpServlet {
|
public class ShoppingTimesChart extends HttpServlet implements Depiction {
|
||||||
|
|
||||||
private static Map<UUID, Map> cache = new HashMap<>();
|
private static Map<UUID, Map> cache = new HashMap<>();
|
||||||
|
|
||||||
private static final long serialVersionUID = 6567531484L;
|
private static final long serialVersionUID = 6567531484L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns formatted analysis result to HTTP GET request from supplied id.
|
||||||
|
*
|
||||||
|
* @param req request object
|
||||||
|
* @param resp response object
|
||||||
|
* @throws IOException failed to initialize print writer
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
||||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
UUID uuid = setup(req, resp, cache);
|
||||||
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
if (uuid == null) return;
|
||||||
resp.setContentType("application/json");
|
|
||||||
PrintWriter out = resp.getWriter();
|
|
||||||
|
|
||||||
List<String> definedOrder = Arrays.asList("<10 Uhr", "10-12 Uhr", "12-14 Uhr", "14-17 Uhr", ">17 Uhr");
|
List<String> definedOrder = Arrays.asList("<10 Uhr", "10-12 Uhr", "12-14 Uhr", "14-17 Uhr", ">17 Uhr");
|
||||||
Comparator<String> comparator = Comparator.comparingInt(definedOrder::indexOf);
|
Comparator<String> comparator = Comparator.comparingInt(definedOrder::indexOf);
|
||||||
|
|
||||||
Map<String, Collection<String>> result = new HashMap<>();
|
Map<String, Collection<String>> result = new HashMap<>();
|
||||||
|
|
||||||
Gson gson = new Gson();
|
File file = DatasetManagement.get(uuid);
|
||||||
|
|
||||||
String id = req.getParameter("id");
|
|
||||||
boolean match = Pattern.matches("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", id);
|
|
||||||
if (id == null || !match) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID uuid = UUID.fromString(id);
|
|
||||||
|
|
||||||
|
|
||||||
if (cache.containsKey(uuid)) {
|
|
||||||
out.print(gson.toJson(cache.get(uuid)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
File file = Data.get(uuid);
|
|
||||||
|
|
||||||
ShoppingTimes shoppingTimes = new ShoppingTimes(file);
|
ShoppingTimes shoppingTimes = new ShoppingTimes(file);
|
||||||
Map<Map.Entry<String, String>, Integer> map = shoppingTimes.getResult();
|
Map<Map.Entry<String, String>, Integer> map = shoppingTimes.getResult();
|
||||||
|
@ -73,14 +71,17 @@ public class ShoppingTimesDiagram extends HttpServlet {
|
||||||
|
|
||||||
|
|
||||||
for (String day : days) {
|
for (String day : days) {
|
||||||
if (!result.containsKey(day))
|
if (!result.containsKey(day)) {
|
||||||
result.put(day, new ArrayList<>());
|
result.put(day, new ArrayList<>());
|
||||||
|
}
|
||||||
for (String hour : hours) {
|
for (String hour : hours) {
|
||||||
if (map.containsKey(new AbstractMap.SimpleEntry<>(day, hour))) {
|
if (map.containsKey(new AbstractMap.SimpleEntry<>(day, hour))) {
|
||||||
result.get(day).add(map.get(new AbstractMap.SimpleEntry<>(day, hour)).toString());
|
result.get(day).add(map.get(new AbstractMap.SimpleEntry<>(day, hour)).toString());
|
||||||
} else result.get(day).add("0");
|
} else result.get(day).add("0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PrintWriter out = resp.getWriter();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
cache.put(uuid, result);
|
cache.put(uuid, result);
|
||||||
out.print(gson.toJson(result));
|
out.print(gson.toJson(result));
|
|
@ -1,7 +1,8 @@
|
||||||
package de.hsel.spm.baudas.web;
|
package de.hsel.spm.baudas.web.depiction;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import de.hsel.spm.baudas.analysis.WeekOverview;
|
import de.hsel.spm.baudas.analysis.WeekOverview;
|
||||||
|
import de.hsel.spm.baudas.web.DatasetManagement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
@ -11,7 +12,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -19,50 +19,39 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* changes data from week overview into readable format for chart.js
|
* changes data from week overview into readable format for chart.js
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
* @since 0.1
|
* @since 1.0
|
||||||
**/
|
**/
|
||||||
@WebServlet("/week_overview")
|
@WebServlet("/week_overview")
|
||||||
public class WeekOverviewDiagram extends HttpServlet {
|
public class WeekOverviewChart extends HttpServlet implements Depiction {
|
||||||
|
|
||||||
private static Map<UUID, Map> cache = new HashMap<>();
|
private static Map<UUID, Map> cache = new HashMap<>();
|
||||||
|
|
||||||
private static final long serialVersionUID = 8484151844118L;
|
private static final long serialVersionUID = 8484151844118L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns formatted analysis result to HTTP GET request from supplied id.
|
||||||
|
*
|
||||||
|
* @param req request object
|
||||||
|
* @param resp response object
|
||||||
|
* @throws IOException failed to initialize print writer
|
||||||
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
protected void doGet(@NotNull HttpServletRequest req, @NotNull HttpServletResponse resp) throws IOException {
|
||||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
UUID uuid = setup(req, resp, cache);
|
||||||
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
|
||||||
resp.setContentType("application/json");
|
if (uuid == null) return;
|
||||||
PrintWriter out = resp.getWriter();
|
|
||||||
|
|
||||||
List<String> definedOrder = Arrays.asList("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag");
|
List<String> definedOrder = Arrays.asList("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag");
|
||||||
Map<String, List<String>> result = new HashMap<>();
|
Map<String, List<String>> result = new HashMap<>();
|
||||||
|
|
||||||
Gson gson = new Gson();
|
File file = DatasetManagement.get(uuid);
|
||||||
|
|
||||||
String id = req.getParameter("id");
|
|
||||||
boolean match = Pattern.matches("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", id);
|
|
||||||
|
|
||||||
|
|
||||||
if (id == null || !match) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID uuid = UUID.fromString(id);
|
|
||||||
if(cache.containsKey(uuid)) {
|
|
||||||
out.println(gson.toJson(cache.get(uuid)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File file = Data.get(uuid);
|
|
||||||
|
|
||||||
WeekOverview overview = new WeekOverview(file);
|
WeekOverview overview = new WeekOverview(file);
|
||||||
|
|
||||||
|
@ -86,6 +75,9 @@ public class WeekOverviewDiagram extends HttpServlet {
|
||||||
result.put("count", count);
|
result.put("count", count);
|
||||||
result.put("revenue", revenue);
|
result.put("revenue", revenue);
|
||||||
|
|
||||||
|
PrintWriter out = resp.getWriter();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
cache.put(uuid, result);
|
cache.put(uuid, result);
|
||||||
out.print(gson.toJson(result));
|
out.print(gson.toJson(result));
|
||||||
}
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 32 KiB |
|
@ -0,0 +1,87 @@
|
||||||
|
<!--Cards-->
|
||||||
|
<!--Analyse-Cards-->
|
||||||
|
<div id="analysis" class="row container black-text">
|
||||||
|
<!--Übersicht-->
|
||||||
|
<div class="col s12 m12">
|
||||||
|
<div id="overview" class="card white">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Wochenübersicht</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-content">
|
||||||
|
<div>
|
||||||
|
<canvas class="black-text" id="overview_chart" width="1000" height="400"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--Einkaufszeiten-->
|
||||||
|
<div class="col s12 m12">
|
||||||
|
<div id="shopping_times" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title">Einkaufszeiten</span>
|
||||||
|
</div>
|
||||||
|
<div class="center">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<select id="day" onchange="changeDay()">
|
||||||
|
<option value="0">Montag</option>
|
||||||
|
<option value="1">Dienstag</option>
|
||||||
|
<option value="2">Mittwoch</option>
|
||||||
|
<option value="3">Donnerstag</option>
|
||||||
|
<option value="4">Freitag</option>
|
||||||
|
<option value="5">Samstag</option>
|
||||||
|
</select>
|
||||||
|
<label for="day">Wochentag</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<canvas id="shopping_times_chart" width="1000" height="400"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--Verkaufszahlen-->
|
||||||
|
<div class="col s12 m12">
|
||||||
|
<div id="top_articles" class="card white">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Verkaufszahlen</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<div>
|
||||||
|
<canvas id="sales_chart" width="1000" height="400"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--Gruppenübersicht-->
|
||||||
|
<div class="col s12 m12">
|
||||||
|
<div id="group_overview" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Gruppenübersicht</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table id="cluster_table">
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--Warenkorbanlyse-->
|
||||||
|
<div id="shopping_card_analysis" class="col s12 m12">
|
||||||
|
<div class="card white">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Warenkorbanalyse</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<table id="shopping_cart_table">
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,19 +1,11 @@
|
||||||
<!--Anfang Skriptbereich-->
|
|
||||||
|
|
||||||
<!--Script für Diagramme-->
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"
|
|
||||||
integrity="sha256-xKeoJ50pzbUGkpQxDYHD7o7hxe0LaOGeguUidbq6vis=" crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||||
<%@include file="theming.jsp"%>
|
<script src="https://cdn.jsdelivr.net/npm/google-palette@1.1.0/palette.min.js"></script>
|
||||||
|
<script>
|
||||||
|
M.AutoInit();
|
||||||
|
</script>
|
||||||
|
|
||||||
<script src="js/upload.js"></script>
|
|
||||||
<script src="js/cache.js"></script>
|
|
||||||
<script src="js/week_overview.js"></script>
|
|
||||||
<script src="js/shopping_times.js"></script>
|
|
||||||
<script src="js/top_flop.js"></script>
|
|
||||||
<script src="js/clusters.js"></script>
|
|
||||||
<script src="js/shopping_cart.js"></script>
|
|
||||||
|
|
||||||
<!--Ende Skriptbereich-->
|
<!--Ende Skriptbereich-->
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<%@ page import="java.nio.charset.StandardCharsets" %>
|
||||||
<% response.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
<% response.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
<% request.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
<% request.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|
|
@ -1,198 +1,10 @@
|
||||||
<%@ page import="java.nio.charset.StandardCharsets" %>
|
<%@ page import="java.nio.charset.StandardCharsets" %>
|
||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@include file="menu.jsp" %>
|
|
||||||
<% response.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
<% response.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
<% request.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
<% request.setCharacterEncoding(StandardCharsets.UTF_8.name()); %>
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" %>
|
||||||
|
<%@include file="menu.jsp" %>
|
||||||
|
|
||||||
<!--Cards-->
|
<%@include file="analysis.jsp"%>
|
||||||
<!--Analyse-Cards-->
|
<%@include file="marketing.jsp"%>
|
||||||
<div id="analysis" class="row container black-text">
|
|
||||||
<!--Übersicht-->
|
|
||||||
<div class="col s12 m12">
|
|
||||||
<div id="overview" class="card white">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Wochenübersicht</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-content">
|
<%@include file="theming.jsp" %>
|
||||||
<div>
|
|
||||||
<canvas class="black-text" id="overview_chart" width="1000" height="400"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Einkaufszeiten-->
|
|
||||||
<div class="col s12 m12">
|
|
||||||
<div id="shopping_times" class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title">Einkaufszeiten</span>
|
|
||||||
</div>
|
|
||||||
<div class="center">
|
|
||||||
<div class="input-field col s12">
|
|
||||||
<select id="day" onchange="changeDay()">
|
|
||||||
<option value="0">Montag</option>
|
|
||||||
<option value="1">Dienstag</option>
|
|
||||||
<option value="2">Mittwoch</option>
|
|
||||||
<option value="3">Donnerstag</option>
|
|
||||||
<option value="4">Freitag</option>
|
|
||||||
<option value="5">Samstag</option>
|
|
||||||
</select>
|
|
||||||
<label for="day">Wochentag</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<canvas id="shopping_times_chart" width="1000" height="400"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Verkaufszahlen-->
|
|
||||||
<div class="col s12 m12">
|
|
||||||
<div id="top_articles" class="card white">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Verkaufszahlen</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-content">
|
|
||||||
<div>
|
|
||||||
<canvas id="top_flop_chart" width="1000" height="400"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Gruppenübersicht-->
|
|
||||||
<div class="col s12 m12">
|
|
||||||
<div id="group_overview" class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Gruppenübersicht</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<table id="cluster_table">
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Warenkorbanlyse-->
|
|
||||||
<div id="shopping_card_analysis" class="col s12 m12">
|
|
||||||
<div class="card white">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Warenkorbanalyse</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-content">
|
|
||||||
<table id="shopping_cart_table">
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--Marketing-Cards-->
|
|
||||||
<div id="marketing" class="row container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col s12 m6">
|
|
||||||
<div id="marketing_tip_3" class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Werbung</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
Werbung dient dazu, auf bestimmte Produkte, Angebote oder den Markt im
|
|
||||||
Allgemeinen aufmerksam zu machen. Sie kann über verschiedene Wege verbreitet
|
|
||||||
werden, etwa das Internet, Zeitungsannoncen oder auch per TV/Radio.
|
|
||||||
Im Gegensatz zu Rabatten (die zeitabhängig am besten funktionieren) ist Werbung
|
|
||||||
stark von der Zielgruppe abhängig. Insbesondere in der Kombination mit anderen
|
|
||||||
Marketingmaßnahmen kann sie so ihre volle Wirkung entfalten.
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
Analysen, die für Werbung nützlich sein könnten:
|
|
||||||
Clusteranalyse, Wochenübersicht, Verkaufszahlen
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12 m6">
|
|
||||||
<div id="marketing_tip_4" class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Sortimentsveränderung</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
Gibt es eine Produktgruppe, die sich besonders gut verkauft, so sollte unter
|
|
||||||
Umständen über die Erweiterung des Sortiments innerhalb dieser Gruppe
|
|
||||||
nachgedacht werden.
|
|
||||||
Im Umkehrschluss dazu bietet sich an, schlecht verkaufte Produkte, welche keinen
|
|
||||||
hohen Gewinn abwerfen aus dem täglichen Verkaufsgeschäft wieder zu entfernen.
|
|
||||||
Dies verringert die Bildung von „Ladenhütern“ und schafft Platz für neue, sich
|
|
||||||
besser verkaufende Produkte.
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
Analysen, die bei der Sortimentswahl nützlich sein könnten:
|
|
||||||
Verkaufszahlen, Clusterübersicht
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col s12 m6">
|
|
||||||
<div id="marketing_tip_1" class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Rabatt</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
Rabatte können z.B. an Tagen angeboten werden, an denen nur wenige Kunden
|
|
||||||
erscheinen. Dadurch wird einerseits an dieses Tagen oder Uhrzeiten das
|
|
||||||
Kaufverhalten angeregt, als auch der Andrang an anderen reduziert. Dies dient
|
|
||||||
insbesondere der Entzerrung des zeitabhängigen Kaufverhaltens.
|
|
||||||
Des Weiteren können durch Rabatte weniger gut laufende Produkte in den
|
|
||||||
Vordergrund gerückt du vergünstigt angeboten werden.
|
|
||||||
Zusätzlich dazu können sich gut verkaufende Produkte mit einem (vermeintlich)
|
|
||||||
verringerten Preis versehen werden. Dies kann beim Kunden den „inneren
|
|
||||||
Schnäppchenjäger“ wecken und dafür sorgen, dass er sich dieses gute Angebot
|
|
||||||
nicht entgehen lassen kann.
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
Analysen, die zur Platzierung von Rabatten nützlich sein können:
|
|
||||||
Wochenübersicht, Einkaufszeiten, Verkaufszahlen
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12 m6">
|
|
||||||
<div id="marketing_tip_2" class="card white">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<span class="card-title center">Produktplatzierung </span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
Es gibt bestimmte Produkte, die werden häufig zusammen erworben. Sind diese
|
|
||||||
Produkte quer durch den Laden verstreut, so müssen die Kunden zusätzlich zu
|
|
||||||
ihren Wunschprodukten auch an anderen Auslagen vorbei und die Anzahl an
|
|
||||||
Spontankäufen eben jener weiteren Produkte steigt.
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
Analysen, die bei der Produktplatzierung hilfreich sein könnten:
|
|
||||||
Warenkorbsanalyse, Verkaufszahlen
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<%@include file="footer.jsp" %>
|
|
|
@ -32,7 +32,7 @@ function clearSelected(){
|
||||||
|
|
||||||
function updateDatasets() {
|
function updateDatasets() {
|
||||||
let dataset = $('#dataset');
|
let dataset = $('#dataset');
|
||||||
request('files').then(results => {
|
request('datasets').then(results => {
|
||||||
dataset.empty();
|
dataset.empty();
|
||||||
for (const result of results) {
|
for (const result of results) {
|
||||||
dataset.append($("<option></option>")
|
dataset.append($("<option></option>")
|
||||||
|
@ -56,7 +56,7 @@ function updateCache() {
|
||||||
} else {
|
} else {
|
||||||
//requesting files, getting values from html does not work...
|
//requesting files, getting values from html does not work...
|
||||||
//if no selection is provided, select newest file
|
//if no selection is provided, select newest file
|
||||||
request('files').then(results => {
|
request('datasets').then(results => {
|
||||||
let uuid = results[results.length - 1].uuid;
|
let uuid = results[results.length - 1].uuid;
|
||||||
dataset.val(uuid);
|
dataset.val(uuid);
|
||||||
updateAll(uuid);
|
updateAll(uuid);
|
||||||
|
@ -69,7 +69,7 @@ function updateAll(uuid) {
|
||||||
updateWeekOverviewChart(uuid);
|
updateWeekOverviewChart(uuid);
|
||||||
updateShoppingTimesChart(uuid);
|
updateShoppingTimesChart(uuid);
|
||||||
updateTopFlopChart(uuid);
|
updateTopFlopChart(uuid);
|
||||||
updateClusters(uuid)
|
updateClusters(uuid);
|
||||||
updateShoppingCartTable(uuid);
|
updateShoppingCartTable(uuid);
|
||||||
//add new charts here.
|
//add new charts here.
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
let top_flop_result;
|
let top_flop_result;
|
||||||
|
|
||||||
|
|
||||||
let top_flop = new Chart($("#top_flop_chart"), {
|
let sales = new Chart($("#sales_chart"), {
|
||||||
type: 'horizontalBar',
|
type: 'horizontalBar',
|
||||||
data: {
|
data: {
|
||||||
labels: [],
|
labels: [],
|
||||||
|
@ -34,23 +34,23 @@ let top_flop = new Chart($("#top_flop_chart"), {
|
||||||
|
|
||||||
function updateTopFlopChart(id) {
|
function updateTopFlopChart(id) {
|
||||||
if (typeof id !== 'undefined') {
|
if (typeof id !== 'undefined') {
|
||||||
request('top_flop', id).then(function (data) {
|
request('sales', id).then(function (data) {
|
||||||
top_flop_result = data;
|
top_flop_result = data;
|
||||||
updateTopFlop();
|
updateTopFlop();
|
||||||
});
|
});
|
||||||
} else request('top_flop').then(function (data) {
|
} else request('sales').then(function (data) {
|
||||||
top_flop_result = data;
|
top_flop_result = data;
|
||||||
updateTopFlop();
|
updateTopFlop();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTopFlop() {
|
function updateTopFlop() {
|
||||||
top_flop.data.labels = top_flop_result.labels;
|
sales.data.labels = top_flop_result.labels;
|
||||||
top_flop.data.datasets[0].data = top_flop_result.data;
|
sales.data.datasets[0].data = top_flop_result.data;
|
||||||
let seq = palette('mpn65', 15);
|
let seq = palette('mpn65', 15);
|
||||||
for (let i = 0; i < 15; i++) {
|
for (let i = 0; i < 15; i++) {
|
||||||
top_flop.data.datasets[0].backgroundColor[i] = "#" + seq[i];
|
sales.data.datasets[0].backgroundColor[i] = "#" + seq[i];
|
||||||
}
|
}
|
||||||
top_flop.update();
|
sales.update();
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,47 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Login</title>
|
|
||||||
<!--Import Google Icon Font-->
|
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
|
||||||
<!--Import materialize.css-->
|
|
||||||
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" media="screen,projection" />
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css" integrity="sha256-aa0xaJgmK/X74WM224KMQeNQC2xYKwlAt08oZqjeF0E=" crossorigin="anonymous" />
|
|
||||||
<!--Let browser know website is optimized for mobile-->
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
</head>
|
|
||||||
<body class="blue-grey lighten-5">
|
|
||||||
<div class="container row">
|
|
||||||
<!--Login-->
|
|
||||||
<div class="center">
|
|
||||||
<div class="card white col s6 push-s3">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="center">
|
|
||||||
<img style="width: 50%" src="logoOrginal.gif">
|
|
||||||
</div>
|
|
||||||
<div class="divider"></div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col s8 push-s2">
|
|
||||||
|
|
||||||
<form action="login" method="post">
|
|
||||||
<input id="password" type="password" class="validate" placeholder="Passwort" name="password">
|
|
||||||
<input class="white-text btn blue-grey lighten-2" type="submit" value="Login">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--<a class="waves-effect waves-light btn blue-grey lighten-2"><i class="material-icons left">lock_open</i>Login</a>-->
|
|
||||||
<!--Anfang Skriptbereich-->
|
|
||||||
|
|
||||||
<!--Script für Materlialize-->
|
|
||||||
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
|
||||||
<script type="text/javascript" src="js/materialize_components.js"></script>
|
|
||||||
|
|
||||||
<!--Ende Skriptbereich-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<%@include file="emptyHeader.jsp"%>
|
||||||
|
|
||||||
|
<div class="container row">
|
||||||
|
<!--Login-->
|
||||||
|
<div class="center">
|
||||||
|
<div class="card white col s6 push-s3">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<img style="width: 50%" src="logoOrginal.gif">
|
||||||
|
</div>
|
||||||
|
<div class="divider"></div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s8 push-s2">
|
||||||
|
|
||||||
|
<form action="login" method="post">
|
||||||
|
<input id="password" type="password" class="validate" placeholder="Passwort" name="password">
|
||||||
|
<input class="white-text btn blue-grey lighten-2" type="submit" value="Login">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%@include file="footer.jsp"%>
|
|
@ -0,0 +1,102 @@
|
||||||
|
<!--Marketing-Cards-->
|
||||||
|
<div id="marketing" class="row container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div id="marketing_tip_3" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Werbung</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Werbung dient dazu, auf bestimmte Produkte, Angebote oder den Markt im
|
||||||
|
Allgemeinen aufmerksam zu machen. Sie kann über verschiedene Wege verbreitet
|
||||||
|
werden, etwa das Internet, Zeitungsannoncen oder auch per TV/Radio.
|
||||||
|
Im Gegensatz zu Rabatten (die zeitabhängig am besten funktionieren) ist Werbung
|
||||||
|
stark von der Zielgruppe abhängig. Insbesondere in der Kombination mit anderen
|
||||||
|
Marketingmaßnahmen kann sie so ihre volle Wirkung entfalten.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Analysen, die für Werbung nützlich sein könnten:
|
||||||
|
Clusteranalyse, Wochenübersicht, Verkaufszahlen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div id="marketing_tip_4" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Sortimentsveränderung</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Gibt es eine Produktgruppe, die sich besonders gut verkauft, so sollte unter
|
||||||
|
Umständen über die Erweiterung des Sortiments innerhalb dieser Gruppe
|
||||||
|
nachgedacht werden.
|
||||||
|
Im Umkehrschluss dazu bietet sich an, schlecht verkaufte Produkte, welche keinen
|
||||||
|
hohen Gewinn abwerfen aus dem täglichen Verkaufsgeschäft wieder zu entfernen.
|
||||||
|
Dies verringert die Bildung von „Ladenhütern“ und schafft Platz für neue, sich
|
||||||
|
besser verkaufende Produkte.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Analysen, die bei der Sortimentswahl nützlich sein könnten:
|
||||||
|
Verkaufszahlen, Clusterübersicht
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div id="marketing_tip_1" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Rabatt</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Rabatte können z.B. an Tagen angeboten werden, an denen nur wenige Kunden
|
||||||
|
erscheinen. Dadurch wird einerseits an dieses Tagen oder Uhrzeiten das
|
||||||
|
Kaufverhalten angeregt, als auch der Andrang an anderen reduziert. Dies dient
|
||||||
|
insbesondere der Entzerrung des zeitabhängigen Kaufverhaltens.
|
||||||
|
Des Weiteren können durch Rabatte weniger gut laufende Produkte in den
|
||||||
|
Vordergrund gerückt du vergünstigt angeboten werden.
|
||||||
|
Zusätzlich dazu können sich gut verkaufende Produkte mit einem (vermeintlich)
|
||||||
|
verringerten Preis versehen werden. Dies kann beim Kunden den „inneren
|
||||||
|
Schnäppchenjäger“ wecken und dafür sorgen, dass er sich dieses gute Angebot
|
||||||
|
nicht entgehen lassen kann.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Analysen, die zur Platzierung von Rabatten nützlich sein können:
|
||||||
|
Wochenübersicht, Einkaufszeiten, Verkaufszahlen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div id="marketing_tip_2" class="card white">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="center">
|
||||||
|
<span class="card-title center">Produktplatzierung </span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Es gibt bestimmte Produkte, die werden häufig zusammen erworben. Sind diese
|
||||||
|
Produkte quer durch den Laden verstreut, so müssen die Kunden zusätzlich zu
|
||||||
|
ihren Wunschprodukten auch an anderen Auslagen vorbei und die Anzahl an
|
||||||
|
Spontankäufen eben jener weiteren Produkte steigt.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Analysen, die bei der Produktplatzierung hilfreich sein könnten:
|
||||||
|
Warenkorbsanalyse, Verkaufszahlen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,5 +1,17 @@
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
<!--Script für Diagramme-->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/google-palette@1.1.0/palette.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"
|
||||||
<script>
|
integrity="sha256-xKeoJ50pzbUGkpQxDYHD7o7hxe0LaOGeguUidbq6vis=" crossorigin="anonymous"></script>
|
||||||
M.AutoInit();
|
|
||||||
</script>
|
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||||
|
|
||||||
|
<script src="js/upload.js"></script>
|
||||||
|
<script src="js/cache.js"></script>
|
||||||
|
<script src="js/week_overview.js"></script>
|
||||||
|
<script src="js/shopping_times.js"></script>
|
||||||
|
<script src="js/sales.js"></script>
|
||||||
|
<script src="js/clusters.js"></script>
|
||||||
|
<script src="js/shopping_cart.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<%@include file="footer.jsp"%>
|
|
@ -14,7 +14,7 @@ public class TopFlopArticlesTest {
|
||||||
void test100() {
|
void test100() {
|
||||||
URL url = getClass().getClassLoader().getResource("kd100.csv");
|
URL url = getClass().getClassLoader().getResource("kd100.csv");
|
||||||
assert url != null;
|
assert url != null;
|
||||||
TopFlopArticle tfArticle = new TopFlopArticle(new File(url.getFile()));
|
SalesNumbers tfArticle = new SalesNumbers(new File(url.getFile()));
|
||||||
Map<String, Integer> results = tfArticle.getResult();
|
Map<String, Integer> results = tfArticle.getResult();
|
||||||
|
|
||||||
assertEquals(529, results.get("Farben"));
|
assertEquals(529, results.get("Farben"));
|
||||||
|
@ -29,7 +29,7 @@ public class TopFlopArticlesTest {
|
||||||
void test1000() {
|
void test1000() {
|
||||||
URL url = getClass().getClassLoader().getResource("kd1000.csv");
|
URL url = getClass().getClassLoader().getResource("kd1000.csv");
|
||||||
assert url != null;
|
assert url != null;
|
||||||
TopFlopArticle tfArticle = new TopFlopArticle(new File(url.getFile()));
|
SalesNumbers tfArticle = new SalesNumbers(new File(url.getFile()));
|
||||||
Map<String, Integer> results = tfArticle.getResult();
|
Map<String, Integer> results = tfArticle.getResult();
|
||||||
|
|
||||||
assertEquals(5643, results.get("Eisenwaren"));
|
assertEquals(5643, results.get("Eisenwaren"));
|
||||||
|
@ -44,7 +44,7 @@ public class TopFlopArticlesTest {
|
||||||
void test10000() {
|
void test10000() {
|
||||||
URL url = getClass().getClassLoader().getResource("kd10000.csv");
|
URL url = getClass().getClassLoader().getResource("kd10000.csv");
|
||||||
assert url != null;
|
assert url != null;
|
||||||
TopFlopArticle tfArticle = new TopFlopArticle(new File(url.getFile()));
|
SalesNumbers tfArticle = new SalesNumbers(new File(url.getFile()));
|
||||||
Map<String, Integer> results = tfArticle.getResult();
|
Map<String, Integer> results = tfArticle.getResult();
|
||||||
|
|
||||||
assertEquals(101665, results.get("Handwerkzeuge"));
|
assertEquals(101665, results.get("Handwerkzeuge"));
|
||||||
|
|
|
@ -13,7 +13,7 @@ import static org.junit.jupiter.api.Assertions.assertTimeout;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Week WeekOverviewDiagram Analysis Test.
|
* Week Overview Analysis Test.
|
||||||
*
|
*
|
||||||
* @author Johannes Theiner
|
* @author Johannes Theiner
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
|
|
Loading…
Reference in New Issue