You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2018/09/03 15:51:12 UTC

empire-db git commit: EMPIREDB-271 Vue project improvement

Repository: empire-db
Updated Branches:
  refs/heads/master 4c7e1b69b -> f6e918ff7


EMPIREDB-271
Vue project improvement


Project: http://git-wip-us.apache.org/repos/asf/empire-db/repo
Commit: http://git-wip-us.apache.org/repos/asf/empire-db/commit/f6e918ff
Tree: http://git-wip-us.apache.org/repos/asf/empire-db/tree/f6e918ff
Diff: http://git-wip-us.apache.org/repos/asf/empire-db/diff/f6e918ff

Branch: refs/heads/master
Commit: f6e918ff7353e4d2d52b829a242f1b5912633022
Parents: 4c7e1b6
Author: Rainer Döbele <do...@apache.org>
Authored: Mon Sep 3 17:51:05 2018 +0200
Committer: Rainer Döbele <do...@apache.org>
Committed: Mon Sep 3 17:51:05 2018 +0200

----------------------------------------------------------------------
 .gitignore                                      |   6 +
 .../main/webapp/WEB-INF/faces-config.pageflow   |   2 +
 .../src/main/webapp/css/layout.css              |   2 +-
 .../empire-db-example-vue/pom.xml               |  14 +-
 .../rest/service/AuthenticationService.java     |  70 ++++++
 .../empire/rest/service/EmployeeService.java    |  86 +++----
 .../org/apache/empire/rest/service/Service.java |  19 +-
 .../empire/rest/service/filter/CORSFilter.java  |  42 +++-
 .../service/filter/ServiceRequestFilter.java    |  43 +++-
 .../service/filter/ServiceResponseFilter.java   |   4 +-
 .../rest/service/listener/AppListener.java      |   4 +-
 .../vuesample/model/EmpireServiceConsts.java    |  31 ---
 .../src/main/vue/README.txt                     |  38 +++
 .../src/main/vue/config/dev.env.js              |  26 ++
 .../src/main/vue/config/index.js                |  55 +++++
 .../src/main/vue/config/prod.env.js             |  23 ++
 .../src/main/vue/index.html                     |  34 +++
 .../src/main/vue/package.json                   |  72 ++++++
 .../src/main/vue/src/App.vue                    |  64 +++++
 .../src/main/vue/src/api/emp-api.js             | 126 ++++++++++
 .../src/main/vue/src/assets/css/layout.css      | 241 +++++++++++++++++++
 .../src/main/vue/src/assets/img/boxes.gif       | Bin 0 -> 1132 bytes
 .../src/main/vue/src/main.js                    |  32 +++
 .../src/main/vue/src/pages/details.vue          |  82 +++++++
 .../src/main/vue/src/pages/list.vue             | 116 +++++++++
 .../src/main/vue/src/pages/login.vue            |  79 ++++++
 .../src/main/vue/src/router/index.js            |  47 ++++
 .../src/main/webapp/WEB-INF/web.xml             |   8 +-
 .../src/main/webapp/index.html                  |  12 +-
 29 files changed, 1266 insertions(+), 112 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 0d2b9fe..ab126fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,9 @@ target/
 .idea/
 *.iml
 empire-db-examples/empire-db-example-vue/.tomcatplugin
+empire-db-examples/empire-db-example-vue/src/main/vue/node_modules/
+empire-db-examples/empire-db-example-vue/src/main/vue/.postcssrc.js
+empire-db-examples/empire-db-example-vue/src/main/vue/.eslintrc.js
+empire-db-examples/empire-db-example-vue/src/main/vue/.eslintignore
+empire-db-examples/empire-db-example-vue/src/main/vue/.editorconfig
+empire-db-examples/empire-db-example-vue/src/main/vue/package-lock.json

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-jsf2/.metadata/src/main/webapp/WEB-INF/faces-config.pageflow
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-jsf2/.metadata/src/main/webapp/WEB-INF/faces-config.pageflow b/empire-db-examples/empire-db-example-jsf2/.metadata/src/main/webapp/WEB-INF/faces-config.pageflow
new file mode 100644
index 0000000..9cada8c
--- /dev/null
+++ b/empire-db-examples/empire-db-example-jsf2/.metadata/src/main/webapp/WEB-INF/faces-config.pageflow
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pageflow:Pageflow xmlns:pageflow="http://www.sybase.com/suade/pageflow" id="pf15359889576430" configfile="/empire-db-example-jsf2/src/main/webapp/WEB-INF/faces-config.xml"/>

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/layout.css
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/layout.css b/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/layout.css
index f710f40..39bcce1 100644
--- a/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/layout.css
+++ b/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/layout.css
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-@CHARSET "UTF-8";
+@charset "UTF-8";
 
 @import url("common.css");
 @import url("content.css");

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/pom.xml
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/pom.xml b/empire-db-examples/empire-db-example-vue/pom.xml
index a78c8f3..758a5b8 100644
--- a/empire-db-examples/empire-db-example-vue/pom.xml
+++ b/empire-db-examples/empire-db-example-vue/pom.xml
@@ -66,6 +66,18 @@
 			<version>2.0</version>
 		</dependency>
 
+		<!-- JSON -->
+		<dependency>
+			<groupId>javax.json</groupId>
+			<artifactId>javax.json-api</artifactId>
+			<version>1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.glassfish</groupId>
+			<artifactId>javax.json</artifactId>
+			<version>1.0.4</version>
+		</dependency>
+
 		<!-- Jersey -->
 		<dependency>
 			<groupId>org.glassfish.jersey.containers</groupId>
@@ -99,7 +111,7 @@
 
 	<build>
 
-		<finalName>evue</finalName>
+		<finalName>empvue</finalName>
 
 		<plugins>
 			<!-- Eclipse Web Tools Platform -->

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/AuthenticationService.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/AuthenticationService.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/AuthenticationService.java
new file mode 100644
index 0000000..6016583
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/AuthenticationService.java
@@ -0,0 +1,70 @@
+package org.apache.empire.rest.service;
+
+import java.util.UUID;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.NewCookie;
+import javax.ws.rs.core.Response;
+
+import org.apache.empire.commons.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/auth")
+public class AuthenticationService
+{
+    private static final Logger log = LoggerFactory.getLogger(AuthenticationService.class);
+
+    @POST
+    @Path("login")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response login(@FormParam("username") String username, @FormParam("password") String password)
+    {
+        JsonObjectBuilder jsonObjBuilder;
+        // Check params
+        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
+        {  
+            jsonObjBuilder = Json.createObjectBuilder();
+            jsonObjBuilder.add("error", "Invalid username or password.");
+            JsonObject jsonObj = jsonObjBuilder.build();
+            return Response.status(Response.Status.BAD_REQUEST).entity(jsonObj.toString()).build();
+        }
+
+        if (username.equals("bad") || password.equals("password"))
+        {
+            jsonObjBuilder = Json.createObjectBuilder();
+            jsonObjBuilder.add("error", "Bad user or password");
+            JsonObject jsonObj = jsonObjBuilder.build();
+            return Response.status(Response.Status.UNAUTHORIZED).entity(jsonObj.toString()).build();
+        }
+        
+        log.info("Log in for user {}", username);
+
+        // Set Cookie
+        String cookieValue = UUID.randomUUID().toString().replaceAll("-", "");
+        NewCookie cookie = new NewCookie(Service.Consts.LOGIN_COOKIE_NAME, cookieValue, "/", null, null, NewCookie.DEFAULT_MAX_AGE, false);
+        
+        // OK
+        return Response.ok().cookie(cookie).build();
+    }
+
+    @POST
+    @Path("logout")
+    public Response logout(@Context HttpServletRequest servletRequest)
+    {
+        NewCookie cookie = new NewCookie(Service.Consts.LOGIN_COOKIE_NAME, null, "/", null, null, 0, false);
+        return Response.status(Response.Status.NO_CONTENT).cookie(cookie).build();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/EmployeeService.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/EmployeeService.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/EmployeeService.java
index 8efcbe0..a8416b9 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/EmployeeService.java
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/EmployeeService.java
@@ -47,39 +47,39 @@ public class EmployeeService extends Service {
 
 	private static final Logger log = LoggerFactory.getLogger(EmployeeService.class);
 
-	@POST
-	@Path("/{employeeId}")
-	@Consumes(MediaType.APPLICATION_JSON)
-	public Response updateEmployee(@PathParam("employeeId") int employeeId, EmployeeBean employee) {
+    @GET
+    @Path("/list/")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getEmployeeList() {
 
-		SampleDB db = getDatabase();
-		TEmployees TE = db.T_EMPLOYEES;
+        SampleDB db = getDatabase();
 
-		DBCommand cmd = db.createCommand();
+        TEmployees TE = db.T_EMPLOYEES;
 
-		// First name
-		cmd.set(TE.FIRST_NAME.to(TE.FIRST_NAME.validate(getValue(employee.getFirstName()))));
+        log.info("Providing employee list...");
 
-		// Last name
-		cmd.set(TE.LAST_NAME.to(TE.LAST_NAME.validate(getValue(employee.getLastName()))));
+        DBCommand cmd = db.createCommand();
+        cmd.select(TE.EMPLOYEE_ID, TE.LAST_NAME, TE.FIRST_NAME, TE.DATE_OF_BIRTH);
 
-		// Date of Birth
-		cmd.set(TE.DATE_OF_BIRTH.to(TE.DATE_OF_BIRTH.validate(getValue(employee.getDateOfBirth()))));
+        DBReader reader = new DBReader();
+        List<EmployeeBean> list = new ArrayList<>();
 
-		cmd.where(TE.EMPLOYEE_ID.is(employeeId));
+        try {
+            reader.open(cmd, getConnection());
+            while (reader.moveNext()) {
+                list.add(createEmployee(reader));
+            }
 
-		int executeUpdate = db.executeUpdate(cmd, getConnection());
+        } finally {
+            reader.close();
+        }
 
-		if (executeUpdate == 0) {
-			return Response.status(Status.NOT_FOUND).build();
-		} else {
-			return Response.ok().build();
-		}
+        return Response.ok(list).build();
 
-	}
+    }
 
 	@GET
-	@Path("/{employeeId}")
+	@Path("/get/{employeeId}")
 	@Produces(MediaType.APPLICATION_JSON)
 	public Response getEmployee(@PathParam("employeeId") int employeeId) {
 
@@ -111,34 +111,36 @@ public class EmployeeService extends Service {
 		return Response.ok(eb).build();
 	}
 
-	@GET
-	@Path("/list/")
-	@Produces(MediaType.APPLICATION_JSON)
-	public Response getEmployeeList() {
+    @POST
+    @Path("/set")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateEmployee(EmployeeBean employee) {
 
-		SampleDB db = getDatabase();
+        SampleDB db = getDatabase();
+        TEmployees TE = db.T_EMPLOYEES;
 
-		TEmployees TE = db.T_EMPLOYEES;
+        DBCommand cmd = db.createCommand();
 
-		DBCommand cmd = db.createCommand();
-		cmd.select(TE.EMPLOYEE_ID, TE.LAST_NAME, TE.FIRST_NAME, TE.DATE_OF_BIRTH);
+        // First name
+        cmd.set(TE.FIRST_NAME.to(TE.FIRST_NAME.validate(getValue(employee.getFirstName()))));
 
-		DBReader reader = new DBReader();
-		List<EmployeeBean> list = new ArrayList<>();
+        // Last name
+        cmd.set(TE.LAST_NAME.to(TE.LAST_NAME.validate(getValue(employee.getLastName()))));
 
-		try {
-			reader.open(cmd, getConnection());
-			while (reader.moveNext()) {
-				list.add(createEmployee(reader));
-			}
+        // Date of Birth
+        cmd.set(TE.DATE_OF_BIRTH.to(TE.DATE_OF_BIRTH.validate(getValue(employee.getDateOfBirth()))));
 
-		} finally {
-			reader.close();
-		}
+        cmd.where(TE.EMPLOYEE_ID.is(employee.getEmployeeId()));
 
-		return Response.ok(list).build();
+        int executeUpdate = db.executeUpdate(cmd, getConnection());
 
-	}
+        if (executeUpdate == 0) {
+            return Response.status(Status.NOT_FOUND).build();
+        } else {
+            return Response.ok().build();
+        }
+
+    }
 
 	private EmployeeBean createEmployee(DBReader reader) {
 

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/Service.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/Service.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/Service.java
index f1a449d..c016748 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/Service.java
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/Service.java
@@ -26,12 +26,25 @@ import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.container.ContainerRequestContext;
 import javax.ws.rs.core.Context;
 
-import org.apache.empire.vuesample.model.EmpireServiceConsts;
 import org.apache.empire.vuesample.model.db.SampleDB;
 import org.glassfish.jersey.server.ContainerRequest;
 
 public abstract class Service {
 
+    public static class Consts {
+    
+        public static final String  LOGIN_COOKIE_NAME       = "EmployeeVueLoginCookie";
+        
+        public static final String  ATTRIBUTE_DB            = "db";
+    
+        public static final String  ATTRIBUTE_CONNECTION    = "connection";
+    
+        public static final String  ATTRIBUTE_DATASOURCE    = "ds";
+    
+        public static final String  ATTRIBUTE_CONFIG        = "config";
+    
+    }
+    
 	@Context
 	private ServletContext			context;
 
@@ -42,12 +55,12 @@ public abstract class Service {
 	private HttpServletRequest		req;
 
 	public SampleDB getDatabase() {
-		return (SampleDB) this.context.getAttribute(EmpireServiceConsts.ATTRIBUTE_DB);
+		return (SampleDB) this.context.getAttribute(Service.Consts.ATTRIBUTE_DB);
 	}
 
 	public Connection getConnection() {
 		ContainerRequest containerRequest = (ContainerRequest) this.containerRequestContext;
-		return (Connection) containerRequest.getProperty(EmpireServiceConsts.ATTRIBUTE_CONNECTION);
+		return (Connection) containerRequest.getProperty(Service.Consts.ATTRIBUTE_CONNECTION);
 	}
 
 	public ServletRequest getServletRequest() {

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/CORSFilter.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/CORSFilter.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/CORSFilter.java
index b36fe6a..d12ffa1 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/CORSFilter.java
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/CORSFilter.java
@@ -23,18 +23,38 @@ import java.io.IOException;
 import javax.ws.rs.container.ContainerRequestContext;
 import javax.ws.rs.container.ContainerResponseContext;
 import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.container.PreMatching;
 import javax.ws.rs.ext.Provider;
 
-@Provider
-public class CORSFilter implements ContainerResponseFilter {
+import org.apache.empire.commons.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-	@Override
-	public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext cres) throws IOException {
-		// cres.getHeaders().add("Access-Control-Allow-Origin", "*");
-		// cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
-		// cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
-		// cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
-		// cres.getHeaders().add("Access-Control-Max-Age", "1209600");
-	}
+@Provider
+@PreMatching
+public class CORSFilter implements ContainerResponseFilter
+{
+    private static final Logger log = LoggerFactory.getLogger(CORSFilter.class);
 
-}
\ No newline at end of file
+    @Override
+    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
+        throws IOException
+    {
+        // get origin
+        String origin = requestContext.getHeaderString("origin");
+        if (StringUtils.isNotEmpty(origin))
+        {   // origin given
+            log.info("Accepting request from {}", origin);
+            // set response
+            responseContext.getHeaders().add("Access-Control-Allow-Origin", origin);
+            responseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
+            responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
+            responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
+            responseContext.getHeaders().add("Access-Control-Max-Age", "1209600");
+        }
+        else
+        {   // unknown origin
+            log.info("Accepting request from unknown origin");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceRequestFilter.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceRequestFilter.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceRequestFilter.java
index 183595c..427b133 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceRequestFilter.java
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceRequestFilter.java
@@ -26,34 +26,51 @@ import javax.servlet.ServletContext;
 import javax.ws.rs.container.ContainerRequestContext;
 import javax.ws.rs.container.ContainerRequestFilter;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.Provider;
 
+import org.apache.empire.rest.service.Service;
 import org.apache.empire.rest.service.listener.AppListener;
-import org.apache.empire.vuesample.model.EmpireServiceConsts;
 import org.glassfish.jersey.server.ContainerRequest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Provider
 @Priority(0)
-public class ServiceRequestFilter implements ContainerRequestFilter {
+public class ServiceRequestFilter implements ContainerRequestFilter
+{
 
-	private static final Logger	log	= LoggerFactory.getLogger(ServiceRequestFilter.class);
+    private static final Logger log = LoggerFactory.getLogger(ServiceRequestFilter.class);
 
-	@Context
-	private ServletContext		servletContext;
+    @Context
+    private ServletContext      servletContext;
 
-	@Override
-	public void filter(ContainerRequestContext requestContext) throws IOException {
+    @Override
+    public void filter(ContainerRequestContext requestContext)
+        throws IOException
+    {
+        String path = requestContext.getUriInfo().getPath();
+        log.info("Filtering request path: " + path);
+        // Check authentication
+        if (!path.startsWith("auth") && !requestContext.getMethod().equals("OPTIONS"))
+        {
+            Cookie cookie = requestContext.getCookies().get(Service.Consts.LOGIN_COOKIE_NAME);
+            if (cookie == null)
+            {
+                requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
+                return;
+            }
+        }
 
-		ContainerRequest containerRequest = (ContainerRequest) requestContext;
+        ContainerRequest containerRequest = (ContainerRequest) requestContext;
 
-		// get Connection from pool
-		Connection conn = AppListener.getJDBCConnection(this.servletContext);
+        // get Connection from pool
+        Connection conn = AppListener.getJDBCConnection(this.servletContext);
 
-		// Add to context
-		containerRequest.setProperty(EmpireServiceConsts.ATTRIBUTE_CONNECTION, conn);
+        // Add to context
+        containerRequest.setProperty(Service.Consts.ATTRIBUTE_CONNECTION, conn);
 
-	}
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceResponseFilter.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceResponseFilter.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceResponseFilter.java
index b2dedb0..0c84d62 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceResponseFilter.java
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/filter/ServiceResponseFilter.java
@@ -29,7 +29,7 @@ import javax.ws.rs.container.ContainerResponseFilter;
 import javax.ws.rs.core.Response.Status.Family;
 import javax.ws.rs.ext.Provider;
 
-import org.apache.empire.vuesample.model.EmpireServiceConsts;
+import org.apache.empire.rest.service.Service;
 import org.glassfish.jersey.server.ContainerRequest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,7 +46,7 @@ public class ServiceResponseFilter implements ContainerResponseFilter {
 		// responseContext.getHeaders().putSingle(key, value);
 
 		ContainerRequest containerRequest = (ContainerRequest) requestContext;
-		Connection conn = (Connection) containerRequest.getProperty(EmpireServiceConsts.ATTRIBUTE_CONNECTION);
+		Connection conn = (Connection) containerRequest.getProperty(Service.Consts.ATTRIBUTE_CONNECTION);
 
 		boolean success = responseContext.getStatusInfo().getFamily() == Family.SUCCESSFUL;
 

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/listener/AppListener.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/listener/AppListener.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/listener/AppListener.java
index a3c1249..332b2f7 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/listener/AppListener.java
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/listener/AppListener.java
@@ -34,7 +34,7 @@ import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.exceptions.QueryFailedException;
 import org.apache.empire.db.hsql.DBDatabaseDriverHSql;
 import org.apache.empire.db.mysql.DBDatabaseDriverMySQL;
-import org.apache.empire.vuesample.model.EmpireServiceConsts;
+import org.apache.empire.rest.service.Service;
 import org.apache.empire.vuesample.model.db.SampleDB;
 import org.apache.log4j.ConsoleAppender;
 import org.apache.log4j.Level;
@@ -63,7 +63,7 @@ public class AppListener implements ServletContextListener {
 		db.open(driver, conn);
 
 		// Add to context
-		sce.getServletContext().setAttribute(EmpireServiceConsts.ATTRIBUTE_DB, db);
+		sce.getServletContext().setAttribute(Service.Consts.ATTRIBUTE_DB, db);
 		// sce.getServletContext().setAttribute(MobileImportServiceConsts.ATTRIBUTE_DATASOURCE, ds);
 		// sce.getServletContext().setAttribute(MobileImportServiceConsts.ATTRIBUTE_CONFIG, config);
 

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/EmpireServiceConsts.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/EmpireServiceConsts.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/EmpireServiceConsts.java
deleted file mode 100644
index 833e968..0000000
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/EmpireServiceConsts.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.empire.vuesample.model;
-
-public class EmpireServiceConsts {
-
-	public static final String	ATTRIBUTE_DB			= "db";
-
-	public static final String	ATTRIBUTE_CONNECTION	= "connection";
-
-	public static final String	ATTRIBUTE_DATASOURCE	= "ds";
-
-	public static final String	ATTRIBUTE_CONFIG		= "config";
-
-}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/README.txt
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/README.txt b/empire-db-examples/empire-db-example-vue/src/main/vue/README.txt
new file mode 100644
index 0000000..b3ab0de
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/README.txt
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# vue-web
+
+> A Vue.js project
+
+## Build Setup
+
+``` bash
+# install dependencies
+npm install
+
+# serve with hot reload at localhost:8080
+npm run dev
+
+# build for production with minification
+npm run build
+
+# build for production and view the bundle analyzer report
+npm run build --report
+```
+
+For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/config/dev.env.js
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/config/dev.env.js b/empire-db-examples/empire-db-example-vue/src/main/vue/config/dev.env.js
new file mode 100644
index 0000000..fdbba48
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/config/dev.env.js
@@ -0,0 +1,26 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+var merge = require('webpack-merge')
+var prodEnv = require('./prod.env')
+
+module.exports = merge(prodEnv, {
+  DEBUG_MODE: false,
+  NODE_ENV: '"development"',
+  EMP_SERVICE_URL:  '"http://localhost:8080/empvue/api"',
+  EMP_DEFAULT_USER: '"test"',
+  EMP_DEFAULT_PWD:  '"test"'
+})

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/config/index.js
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/config/index.js b/empire-db-examples/empire-db-example-vue/src/main/vue/config/index.js
new file mode 100644
index 0000000..955003a
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/config/index.js
@@ -0,0 +1,55 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// see http://vuejs-templates.github.io/webpack for documentation.
+var path = require('path')
+
+module.exports = {
+  build: {
+    env: require('./prod.env'),
+    index: path.resolve(__dirname, '../dist/index.html'),
+    assetsRoot: path.resolve(__dirname, '../dist'),
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '',
+    productionSourceMap: true,
+    // Gzip off by default as many popular static hosts such as
+    // Surge or Netlify already gzip all static assets for you.
+    // Before setting to `true`, make sure to:
+    // npm install --save-dev compression-webpack-plugin
+    productionGzip: false,
+    productionGzipExtensions: ['js', 'css'],
+    // Run the build command with an extra argument to
+    // View the bundle analyzer report after build finishes:
+    // `npm run build --report`
+    // Set to `true` or `false` to always turn it on or off
+    bundleAnalyzerReport: process.env.npm_config_report
+  },
+  dev: {
+    env: require('./dev.env'),
+    port: 8088,
+    autoOpenBrowser: true,
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '',
+    proxyTable: {},
+    // CSS Sourcemaps off by default because relative paths are "buggy"
+    // with this option, according to the CSS-Loader README
+    // (https://github.com/webpack/css-loader#sourcemaps)
+    // In our experience, they generally work as expected,
+    // just be aware of this issue when enabling this option.
+    cssSourceMap: false
+  }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/config/prod.env.js
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/config/prod.env.js b/empire-db-examples/empire-db-example-vue/src/main/vue/config/prod.env.js
new file mode 100644
index 0000000..2ea1213
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/config/prod.env.js
@@ -0,0 +1,23 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+module.exports = {
+  DEBUG_MODE: false,
+  NODE_ENV: '"production"',
+  RDP_SERVICE_URL: '"/api"',
+  RDP_DEFAULT_USER: '""',
+  RDP_DEFAULT_PWD: '""'
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/index.html
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/index.html b/empire-db-examples/empire-db-example-vue/src/main/vue/index.html
new file mode 100644
index 0000000..59a4f3d
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/index.html
@@ -0,0 +1,34 @@
+<!-- 
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+ -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    <title>Revierdienstplan</title>
+
+  </head>
+  <body>
+    <div class="container">
+      <div id="app"></div>
+      <!-- built files will be auto injected -->
+    </div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/package.json
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/package.json b/empire-db-examples/empire-db-example-vue/src/main/vue/package.json
new file mode 100644
index 0000000..a083bf7
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/package.json
@@ -0,0 +1,72 @@
+{
+  "name": "vue-web",
+  "version": "1.0.0",
+  "description": "A Vue.js project",
+  "author": "Rainer Doebele <do...@apache.org>",
+  "private": true,
+  "scripts": {
+    "dev": "node build/dev-server.js",
+    "start": "node build/dev-server.js",
+    "build": "node build/build.js",
+    "build-dev": "node build/build-dev.js",
+    "lint": "eslint --ext .js,.vue src"
+  },
+  "dependencies": {
+    "jquery": "^3.2.1",
+    "vue": "^2.3.3",
+    "vue-router": "^2.6.0"
+  },
+  "devDependencies": {
+    "autoprefixer": "^7.1.2",
+    "babel-core": "^6.22.1",
+    "babel-eslint": "^7.1.1",
+    "babel-loader": "^7.1.1",
+    "babel-plugin-transform-runtime": "^6.22.0",
+    "babel-preset-env": "^1.3.2",
+    "babel-preset-stage-2": "^6.22.0",
+    "babel-register": "^6.22.0",
+    "chalk": "^2.0.1",
+    "connect-history-api-fallback": "^1.3.0",
+    "copy-webpack-plugin": "^4.0.1",
+    "css-loader": "^0.28.0",
+    "cssnano": "^3.10.0",
+    "eslint": "^3.19.0",
+    "eslint-friendly-formatter": "^3.0.0",
+    "eslint-loader": "^1.7.1",
+    "eslint-plugin-html": "^3.0.0",
+    "eslint-config-standard": "^6.2.1",
+    "eslint-plugin-promise": "^3.4.0",
+    "eslint-plugin-standard": "^2.0.1",
+    "eventsource-polyfill": "^0.9.6",
+    "express": "^4.14.1",
+    "extract-text-webpack-plugin": "^2.0.0",
+    "file-loader": "^0.11.1",
+    "friendly-errors-webpack-plugin": "^1.1.3",
+    "html-webpack-plugin": "^2.28.0",
+    "http-proxy-middleware": "^0.17.3",
+    "webpack-bundle-analyzer": "^2.2.1",
+    "semver": "^5.3.0",
+    "shelljs": "^0.7.6",
+    "opn": "^5.1.0",
+    "optimize-css-assets-webpack-plugin": "^2.0.0",
+    "ora": "^1.2.0",
+    "rimraf": "^2.6.0",
+    "url-loader": "^0.5.8",
+    "vue-loader": "^12.1.0",
+    "vue-style-loader": "^3.0.1",
+    "vue-template-compiler": "^2.3.3",
+    "webpack": "^2.6.1",
+    "webpack-dev-middleware": "^1.10.0",
+    "webpack-hot-middleware": "^2.18.0",
+    "webpack-merge": "^4.1.0"
+  },
+  "engines": {
+    "node": ">= 4.0.0",
+    "npm": ">= 3.0.0"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 8"
+  ]
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/src/App.vue
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/App.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/App.vue
new file mode 100644
index 0000000..3bc8796
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/App.vue
@@ -0,0 +1,64 @@
+<!--
+      Licensed to the Apache Software Foundation (ASF) under one or more
+      contributor license agreements. See the NOTICE file distributed with
+      this work for additional information regarding copyright ownership.
+      The ASF licenses this file to You under the Apache License, Version
+      2.0 (the "License"); you may not use this file except in compliance
+      with the License. You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+      applicable law or agreed to in writing, software distributed under the
+      License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+      CONDITIONS OF ANY KIND, either express or implied. See the License for
+      the specific language governing permissions and limitations under the
+      License.
+  -->
+<template>
+  <div id="app">
+
+  	<div class="titleDiv">Employee Management Application</div>
+    <button class="rdp-button" @click="logout">Logout</button>
+
+    <router-view></router-view>
+
+  </div>
+</template>
+
+<script>
+  import EMPAPI from './api/emp-api'
+
+  export default {
+    name: 'app',
+
+    methods: {
+      isLoggedIn: function () {
+        if (EMPAPI.loggedIn === undefined) {
+          EMPAPI.debug('EMPAPI.loggedIn is undefined!')
+          EMPAPI.loggedIn = true // assume true
+        }
+        return EMPAPI.loggedIn
+      },
+      logout: function () {
+        if (!confirm('Do you really want to logout?')) {
+          return
+        }
+        EMPAPI.logout().done(() => this.onLogoutComplete())
+      },
+      onLoginComplete: function () {
+        EMPAPI.loggedIn = true
+        this.$router.push('/list')
+      },
+      onLogoutComplete: function () {
+        EMPAPI.loggedIn = false
+        this.$router.push('/login')
+      }
+    }
+  }
+
+</script>
+
+<style>
+  @import './assets/css/layout.css';
+</style>
+
+</style>

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/src/api/emp-api.js
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/api/emp-api.js b/empire-db-examples/empire-db-example-vue/src/main/vue/src/api/emp-api.js
new file mode 100644
index 0000000..e8cf1b4
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/api/emp-api.js
@@ -0,0 +1,126 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+import $ from 'jquery'
+
+function isDebug () {
+  return process.env.DEBUG_MODE
+}
+
+const AJAX = {
+  initialized: false,
+  baseURL: process.env.EMP_SERVICE_URL,
+  // default options
+  defaultOptions: {
+    xhrFields: {
+      withCredentials: true
+    },
+    statusCode: {
+      401: function () {
+        // Unauthorized
+        EMPAPI.loggedIn = false
+      },
+      404: function () {
+        alert('The requested service is not available!')
+      }
+    },
+    /*
+    beforeSend: function (jqXHR) {
+      //
+      // Add additional header values e.g.
+      //   jqXHR.setRequestHeader('X-RDPLAN-????', 'some value')
+      //
+      EMPAPI.debug('Sensing request!' + this.url)
+    },
+    */
+    error: function (status) {
+      var msg = `${status.statusText} (${status.status})`
+      if (status.responseText) {
+        msg = msg + ': ' + status.responseText
+      }
+      EMPAPI.debug('Ajax error: ' + msg)
+    }
+  },
+  // init ajax
+  setup: function () {
+    // set Ajax defaults
+    $.ajaxSetup(AJAX.defaultOptions)
+    AJAX.initialized = true
+  },
+  call: function (options) {
+    // check initialized
+    if (AJAX.initialized !== true) {
+      EMPAPI.debug('AJAX not initialized. Initialing now...')
+      AJAX.setup()
+    }
+    // extend the url
+    options.url = AJAX.baseURL + options.url
+    // extend options
+    // alert('URL=' + options.url)
+    // options = $.extend({}, AJAX.defaultOptions, options)
+    // call
+    return $.ajax(options)
+  },
+  get: function (target) {
+    return AJAX.call({type: 'GET', url: target})
+  },
+  post: function (target, data) {
+    return AJAX.call({type: 'POST', url: target, data: data})
+  },
+  postJSON: function (target, json) {
+    return AJAX.call({type: 'POST', url: target, contentType: 'application/json', data: JSON.stringify(json)})
+  }
+}
+// setup
+AJAX.setup()
+
+// The EMPAPI
+const EMPAPI = {
+
+  loggedIn: true, // assume true
+
+  debug: function (msg) {
+    if (isDebug()) {
+      alert('Debug: ' + msg)
+    } else {
+      console.log(msg)
+    }
+  },
+
+  login: function (username, password) {
+    const data = {username, password}
+    return AJAX.post('/auth/login', data)
+  },
+
+  logout: function () {
+    return AJAX.post('/auth/logout')
+  },
+
+  loadEmployeeList: function () {
+    return AJAX.get(`/employee/list`)
+  },
+
+  loadEmployeeDetails: function (employeeId) {
+    return AJAX.get(`/employee/get/${employeeId}`)
+  },
+
+  updateEmployee: function (employeeData) {
+    return AJAX.postJSON('/employee/set', employeeData)
+  }
+}
+
+// export
+export default EMPAPI

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/src/assets/css/layout.css
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/assets/css/layout.css b/empire-db-examples/empire-db-example-vue/src/main/vue/src/assets/css/layout.css
new file mode 100644
index 0000000..2de111b
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/assets/css/layout.css
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+* {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+*:before,
+*:after {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+html, body  {
+	width: 800px;
+    margin-left: 10px;
+    margin-right: auto;
+    margin-bottom: 5px;
+    color: black;
+    background-color: white;
+    font-family: Verdana, Arial, sans-serif;
+    font-size:12px;
+}
+.titleDiv {
+    background-color: #EFFBEF;
+    font-weight:bold;
+    font-size:18px;
+    text-align:left;
+    padding-left:10px;
+    padding-top:10px;
+    padding-bottom:10px;
+    border:2px solid #8F99EF;
+}
+h1 { font-weight:bold; color: brown; font-size:15px; text-align:left;}
+
+td { font-size:12px; padding-right:10px; }
+th { text-align:left; font-weight:bold; font-size:13px; padding-right:10px; }
+
+A:link { text-decoration:none;}
+A:visited { text-decoration:none;}
+A:hover { text-decoration:underline;}
+
+.even { background-color: #EFEFFB; 	text-align:left;}
+.odd { background-color:  #FFFFFF; 	text-align:left; }
+
+.nowrap { white-space:nowrap; }
+
+
+#messages ul {
+    background-color: #FBF0F0;
+    border:2px solid #8F99EF;
+	list-style-type: square;
+	padding: 8px;
+	padding-left: 24px;
+}
+#messages ul li {
+	padding: 4px 0;
+/*
+	padding-left:18px;
+    padding-top:2px;
+    padding-bottom:10px;
+    padding-right:5px;
+*/
+	color: #922727;
+    font-weight: bold;
+}
+
+
+form {
+}
+
+div.formPanel {
+	border: 1px #8F99EF solid;
+	background-color: #F8F8F8;
+	padding: 8px 4px;
+}
+table.inputForm {
+	width: 100%;
+}
+table.inputForm td.eCtlLabel {
+	vertical-align:top;
+	width: 140px;
+	height: 24px;
+	padding-top: 3px;
+	font-weight: bold;
+}
+table.inputForm td.eCtlInput {
+	vertical-align:top;
+}
+table.inputForm td.buttonBar {
+	padding-top: 8px;
+}
+
+div.buttonBar {
+	margin: 12px 0;
+}
+
+.buttonBar a,
+.buttonBar a:visited {
+	display: inline-block;
+	border: 1px #8F99EF solid;
+	padding: 4px 12px;
+	color: black;
+	text-decoration: none;
+	margin-right: 16px;
+	background-color: white;
+}
+.buttonBar a:hover {
+	background-color: #EFFBEF;
+}
+
+div.searchResult,
+span.searchResult {
+	display: block;
+	margin: 12px 0;
+	padding: 4px 0;
+}
+.searchResult table {
+	width: 100%;
+	border: 1px #8F99EF solid;
+	border-collapse: collapse;
+}
+.searchResult table tr th,
+.searchResult table tr td {
+	padding: 4px;
+}
+.searchResult table tr th {
+	background-color: #EFFBEF;
+	border-bottom: 1px #8F99EF solid;
+}
+.searchResult table a.eLink,
+.searchResult table a.eLink:visited {
+	color: brown;
+	font-weight: bold;
+}
+
+span.required {
+	color: brown;
+}
+select,
+input[type=text],
+input[type=password] {
+	border: 1px #8f99ef solid;
+}
+select.eInpReq,
+input[type=text].eInpReq {
+	border: 1px brown solid;
+}
+select.eInpDis,
+input[type=text].eInpDis {
+	border: 1px #C0C0C0 solid;
+	color: #808080;
+}
+span.eInpDis {
+	display: inline-block;
+	padding-top: 3px;
+}
+.eUnit {
+	padding-left: 4px;
+	font-style: bold;
+}
+.eInputHint {
+	padding-left: 4px;
+	font-style: italic;
+}
+div.eTypeBoolFalse {
+	width: 12px;
+	height: 12px;
+	background-image:url('../img/boxes.gif');
+	background-repeat: no-repeat;
+	background-position: 0 0;
+}
+div.eTypeBoolTrue {
+	width: 12px;
+	height: 12px;
+	background-image:url('../img/boxes.gif');
+	background-repeat: no-repeat;
+	background-position: -12px 0;
+}
+div.eTabView {
+	width: 500px;
+}
+table.eTabBar {
+	width: 100%;
+	border-spacing: 0;
+	border-collapse: collapse;
+	table-layout: auto;
+	padding: 0;
+}
+table.eTabBar tr td.eTabLabel {
+	border: 1px #8F99EF solid;
+	padding: 8px;
+	white-space: nowrap;
+}
+table.eTabBar tr td.eTabLabel.eTabActive {
+	border-bottom: 1px #F8F8F8 solid;
+	background-color: #F8F8F8;
+}
+table.eTabBar tr td.eTabLabel.eTabDisabled {
+	color: gray;
+	font-style: italic;
+}
+table.eTabBar tr td.eTabBarEmpty {
+	width: 99%;
+	border-bottom: 1px #8F99EF solid;
+}
+table.eTabPanel {
+	width: 100%;
+	border-spacing: 0;
+	border-collapse: collapse;
+	border: 1px #8F99EF solid;
+	border-top: 0px;
+}
+table.eTabPanel tr td.eTabPage {
+	padding: 8px;
+	background-color: #F8F8F8;
+}
+table.eTabPanel tr td.eTabPage div.formPanel {
+	border: 0;
+}
+div.info-msg {
+	padding: 12px;
+	background-color: #FFFFCA;
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/src/assets/img/boxes.gif
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/assets/img/boxes.gif b/empire-db-examples/empire-db-example-vue/src/main/vue/src/assets/img/boxes.gif
new file mode 100644
index 0000000..57bf32d
Binary files /dev/null and b/empire-db-examples/empire-db-example-vue/src/main/vue/src/assets/img/boxes.gif differ

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/src/main.js
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/main.js b/empire-db-examples/empire-db-example-vue/src/main/vue/src/main.js
new file mode 100644
index 0000000..b7f1591
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/main.js
@@ -0,0 +1,32 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// The Vue build version to load with the `import` command
+// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
+import Vue from 'vue'
+import App from './App'
+import router from './router/'
+
+Vue.config.productionTip = false
+
+/* eslint-disable no-new */
+new Vue({
+  el: '#app',
+  router,
+  template: '<App/>',
+  components: { App }
+})

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/details.vue
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/details.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/details.vue
new file mode 100644
index 0000000..942eeef
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/details.vue
@@ -0,0 +1,82 @@
+<!--
+      Licensed to the Apache Software Foundation (ASF) under one or more
+      contributor license agreements. See the NOTICE file distributed with
+      this work for additional information regarding copyright ownership.
+      The ASF licenses this file to You under the Apache License, Version
+      2.0 (the "License"); you may not use this file except in compliance
+      with the License. You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+      applicable law or agreed to in writing, software distributed under the
+      License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+      CONDITIONS OF ANY KIND, either express or implied. See the License for
+      the specific language governing permissions and limitations under the
+      License.
+  -->
+<template>
+  <div class="rdp-content">
+
+    <h1>Employee-Details</h1>
+
+    <!--
+    <div class="rdp-weeknavbar">
+      <button class="rdp-button" @click="showPlan($event)">Zurück</button>
+    </div>
+
+    <div class="rdp-weekinfo">
+      Hinweise für Bezirk <strong>{{info.bereich.kurz}}</strong> ({{info.bereich.name}})
+      <br/>am <strong>{{info.tag.datumLang}}</strong>
+    </div>
+
+    <rdp-hints :hints="info.hinweise"></rdp-hints>
+
+    <div class="rdp-weeknavbar">
+      <button class="rdp-button" @click="showPlan($event)">Zurück</button>
+    </div>
+    -->
+
+    <div class="rdp-weeknavbar">
+      <button class="rdp-button" @click="showList($event)">Back</button>
+    </div>
+
+  </div>
+</template>
+
+<script>
+  import EMPAPI from '../api/emp-api'
+
+  export default {
+    name: 'details',
+
+    components: {
+    },
+
+    created: function () {
+      this.loadDetails()
+    },
+
+    data () {
+      return {
+        loggedIn: true,
+        employeeId: 0,
+        info: {}
+      }
+    },
+
+    methods: {
+      loadDetails: function (event) {
+        EMPAPI.debug('load employee details')
+        /*
+        this.datum = this.$route.params.datum
+        this.bereichId = this.$route.params.bereichId
+        RDPAPI.loadHints(this.datum, this.bereichId)
+          .done(response => (this.info = response))
+          .fail(() => this.$router.push('/login'))
+        */
+      },
+      showList: function (event) {
+        this.$router.push('/list')
+      }
+    }
+  }
+</script>

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/list.vue
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/list.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/list.vue
new file mode 100644
index 0000000..4a800ee
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/list.vue
@@ -0,0 +1,116 @@
+<!--
+      Licensed to the Apache Software Foundation (ASF) under one or more
+      contributor license agreements. See the NOTICE file distributed with
+      this work for additional information regarding copyright ownership.
+      The ASF licenses this file to You under the Apache License, Version
+      2.0 (the "License"); you may not use this file except in compliance
+      with the License. You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+      applicable law or agreed to in writing, software distributed under the
+      License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+      CONDITIONS OF ANY KIND, either express or implied. See the License for
+      the specific language governing permissions and limitations under the
+      License.
+  -->
+<template>
+  <div class="rdp-content">
+
+    <h1>Employee-List</h1>
+
+    <table class="employeeList">
+      <colgroup>
+        <col class="col-id"/>
+        <col class="col-vname"/>
+        <col class="col-nname"/>
+        <col class="col-datum"/>
+      </colgroup>
+
+      <thead>
+      <tr>
+        <th>Ident</th>
+        <th>Vorname</th>
+        <th>Nachname</th>
+        <th>Geburtsdatum</th>
+      </tr>
+      </thead>
+
+      <tbody>
+      <template v-for="(item, index) in employeeList">
+        <tr v-bind:key="index" v-bind:class="[index % 2 == 0 ? 'row-even' : 'row-odd' ]">
+          <td>
+            <router-link class="hint-tile" :to="{ path: '/details/'+item.employeeId.value }">
+              {{item.lastName.value}}, {{item.firstName.value}} ({{item.employeeId.value}})
+            </router-link>
+          </td>
+          <td>{{item.firstName.value}}</td>
+          <td>{{item.lastName.value}}</td>
+          <td>{{item.dateOfBirth.value}}</td>
+        </tr>
+      </template>
+      </tbody>
+
+      <h1>Employee-count is {{employeeList.length}}</h1>
+
+      <!--
+      <button class="rdp-button" @click="doSomething">Do Something</button>
+      -->
+
+    </table>
+
+    <!--
+    <div class="rdp-weeknavbar">
+      <button class="rdp-button" @click="weekOffset -= 1">&lt</button>
+      <button class="rdp-button" @click="weekOffset = 0">heute</button>
+      <button class="rdp-button" @click="weekOffset += 1">&gt</button>
+    </div>
+
+    <div class="rdp-weekinfo">
+      <strong>KW {{info.kw}}</strong> vom <strong>{{info.von}}</strong> bis <strong>{{info.bis}}</strong>
+      <span> / </span>
+      <strong>{{info.name}}</strong>
+    </div>
+
+    <rdp-plan :week-offset="weekOffset"></rdp-plan>
+    -->
+
+  </div>
+</template>
+
+<script>
+  import EMPAPI from '../api/emp-api'
+
+  export default {
+    name: 'list',
+
+    components: {
+    },
+
+    created: function () {
+      this.loadList()
+    },
+
+    data () {
+      return {
+        loggedIn: true,
+        employeeList: {}
+      }
+    },
+
+    methods: {
+      loadList: function () {
+        EMPAPI.debug('load employee list')
+        EMPAPI.loadEmployeeList()
+          .done(response => (this.employeeList = response))
+          .fail(() => this.$router.push('/login'))
+      },
+      doSomething: function () {
+        EMPAPI.debug('list contains ' + this.employeeList.length + ' items')
+      }
+    }
+  }
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+</style>

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/login.vue
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/login.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/login.vue
new file mode 100644
index 0000000..6502402
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/login.vue
@@ -0,0 +1,79 @@
+<!--
+      Licensed to the Apache Software Foundation (ASF) under one or more
+      contributor license agreements. See the NOTICE file distributed with
+      this work for additional information regarding copyright ownership.
+      The ASF licenses this file to You under the Apache License, Version
+      2.0 (the "License"); you may not use this file except in compliance
+      with the License. You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+      applicable law or agreed to in writing, software distributed under the
+      License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+      CONDITIONS OF ANY KIND, either express or implied. See the License for
+      the specific language governing permissions and limitations under the
+      License.
+  -->
+<template>
+  <div class="emp-content">
+
+    <form id="loginForm" name="loginForm" enctype="application/x-www-form-urlencoded" @submit.prevent="login">
+    <p>Hint: enter any non null username and password.</p>
+    <div class="formPanel">
+      <table class="inputForm">
+        <tr class="formButtonRow">
+          <td class="eCtlLabel"><label for="inputUsername">User name</label>:</td>
+          <td class="eCtlInput"><input id="inputUsername" name="username" type="text" v-model="username" tabindex="1" /></td>
+        </tr>
+        <tr class="formButtonRow">
+          <td class="eCtlLabel"><label for="inputPassword">Password</label>:</td>
+          <td class="eCtlInput"><input id="inputPassword" type="password" placeholder="Password" v-model="password" tabindex="2" />
+          </td>
+        </tr>
+        <tr class="formButtonRow">
+          <td></td>
+          <td class="buttonBar" colspan="3">
+            <button type="submit" class="rdp-button btn btn-primary">Login</button>
+          </td>
+        </tr>
+      </table>
+    </div>
+    </form>
+
+  </div>
+</template>
+
+<script>
+  import EMPAPI from '../api/emp-api'
+
+  const defaultUsr = process.env.EMP_DEFAULT_USER
+  const defaultPwd = process.env.EMP_DEFAULT_PWD
+
+  export default {
+    name: 'login',
+
+    data () {
+      return {
+        username: defaultUsr,
+        password: defaultPwd
+      }
+    },
+
+    methods: {
+      login: function () {
+        EMPAPI.login(this.username, this.password)
+          .done(() => this.$parent.onLoginComplete())
+          .fail(function (response) {
+            var msg = 'Der Dienst ist zur Zeit nicht verfügbar.'
+            if (response.responseJSON) {
+              msg = response.responseJSON.error
+            }
+            alert(msg)
+          })
+      }
+    }
+  }
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+</style>

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/vue/src/router/index.js
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/router/index.js b/empire-db-examples/empire-db-example-vue/src/main/vue/src/router/index.js
new file mode 100644
index 0000000..6c1c3e4
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/router/index.js
@@ -0,0 +1,47 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+import Vue from 'vue'
+import Router from 'vue-router'
+import login from '@/pages/login'
+import list from '@/pages/list'
+import details from '@/pages/details'
+
+Vue.use(Router)
+
+export default new Router({
+  routes: [
+    {
+      path: '/login',
+      name: 'Login',
+      component: login
+    },
+    {
+      path: '/list',
+      name: 'List',
+      component: list
+    },
+    {
+      path: '/details/:employeeId',
+      name: 'Details',
+      component: details
+    },
+    {
+      path: '*',
+      redirect: '/login'
+    }
+  ]
+})

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/webapp/WEB-INF/web.xml b/empire-db-examples/empire-db-example-vue/src/main/webapp/WEB-INF/web.xml
index cfb49fe..91670f0 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/webapp/WEB-INF/web.xml
+++ b/empire-db-examples/empire-db-example-vue/src/main/webapp/WEB-INF/web.xml
@@ -16,7 +16,7 @@
 	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 	
 	<servlet>
-		<servlet-name>Jersey Web Application</servlet-name>
+		<servlet-name>EmployeeServiceServlet</servlet-name>
 		<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
 		<init-param>
 			<param-name>jersey.config.server.provider.packages</param-name>
@@ -26,13 +26,15 @@
 	</servlet>
 	
 	<servlet-mapping>
-		<servlet-name>Jersey Web Application</servlet-name>
-		<url-pattern>/ws/*</url-pattern>
+		<servlet-name>EmployeeServiceServlet</servlet-name>
+		<url-pattern>/api/*</url-pattern>
 	</servlet-mapping>
 
+	<!-- 
 	<welcome-file-list>
 		<welcome-file>index.html</welcome-file>
 	</welcome-file-list>
+	 -->
 	
 	<listener>
 		<listener-class>org.apache.empire.rest.service.listener.AppListener</listener-class>

http://git-wip-us.apache.org/repos/asf/empire-db/blob/f6e918ff/empire-db-examples/empire-db-example-vue/src/main/webapp/index.html
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/webapp/index.html b/empire-db-examples/empire-db-example-vue/src/main/webapp/index.html
index ee9eb10..ed01fba 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/webapp/index.html
+++ b/empire-db-examples/empire-db-example-vue/src/main/webapp/index.html
@@ -19,13 +19,17 @@
 <!DOCTYPE html>
 <html>
 <head>
-  <title></title>
+  <title>Employee-Rest-Sevice</title>
   <!-- <script src="js/jquery-3.2.1.min.js"></script> -->
   <!-- <script src="https://unpkg.com/vue"></script>  -->
-  <script src="components/einput/einput.js"></script>
+  <!-- <script src="components/einput/einput.js"></script> -->
 </head>
 <body>
 
+
+	<h1>Should not come here!</h1>
+
+  <!-- 
   <div id="app">
 
 	<table>
@@ -50,8 +54,10 @@
 	</table>
 	
   </div>
+   -->
 
-  <script src="js/app.js"></script>
+  <!--  script src="js/app.js"  -->
+  
 
 </body>
 </html>
\ No newline at end of file