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/27 10:10:38 UTC

[1/2] empire-db git commit: EMPIREDB-271 Vue project improvement

Repository: empire-db
Updated Branches:
  refs/heads/master 79b5e5790 -> 878e45c20


http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/db/SampleDB.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/db/SampleDB.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/db/SampleDB.java
deleted file mode 100644
index 735d323..0000000
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/db/SampleDB.java
+++ /dev/null
@@ -1,156 +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.db;
-
-import org.apache.empire.commons.Options;
-import org.apache.empire.data.DataMode;
-import org.apache.empire.data.DataType;
-import org.apache.empire.db.DBColumn;
-import org.apache.empire.db.DBDatabase;
-import org.apache.empire.db.DBTableColumn;
-
-public class SampleDB extends DBDatabase
-{
-    private final static long       serialVersionUID = 1L;
-
-    // Declare all Tables
-    public final TDepartments       T_DEPARTMENTS    = new TDepartments(this);
-    public final TEmployees         T_EMPLOYEES      = new TEmployees(this);
-
-    /**
-     * Constructor SampleDB
-     */
-    public SampleDB()
-    {
-        // Define Foreign-Key Relations
-        addRelation(T_EMPLOYEES.DEPARTMENT_ID.referenceOn(T_DEPARTMENTS.DEPARTMENT_ID));
-    }
-
-    // Needed for the DBELResolver
-    @Override
-    protected void register(String id)
-    {
-        super.register("db");
-    }
-
-    /**
-     * This class represents the definition of the Departments table.
-     */
-    public static class TDepartments extends SampleTable
-    {
-        private static final long  serialVersionUID = 1L;
-
-        public final DBTableColumn DEPARTMENT_ID;
-        public final DBTableColumn NAME;
-        public final DBTableColumn HEAD;
-        public final DBTableColumn BUSINESS_UNIT;
-        public final DBTableColumn UPDATE_TIMESTAMP;
-
-        public TDepartments(DBDatabase db)
-        {
-            super("DEPARTMENTS", db);
-            // ID
-            DEPARTMENT_ID 	= addColumn("DEPARTMENT_ID", 	DataType.AUTOINC,	 0, DataMode.NotNull, "DEP_ID_SEQUENCE");
-            NAME 			= addColumn("NAME", 			DataType.TEXT, 		80, DataMode.NotNull);
-            HEAD 			= addColumn("HEAD", 			DataType.TEXT, 		80, DataMode.Nullable);
-            BUSINESS_UNIT 	= addColumn("BUSINESS_UNIT", 	DataType.TEXT,		 4, DataMode.NotNull, "ITTK");
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,	 0, DataMode.NotNull);
-
-            // Primary Key
-            setPrimaryKey(DEPARTMENT_ID);
-            // Set other Indexes
-            addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
-
-        }
-    }
-
-  
-
-    /**
-     * This class represents the definition of the Employees table.
-     */
-    public static class TEmployees extends SampleTable
-    {
-        private static final long  serialVersionUID = 1L;
-
-        public final DBTableColumn EMPLOYEE_ID;
-        public final DBTableColumn SALUTATION;
-//      public final DBTableColumn PICTURE;
-        public final DBTableColumn FIRST_NAME;
-        public final DBTableColumn LAST_NAME;
-        public final DBTableColumn DATE_OF_BIRTH;
-        public final DBTableColumn DEPARTMENT_ID;
-        public final DBTableColumn GENDER;
-        public final DBTableColumn PHONE_NUMBER;
-        public final DBTableColumn EMAIL;
-        public final DBTableColumn RETIRED;
-        public final DBTableColumn UPDATE_TIMESTAMP;
-        public TEmployees(DBDatabase db)
-        {
-            super("EMPLOYEES", db);
-            // ID
-            EMPLOYEE_ID 	= addColumn("EMPLOYEE_ID", 		DataType.AUTOINC, 	 0, DataMode.NotNull, "EMPLOYEE_ID_SEQUENCE");
-            SALUTATION 		= addColumn("SALUTATION", 		DataType.TEXT, 		 5, DataMode.Nullable);
-            FIRST_NAME 		= addColumn("FIRST_NAME", 		DataType.TEXT, 		40, DataMode.NotNull);
-            LAST_NAME 		= addColumn("LAST_NAME", 		DataType.TEXT, 		40, DataMode.NotNull);
-            DATE_OF_BIRTH 	= addColumn("DATE_OF_BIRTH", 	DataType.DATE,		 0, DataMode.Nullable);
-            DEPARTMENT_ID 	= addColumn("DEPARTMENT_ID", 	DataType.INTEGER, 	 0, DataMode.NotNull);
-            GENDER 			= addColumn("GENDER", 			DataType.TEXT, 		 1, DataMode.Nullable);
-            PHONE_NUMBER 	= addColumn("PHONE_NUMBER", 	DataType.TEXT, 		40, DataMode.Nullable);
-            EMAIL 			= addColumn("EMAIL", 			DataType.TEXT, 		80, DataMode.Nullable);
-            RETIRED			= addColumn("RETIRED", 			DataType.BOOL, 		 0, DataMode.NotNull, false);
-            // PICTURE 		= addColumn("PICTURE", 			DataType.BLOB, 		 0, DataMode.Nullable);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,	 0, DataMode.NotNull);
-
-            // Primary Key
-            setPrimaryKey(EMPLOYEE_ID);
-            // Set other Indexes
-            addIndex("PERSON_NAME_IDX", true, new DBColumn[] { FIRST_NAME, LAST_NAME, DATE_OF_BIRTH });
-
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
-
-            // Create Options for GENDER column
-            Options genders = new Options();
-            genders.set("M", "!option.employee.gender.male");
-            genders.set("F", "!option.employee.gender.female");
-            GENDER.setOptions(genders);
-            GENDER.setControlType("select");
-
-            Options retired = new Options();
-            retired.set(false, "!option.employee.active");
-            retired.set(true,  "!option.employee.retired");
-            RETIRED.setOptions(retired);
-            RETIRED.setControlType("checkbox");
-            
-            // Set special control types
-            DEPARTMENT_ID.setControlType("select");
-            PHONE_NUMBER .setControlType("phone");
-            
-            // Set optional formatting attributes
-            DATE_OF_BIRTH.setAttribute("format:date", "yyyy-MM-dd");
-            
-            // PICTURE.setControlType("blob");
-
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/db/SampleTable.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/db/SampleTable.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/db/SampleTable.java
deleted file mode 100644
index 353bf75..0000000
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vuesample/model/db/SampleTable.java
+++ /dev/null
@@ -1,81 +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.db;
-
-import java.util.Locale;
-
-import org.apache.empire.data.DataType;
-import org.apache.empire.db.DBDatabase;
-import org.apache.empire.db.DBTable;
-import org.apache.empire.db.DBTableColumn;
-
-/**
- * Base class definition for all database tables Automatically generates a message-key for the field title e.g. for the column
- * EMPLOYEES.DATE_OF_BIRTH it generates the key "!field.title.employees.dateOfBirth";
- */
-public class SampleTable extends DBTable
-{
-    private final static long serialVersionUID   = 1L;
-    public final String       MESSAGE_KEY_PREFIX = "!field.title.";
-
-    public SampleTable(String name, DBDatabase db)
-    {
-        super(name, db);
-    }
-
-    @Override
-    protected void addColumn(DBTableColumn column)
-    {
-        // Set Translation Title
-        String col = column.getBeanPropertyName();
-        String tbl = getName().toLowerCase();
-        String key = MESSAGE_KEY_PREFIX + tbl + "." + col;
-        column.setTitle(key);
-
-        // Set Default Control Type
-        DataType type = column.getDataType();
-        column.setControlType((type == DataType.BOOL) ? "checkbox" : "text");
-
-        // Add Column
-        super.addColumn(column);
-    }
-
-    public enum LanguageIndex {
-        DE(Locale.GERMAN),
-
-        EN(Locale.ENGLISH);
-
-        private final Locale locale;
-
-        private LanguageIndex(Locale locale)
-        {
-            this.locale = locale;
-        }
-
-        public Locale getLocale()
-        {
-            return this.locale;
-        }
-
-        public String getDBLangKey()
-        {
-            return this.name().toUpperCase();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/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
index 0a3a441..147da75 100644
--- 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
@@ -93,6 +93,7 @@ div.formPanel {
 }
 table.inputForm {
 	width: 100%;
+  table-layout: fixed;
 }
 table.inputForm td.eCtlLabel {
 	vertical-align:top;
@@ -176,6 +177,11 @@ span.eInpDis {
 	padding-left: 4px;
 	font-style: bold;
 }
+.eInpWrap {
+}
+.eInput {
+  width: 100%;
+}
 .eInputHint {
 	padding-left: 4px;
 	font-style: italic;

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue
index 3ef9caa..fadc680 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue
@@ -14,7 +14,21 @@
       License.
   -->
 <template>
-  <input :id="'CTL_' + column" name="FIRST_NAME" class="eInput eTypeText" lang="en" type="text" maxlength="40" :value="data[column.property]" @input="updateValue($event)">
+  <div class="eInpWrap">
+    <template v-if="column.options">
+      <select :id="'CTL_' + column.name" :name="column.name" class="eInput eTypeSelect" @change="updateValue($event)">
+        <template v-if="column.required === false && column.options[''] === undefined">
+          <option value="" :selected="inputValue === null"></option>
+        </template>
+        <template v-for="(value, key) in column.options">
+          <option :value="key" :selected="inputValue === key">{{value}}</option>
+        </template>
+      </select>
+    </template>
+    <template v-else>
+      <input :id="'CTL_' + column.name" :name="column.name" class="eInput eTypeText" lang="en" type="text" :maxlength="column.maxLength" :value="inputValue" @input="updateValue($event)">
+    </template>
+  </div>
 </template>
 <script>
   import EMPAPI from '../api/emp-api'
@@ -32,6 +46,12 @@
       }
     },
 
+    computed: {
+      inputValue: function () {
+        return this.data[this.column.property]
+      }
+    },
+
     created: function () {
       // alert('column=' + this.column.name + ' is ' + this.data[this.column.property])
     },

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-value.vue
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-value.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-value.vue
new file mode 100644
index 0000000..9ecb56e
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-value.vue
@@ -0,0 +1,40 @@
+<!--
+      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.
+  -->
+<script>
+  // import $ from 'jquery'
+  export default {
+    functional: true,
+    name: 'e-value',
+
+    props: {
+      column: {
+        required: true
+      },
+      data: {
+        required: true
+      }
+    },
+    render (createElement, context) {
+      var value = context.props.data[context.props.column.property]
+      if (context.props.column.options) {
+        value = context.props.column.options[value]
+      }
+      const text = createElement('span', null, value)
+      return text
+    }
+
+  }
+</script>

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue
index 81abf23..616e0d2 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue
@@ -18,25 +18,25 @@
 
     <h1>Employee-Details for {{employeeId}}</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>
-    -->
+    <table class="inputForm" v-if="record" style="width:400px">
+      <colgroup>
+        <col width="120px"/>
+        <col/>
+      </colgroup>
+      <tr><e-control :data="record.data" :column="record.meta.salutation" /></tr>
+      <tr><e-control :data="record.data" :column="record.meta.firstName" /></tr>
+      <tr><e-control :data="record.data" :column="record.meta.lastName" /></tr>
+      <tr><e-control :data="record.data" :column="record.meta.dateOfBirth" format="[yyyy-MM-dd]"/></tr>
+      <tr><e-control :data="record.data" :column="record.meta.departmentId" /></tr>
+      <tr><e-control :data="record.data" :column="record.meta.gender"   /> </tr>
+      <tr><e-control :data="record.data" :column="record.meta.phoneNumber" /></tr>
+      <tr><e-control :data="record.data" :column="record.meta.email" /></tr>
+      <tr><e-control :data="record.data" :column="record.meta.retired" /></tr>
+    </table>
 
     <div class="rdp-weeknavbar">
       <button class="rdp-button" @click="showList($event)">Back</button>
+      <button @click="saveChanges($event)">Save</button>
     </div>
 
   </div>
@@ -44,11 +44,13 @@
 
 <script>
   import EMPAPI from '../api/emp-api'
+  import eControl from '../components/e-control.vue'
 
   export default {
     name: 'details',
 
     components: {
+      eControl
     },
 
     data () {
@@ -77,6 +79,14 @@
           .fail(() => this.$router.push('/login'))
         */
       },
+      saveChanges: function (event) {
+        EMPAPI.debug('load employee record')
+        EMPAPI.updateEmployee(this.record.data)
+          .done(response => (this.setResult(response)))
+      },
+      setResult (result) {
+        alert('Save OK!')
+      },
       showList: function (event) {
         this.$router.push('/employeeList')
       }

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue
index aa1300f..03f4098 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue
+++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue
@@ -30,10 +30,8 @@
         <e-control :column="filter.meta.lastName"  :data="filter.data"/>
       </tr>
       <tr>
-        <td class="eCtlLabel"><label class="eLabel" for="DEPARTMENT_ID">Department:</label></td>
-        <td class="eCtlInput"><select name="DEPARTMENT_ID" class="eInput eTypeNumber" id="DEPARTMENT_ID" size="1">	<option selected="selected" value=""></option>	<option value="1">Procurement</option>	<option value="2">Development</option>	<option value="3">Sales</option></select></td>
-        <td class="eCtlLabel"><label class="eLabel" for="GENDER">Gender:</label></td>
-        <td class="eCtlInput"><select name="GENDER" class="eInput eTypeText" id="GENDER" size="1">	<option selected="selected" value=""></option>	<option value="M">Male</option>	<option value="F">Female</option></select></td>
+        <e-control :column="filter.meta.departmentId" :data="filter.data"/>
+        <e-control :column="filter.meta.gender"  :data="filter.data"/>
       </tr>
       <tr>
         <td class="eCtlLabel"><label class="eLabel" for="DEPARTMENT_ID">Info:</label></td>
@@ -87,9 +85,9 @@
               </router-link>
             </td>
             <td>{{item.department}}</td>
-            <td>{{item.gender}}</td>
-            <td>{{item.dateOfBirth}}</td>
-            <td>?</td>
+            <td><e-value :column="employeeList.meta.gender" :data="item"/></td>
+            <td><e-value :column="employeeList.meta.dateOfBirth" :data="item"/></td>
+            <td><e-value :column="employeeList.meta.retired" :data="item"/></td>
           </tr>
         </template>
         </tbody>
@@ -121,14 +119,18 @@
   import EMPAPI from '../api/emp-api'
   import eControl from '../components/e-control.vue'
   import eInput from '../components/e-input'
+//  import eLabel from '../components/e-label'
+  import eValue from '../components/e-value'
   import $ from 'jquery'
 
   export default {
     name: 'list',
 
     components: {
+      eControl,
       eInput,
-      eControl
+//    eLabel,
+      eValue
     },
 
     data () {

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/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 91670f0..496889c 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
@@ -37,7 +37,7 @@
 	 -->
 	
 	<listener>
-		<listener-class>org.apache.empire.rest.service.listener.AppListener</listener-class>
+		<listener-class>org.apache.empire.rest.app.SampleServiceApp$ContextListener</listener-class>
 	</listener>
 
 </web-app>
\ No newline at end of file


[2/2] empire-db git commit: EMPIREDB-271 Vue project improvement

Posted by do...@apache.org.
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/878e45c2
Tree: http://git-wip-us.apache.org/repos/asf/empire-db/tree/878e45c2
Diff: http://git-wip-us.apache.org/repos/asf/empire-db/diff/878e45c2

Branch: refs/heads/master
Commit: 878e45c204adb47d6e8a726854e1c471d2e2f9f7
Parents: 79b5e57
Author: Rainer Döbele <do...@apache.org>
Authored: Thu Sep 27 12:10:32 2018 +0200
Committer: Rainer Döbele <do...@apache.org>
Committed: Thu Sep 27 12:10:32 2018 +0200

----------------------------------------------------------------------
 .../apache/empire/rest/app/EmployeeVueApp.java  | 267 -----------------
 .../empire/rest/app/ResourceTextResolver.java   |   4 +
 .../empire/rest/app/SampleServiceApp.java       | 286 +++++++++++++++++++
 .../apache/empire/rest/json/ColumnMetaData.java |  80 ------
 .../apache/empire/rest/json/EmployeeData.java   |  65 -----
 .../empire/rest/json/EmployeeSearchFilter.java  |  82 ------
 .../apache/empire/rest/json/JsoColumnMeta.java  | 101 +++++++
 .../apache/empire/rest/json/JsoRecordData.java  | 177 ++++++++++++
 .../empire/rest/json/JsoResultWithMeta.java     |  59 ++++
 .../apache/empire/rest/json/ResultWithMeta.java |  48 ----
 .../empire/rest/service/EmployeeService.java    | 121 ++++----
 .../org/apache/empire/rest/service/Service.java |  32 ++-
 .../service/filter/ServiceRequestFilter.java    |   4 +-
 .../rest/service/listener/AppListener.java      |  48 ----
 .../empire/vue/sample/db/RecordContext.java     |   8 +
 .../apache/empire/vue/sample/db/SampleDB.java   | 156 ++++++++++
 .../empire/vue/sample/db/SampleTable.java       |  81 ++++++
 .../vue/sample/db/records/DepartmentRecord.java |  34 +++
 .../vue/sample/db/records/EmployeeRecord.java   |  77 +++++
 .../vue/sample/db/records/SampleRecord.java     | 139 +++++++++
 .../empire/vuesample/model/db/SampleDB.java     | 156 ----------
 .../empire/vuesample/model/db/SampleTable.java  |  81 ------
 .../src/main/vue/src/assets/css/layout.css      |   6 +
 .../src/main/vue/src/components/e-input.vue     |  22 +-
 .../src/main/vue/src/components/e-value.vue     |  40 +++
 .../src/main/vue/src/pages/employeeDetail.vue   |  42 +--
 .../src/main/vue/src/pages/employeeList.vue     |  18 +-
 .../src/main/webapp/WEB-INF/web.xml             |   2 +-
 28 files changed, 1324 insertions(+), 912 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/EmployeeVueApp.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/EmployeeVueApp.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/EmployeeVueApp.java
deleted file mode 100644
index adb4e69..0000000
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/EmployeeVueApp.java
+++ /dev/null
@@ -1,267 +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.rest.app;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-import javax.servlet.ServletContext;
-
-import org.apache.empire.commons.StringUtils;
-import org.apache.empire.db.DBCommand;
-import org.apache.empire.db.DBDatabase;
-import org.apache.empire.db.DBDatabaseDriver;
-import org.apache.empire.db.DBRecord;
-import org.apache.empire.db.DBSQLScript;
-import org.apache.empire.db.exceptions.QueryFailedException;
-import org.apache.empire.db.hsql.DBDatabaseDriverHSql;
-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;
-import org.apache.log4j.PatternLayout;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EmployeeVueApp
-{
-    private static final Logger log = LoggerFactory.getLogger(EmployeeVueApp.class);
-    
-    private static Map<Locale, ResourceTextResolver> textResolverMap = new HashMap<Locale, ResourceTextResolver>();
-    
-    private static EmployeeVueApp app;
-    
-    public static EmployeeVueApp instance()
-    {
-        return app;
-    }
-    
-    public static EmployeeVueApp create(ServletContext ctx)
-    {
-        if (app!=null)
-            throw new RuntimeException("Application already exists");
-        app = new EmployeeVueApp(ctx);
-        return app;
-    }
-    
-    protected EmployeeVueApp(ServletContext ctx) 
-    {
-        // Logging
-        initLogging();
-        
-        String messageBundle ="lang.messages";
-        textResolverMap.put(Locale.ENGLISH, new ResourceTextResolver(ResourceBundle.getBundle(messageBundle, Locale.ENGLISH)));
-        textResolverMap.put(Locale.GERMAN,  new ResourceTextResolver(ResourceBundle.getBundle(messageBundle, Locale.GERMAN)));
-        
-        // get connection
-        Connection conn = getJDBCConnection(ctx);
-
-        // DB
-        SampleDB db = initDatabase(ctx);
-        DBDatabaseDriver driver = new DBDatabaseDriverHSql();
-        db.open(driver, conn);
-
-        // Add to context
-        ctx.setAttribute(Service.Consts.ATTRIBUTE_DB, db);
-        // sce.getServletContext().setAttribute(MobileImportServiceConsts.ATTRIBUTE_DATASOURCE, ds);
-        // sce.getServletContext().setAttribute(MobileImportServiceConsts.ATTRIBUTE_CONFIG, config);
-        
-    }
-    
-    public TextResolver getTextResolver(Locale locale) {
-        TextResolver tr = textResolverMap.get(locale);
-        return (tr!=null ? tr : textResolverMap.get(Locale.ENGLISH));
-    }
-    
-    public Connection getJDBCConnection(ServletContext appContext) {
-        // Establish a new database connection
-        Connection conn = null;
-
-        String jdbcURL = "jdbc:hsqldb:file:hsqldb/sample;shutdown=true";
-        String jdbcUser = "sa";
-        String jdbcPwd = "";
-
-        if (jdbcURL.indexOf("file:") > 0) {
-            jdbcURL = StringUtils.replace(jdbcURL, "file:", "file:" + appContext.getRealPath("/"));
-        }
-        // Connect
-        log.info("Connecting to Database'" + jdbcURL + "' / User=" + jdbcUser);
-        try { // Connect to the databse
-            Class.forName("org.hsqldb.jdbcDriver").newInstance();
-            conn = DriverManager.getConnection(jdbcURL, jdbcUser, jdbcPwd);
-            log.info("Connected successfully");
-            // set the AutoCommit to false this session. You must commit
-            // explicitly now
-            conn.setAutoCommit(false);
-            log.info("AutoCommit is " + conn.getAutoCommit());
-
-        } catch (Exception e) {
-            log.error("Failed to connect directly to '" + jdbcURL + "' / User=" + jdbcUser);
-            log.error(e.toString());
-            throw new RuntimeException(e);
-        }
-        return conn;
-    }
-
-    protected void releaseConnection(DBDatabase db, Connection conn, boolean commit) {
-        // release connection
-        if (conn == null) {
-            return;
-        }
-        // Commit or rollback connection depending on the exit code
-        if (commit) { // success: commit all changes
-            db.commit(conn);
-            log.debug("REQUEST {}: commited.");
-        } else { // failure: rollback all changes
-            db.rollback(conn);
-            log.debug("REQUEST {}: rolled back.");
-        }
-    }
-    
-    
-    // ********************* private ********************* 
-
-    private SampleDB initDatabase(ServletContext ctx) {
-        SampleDB db = new SampleDB();
-
-        // Open Database (and create if not existing)
-        DBDatabaseDriver driver = new DBDatabaseDriverHSql();
-        log.info("Opening database '{}' using driver '{}'", db.getClass().getSimpleName(), driver.getClass().getSimpleName());
-        Connection conn = null;
-        try {
-            conn = getJDBCConnection(ctx);
-            db.open(driver, conn);
-            if (!databaseExists(db, conn)) {
-                // STEP 4: Create Database
-                log.info("Creating database {}", db.getClass().getSimpleName());
-                createSampleDatabase(db, driver, conn);
-            }
-        } finally {
-            releaseConnection(db, conn, true);
-        }
-
-        return db;
-    }
-
-    private static boolean databaseExists(SampleDB db, Connection conn) {
-        // Check wether DB exists
-        DBCommand cmd = db.createCommand();
-        cmd.select(db.T_DEPARTMENTS.count());
-        try {
-            return (db.querySingleInt(cmd, -1, conn) >= 0);
-        } catch (QueryFailedException e) {
-            return false;
-        }
-    }
-
-    private static void createSampleDatabase(SampleDB db, DBDatabaseDriver driver, Connection conn) {
-        // create DLL for Database Definition
-        DBSQLScript script = new DBSQLScript();
-        db.getCreateDDLScript(driver, script);
-        // Show DLL Statements
-        System.out.println(script.toString());
-        // Execute Script
-        script.executeAll(driver, conn, false);
-        db.commit(conn);
-        // Open again
-        if (!db.isOpen()) {
-            db.open(driver, conn);
-        }
-        // Insert Sample Departments
-        insertDepartmentSampleRecord(db, conn, "Procurement", "ITTK");
-        int idDevDep = insertDepartmentSampleRecord(db, conn, "Development", "ITTK");
-        int idSalDep = insertDepartmentSampleRecord(db, conn, "Sales", "ITTK");
-        // Insert Sample Employees
-        insertEmployeeSampleRecord(db, conn, "Mr.", "Eugen", "Miller", "M", idDevDep);
-        insertEmployeeSampleRecord(db, conn, "Mr.", "Max", "Mc. Callahan", "M", idDevDep);
-        insertEmployeeSampleRecord(db, conn, "Mrs.", "Anna", "Smith", "F", idSalDep);
-        // Commit
-        db.commit(conn);
-    }
-
-    private static int insertDepartmentSampleRecord(SampleDB db, Connection conn, String department_name, String businessUnit) {
-        // Insert a Department
-        DBRecord rec = new DBRecord();
-        rec.create(db.T_DEPARTMENTS);
-        rec.setValue(db.T_DEPARTMENTS.NAME, department_name);
-        rec.setValue(db.T_DEPARTMENTS.BUSINESS_UNIT, businessUnit);
-        try {
-            rec.update(conn);
-        } catch (Exception e) {
-            log.error(e.getLocalizedMessage());
-            return 0;
-        }
-        // Return Department ID
-        return rec.getInt(db.T_DEPARTMENTS.DEPARTMENT_ID);
-    }
-
-    /*
-     * Insert a person
-     */
-    private static int insertEmployeeSampleRecord(SampleDB db, Connection conn, String salutation, String firstName, String lastName, String gender, int depID) {
-        // Insert an Employee
-        DBRecord rec = new DBRecord();
-        rec.create(db.T_EMPLOYEES);
-        rec.setValue(db.T_EMPLOYEES.SALUTATION, salutation);
-        rec.setValue(db.T_EMPLOYEES.FIRST_NAME, firstName);
-        rec.setValue(db.T_EMPLOYEES.LAST_NAME, lastName);
-        rec.setValue(db.T_EMPLOYEES.GENDER, gender);
-        rec.setValue(db.T_EMPLOYEES.DEPARTMENT_ID, depID);
-        try {
-            rec.update(conn);
-        } catch (Exception e) {
-            log.error(e.getLocalizedMessage());
-            return 0;
-        }
-        // Return Employee ID
-        return rec.getInt(db.T_EMPLOYEES.EMPLOYEE_ID);
-    }
-
-    private void initLogging() {
-
-        // Init Logging
-        ConsoleAppender consoleAppender = new ConsoleAppender();
-        String pattern = "%-5p [%d{yyyy/MM/dd HH:mm}]: %m at %l %n";
-        consoleAppender.setLayout(new PatternLayout(pattern));
-        consoleAppender.activateOptions();
-
-        org.apache.log4j.Logger.getRootLogger().addAppender(consoleAppender);
-        org.apache.log4j.Logger.getRootLogger().setLevel(Level.ALL);
-
-        Level loglevel = Level.DEBUG;
-        log.info("Setting LogLevel to {}", loglevel);
-
-        // RootLogger
-        org.apache.log4j.Logger.getRootLogger().setLevel(Level.INFO);
-
-        // Empire-db Logs
-        org.apache.log4j.Logger empireLog = org.apache.log4j.Logger.getLogger("org.apache.empire.db.DBDatabase");
-        empireLog.setLevel(loglevel);
-
-        // Vue.js Sample
-        org.apache.log4j.Logger miLog = org.apache.log4j.Logger.getLogger("org.apache.empire.rest");
-        miLog.setLevel(loglevel);
-
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/ResourceTextResolver.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/ResourceTextResolver.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/ResourceTextResolver.java
index a53403d..526a016 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/ResourceTextResolver.java
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/ResourceTextResolver.java
@@ -44,11 +44,13 @@ public class ResourceTextResolver implements TextResolver
         return resBundle;
     }
     
+    @Override
     public final Locale getLocale()
     {
         return resBundle.getLocale();
     }
 
+    @Override
     public String resolveKey(String key)
     {
         try
@@ -70,6 +72,7 @@ public class ResourceTextResolver implements TextResolver
         }
     }
     
+    @Override
     public String resolveText(String text)
     {
         // Translate
@@ -81,6 +84,7 @@ public class ResourceTextResolver implements TextResolver
         return text;
     }
     
+    @Override
     public String getExceptionMessage(Exception e)
     {
         if (e instanceof EmpireException)

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/SampleServiceApp.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/SampleServiceApp.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/SampleServiceApp.java
new file mode 100644
index 0000000..8a9e1a5
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/app/SampleServiceApp.java
@@ -0,0 +1,286 @@
+/*
+ * 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.rest.app;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.db.DBCommand;
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBDatabaseDriver;
+import org.apache.empire.db.DBRecord;
+import org.apache.empire.db.DBSQLScript;
+import org.apache.empire.db.exceptions.QueryFailedException;
+import org.apache.empire.db.hsql.DBDatabaseDriverHSql;
+import org.apache.empire.rest.service.Service;
+import org.apache.empire.vue.sample.db.SampleDB;
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.PatternLayout;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SampleServiceApp
+{
+    private static final Logger log = LoggerFactory.getLogger(SampleServiceApp.class);
+    
+    /**
+     * Implementation of ServletContextListener which create the SampleServiceApp Singleton
+     * @author doebele
+     */
+    public static class ContextListener implements ServletContextListener {
+    
+        @Override
+        public void contextInitialized(ServletContextEvent sce) {
+    
+            System.out.println("ServletContextListener:contextInitialized");
+            // check singleton
+            if (app!=null)
+                throw new RuntimeException("FATAL: SampleServiceApp already created!");
+            // create application
+            ServletContext ctx = sce.getServletContext();
+            app = new SampleServiceApp(ctx);
+            // done
+            log.debug("SampleServiceApp created sucessfully!");
+        }
+    
+        @Override
+        public void contextDestroyed(ServletContextEvent sce) {
+            System.out.println("ServletContextListener:contextDestroyed");
+        }
+    }
+    
+    private static SampleServiceApp app;
+    
+    public static SampleServiceApp instance()
+    {
+        return app;
+    }
+
+    private Map<Locale, ResourceTextResolver> textResolverMap = new HashMap<Locale, ResourceTextResolver>();
+    
+    protected SampleServiceApp(ServletContext ctx) 
+    {
+        // Logging
+        initLogging();
+        
+        String messageBundle ="lang.messages";
+        textResolverMap.put(Locale.ENGLISH, new ResourceTextResolver(ResourceBundle.getBundle(messageBundle, Locale.ENGLISH)));
+        textResolverMap.put(Locale.GERMAN,  new ResourceTextResolver(ResourceBundle.getBundle(messageBundle, Locale.GERMAN)));
+        
+        // get connection
+        Connection conn = getJDBCConnection(ctx);
+
+        // DB
+        SampleDB db = initDatabase(ctx);
+        DBDatabaseDriver driver = new DBDatabaseDriverHSql();
+        db.open(driver, conn);
+
+        // Add to context
+        ctx.setAttribute(Service.Consts.ATTRIBUTE_DB, db);
+        // sce.getServletContext().setAttribute(MobileImportServiceConsts.ATTRIBUTE_DATASOURCE, ds);
+        // sce.getServletContext().setAttribute(MobileImportServiceConsts.ATTRIBUTE_CONFIG, config);
+        
+    }
+    
+    public TextResolver getTextResolver(Locale locale) {
+        TextResolver tr = textResolverMap.get(locale);
+        return (tr!=null ? tr : textResolverMap.get(Locale.ENGLISH));
+    }
+    
+    public Connection getJDBCConnection(ServletContext appContext) {
+        // Establish a new database connection
+        Connection conn = null;
+
+        String jdbcURL = "jdbc:hsqldb:file:hsqldb/sample;shutdown=true";
+        String jdbcUser = "sa";
+        String jdbcPwd = "";
+
+        if (jdbcURL.indexOf("file:") > 0) {
+            jdbcURL = StringUtils.replace(jdbcURL, "file:", "file:" + appContext.getRealPath("/"));
+        }
+        // Connect
+        log.info("Connecting to Database'" + jdbcURL + "' / User=" + jdbcUser);
+        try { // Connect to the databse
+            Class.forName("org.hsqldb.jdbcDriver").newInstance();
+            conn = DriverManager.getConnection(jdbcURL, jdbcUser, jdbcPwd);
+            log.info("Connected successfully");
+            // set the AutoCommit to false this session. You must commit
+            // explicitly now
+            conn.setAutoCommit(false);
+            log.info("AutoCommit is " + conn.getAutoCommit());
+
+        } catch (Exception e) {
+            log.error("Failed to connect directly to '" + jdbcURL + "' / User=" + jdbcUser);
+            log.error(e.toString());
+            throw new RuntimeException(e);
+        }
+        return conn;
+    }
+
+    protected void releaseConnection(DBDatabase db, Connection conn, boolean commit) {
+        // release connection
+        if (conn == null) {
+            return;
+        }
+        // Commit or rollback connection depending on the exit code
+        if (commit) { // success: commit all changes
+            db.commit(conn);
+            log.debug("REQUEST {}: commited.");
+        } else { // failure: rollback all changes
+            db.rollback(conn);
+            log.debug("REQUEST {}: rolled back.");
+        }
+    }
+    
+    
+    // ********************* private ********************* 
+
+    private SampleDB initDatabase(ServletContext ctx) {
+        SampleDB db = new SampleDB();
+
+        // Open Database (and create if not existing)
+        DBDatabaseDriver driver = new DBDatabaseDriverHSql();
+        log.info("Opening database '{}' using driver '{}'", db.getClass().getSimpleName(), driver.getClass().getSimpleName());
+        Connection conn = null;
+        try {
+            conn = getJDBCConnection(ctx);
+            db.open(driver, conn);
+            if (!databaseExists(db, conn)) {
+                // STEP 4: Create Database
+                log.info("Creating database {}", db.getClass().getSimpleName());
+                createSampleDatabase(db, driver, conn);
+            }
+        } finally {
+            releaseConnection(db, conn, true);
+        }
+
+        return db;
+    }
+
+    private static boolean databaseExists(SampleDB db, Connection conn) {
+        // Check wether DB exists
+        DBCommand cmd = db.createCommand();
+        cmd.select(db.T_DEPARTMENTS.count());
+        try {
+            return (db.querySingleInt(cmd, -1, conn) >= 0);
+        } catch (QueryFailedException e) {
+            return false;
+        }
+    }
+
+    private static void createSampleDatabase(SampleDB db, DBDatabaseDriver driver, Connection conn) {
+        // create DLL for Database Definition
+        DBSQLScript script = new DBSQLScript();
+        db.getCreateDDLScript(driver, script);
+        // Show DLL Statements
+        System.out.println(script.toString());
+        // Execute Script
+        script.executeAll(driver, conn, false);
+        db.commit(conn);
+        // Open again
+        if (!db.isOpen()) {
+            db.open(driver, conn);
+        }
+        // Insert Sample Departments
+        insertDepartmentSampleRecord(db, conn, "Procurement", "ITTK");
+        int idDevDep = insertDepartmentSampleRecord(db, conn, "Development", "ITTK");
+        int idSalDep = insertDepartmentSampleRecord(db, conn, "Sales", "ITTK");
+        // Insert Sample Employees
+        insertEmployeeSampleRecord(db, conn, "Mr.", "Eugen", "Miller", "M", idDevDep);
+        insertEmployeeSampleRecord(db, conn, "Mr.", "Max", "Mc. Callahan", "M", idDevDep);
+        insertEmployeeSampleRecord(db, conn, "Mrs.", "Anna", "Smith", "F", idSalDep);
+        // Commit
+        db.commit(conn);
+    }
+
+    private static int insertDepartmentSampleRecord(SampleDB db, Connection conn, String department_name, String businessUnit) {
+        // Insert a Department
+        DBRecord rec = new DBRecord();
+        rec.create(db.T_DEPARTMENTS);
+        rec.setValue(db.T_DEPARTMENTS.NAME, department_name);
+        rec.setValue(db.T_DEPARTMENTS.BUSINESS_UNIT, businessUnit);
+        try {
+            rec.update(conn);
+        } catch (Exception e) {
+            log.error(e.getLocalizedMessage());
+            return 0;
+        }
+        // Return Department ID
+        return rec.getInt(db.T_DEPARTMENTS.DEPARTMENT_ID);
+    }
+
+    /*
+     * Insert a person
+     */
+    private static int insertEmployeeSampleRecord(SampleDB db, Connection conn, String salutation, String firstName, String lastName, String gender, int depID) {
+        // Insert an Employee
+        DBRecord rec = new DBRecord();
+        rec.create(db.T_EMPLOYEES);
+        rec.setValue(db.T_EMPLOYEES.SALUTATION, salutation);
+        rec.setValue(db.T_EMPLOYEES.FIRST_NAME, firstName);
+        rec.setValue(db.T_EMPLOYEES.LAST_NAME, lastName);
+        rec.setValue(db.T_EMPLOYEES.GENDER, gender);
+        rec.setValue(db.T_EMPLOYEES.DEPARTMENT_ID, depID);
+        try {
+            rec.update(conn);
+        } catch (Exception e) {
+            log.error(e.getLocalizedMessage());
+            return 0;
+        }
+        // Return Employee ID
+        return rec.getInt(db.T_EMPLOYEES.EMPLOYEE_ID);
+    }
+
+    private void initLogging() {
+
+        // Init Logging
+        ConsoleAppender consoleAppender = new ConsoleAppender();
+        String pattern = "%-5p [%d{yyyy/MM/dd HH:mm}]: %m at %l %n";
+        consoleAppender.setLayout(new PatternLayout(pattern));
+        consoleAppender.activateOptions();
+
+        org.apache.log4j.Logger.getRootLogger().addAppender(consoleAppender);
+        org.apache.log4j.Logger.getRootLogger().setLevel(Level.ALL);
+
+        Level loglevel = Level.DEBUG;
+        log.info("Setting LogLevel to {}", loglevel);
+
+        // RootLogger
+        org.apache.log4j.Logger.getRootLogger().setLevel(Level.INFO);
+
+        // Empire-db Logs
+        org.apache.log4j.Logger empireLog = org.apache.log4j.Logger.getLogger("org.apache.empire.db.DBDatabase");
+        empireLog.setLevel(loglevel);
+
+        // Vue.js Sample
+        org.apache.log4j.Logger miLog = org.apache.log4j.Logger.getLogger("org.apache.empire.rest");
+        miLog.setLevel(loglevel);
+
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/ColumnMetaData.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/ColumnMetaData.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/ColumnMetaData.java
deleted file mode 100644
index 6dddbdf..0000000
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/ColumnMetaData.java
+++ /dev/null
@@ -1,80 +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.rest.json;
-
-import org.apache.empire.commons.StringUtils;
-import org.apache.empire.db.DBColumn;
-import org.apache.empire.db.DBColumnExpr;
-import org.apache.empire.rest.app.TextResolver;
-
-public class ColumnMetaData
-{
-    // private static final long serialVersionUID = 1L;
-    private final String      name;
-    private final String      dataType;
-    private final int         length;
-    private final String      property;
-    private final String      title;
-    
-    public ColumnMetaData(DBColumn column, TextResolver resolver)
-    {
-        this.name = column.getName();
-        this.dataType = column.getDataType().name();
-        this.length = (int)column.getSize();
-        this.property = column.getBeanPropertyName();
-        this.title = resolver.resolveText(column.getTitle());
-    }
-    
-    public ColumnMetaData(DBColumnExpr column, TextResolver resolver)
-    {
-        this.name = column.getName();
-        this.dataType = column.getDataType().name();
-        this.length = 0;
-        this.property = column.getBeanPropertyName();
-        String title = column.getTitle();
-        this.title = (StringUtils.isEmpty(title) ? column.getName() : resolver.resolveText(title));
-    }
-
-    public String getName()
-    {
-        return name;
-    }
-
-    public String getDataType()
-    {
-        return dataType;
-    }
-
-    public int getLength()
-    {
-        return length;
-    }
-
-    public String getProperty()
-    {
-        return property;
-    }
-
-    public String getTitle()
-    {
-        return title;
-    }
-    
-    
-}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/EmployeeData.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/EmployeeData.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/EmployeeData.java
deleted file mode 100644
index 83964bc..0000000
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/EmployeeData.java
+++ /dev/null
@@ -1,65 +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.rest.json;
-
-import java.util.LinkedHashMap;
-
-import org.apache.empire.db.DBRecordData;
-
-/*
-public static class MyItemDeserializer extends StdDeserializer<EmployeeFilter> { 
- 
-    public MyItemDeserializer() { 
-        this(null); 
-    } 
- 
-    public MyItemDeserializer(Class<?> vc) { 
-        super(vc); 
-    }
- 
-    @Override
-    public EmployeeFilter deserialize(JsonParser jp, DeserializationContext ctxt) 
-      throws IOException, JsonProcessingException {
-        JsonNode node = jp.getCodec().readTree(jp);
-        // int id = (Integer) ((IntNode) node.get("id")).numberValue();
-        // int userId = (Integer) ((IntNode) node.get("createdBy")).numberValue();
-        String firstname = node.get("firstname").asText();
-        String lastname  = node.get("lastname").asText();
- 
-        return new EmployeeFilter();
-    }
-}*/
-
-// @JsonDeserialize(using = MyItemDeserializer.class)   
-public class EmployeeData extends LinkedHashMap<String, Object>
-{
-    private static final long serialVersionUID = 1L;
-
-    public EmployeeData(DBRecordData rec)
-    {
-        super(rec.getFieldCount());
-        for (int i=0; i<rec.getFieldCount(); i++)
-        {
-            String prop = rec.getColumnExpr(i).getBeanPropertyName();
-            if (prop==null)
-                continue;
-            put(prop, rec.getValue(i));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/EmployeeSearchFilter.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/EmployeeSearchFilter.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/EmployeeSearchFilter.java
deleted file mode 100644
index 2d175fa..0000000
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/EmployeeSearchFilter.java
+++ /dev/null
@@ -1,82 +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.rest.json;
-
-public class EmployeeSearchFilter
-{
-    // private static final long serialVersionUID = 1L;
-
-    private String            employeeId;
-    private String            firstName;
-    private String            lastName;
-    private int               departmentId;
-    private String            gender;
-
-    public EmployeeSearchFilter()
-    {
-    }
-
-    public String getEmployeeId()
-    {
-        return employeeId;
-    }
-
-    public void setEmployeeId(String employeeId)
-    {
-        this.employeeId = employeeId;
-    }
-
-    public int getDepartmentId()
-    {
-        return departmentId;
-    }
-
-    public void setDepartmentId(int departmentId)
-    {
-        this.departmentId = departmentId;
-    }
-
-    public String getFirstName()
-    {
-        return firstName;
-    }
-
-    public void setFirstName(String firstName)
-    {
-        this.firstName = firstName;
-    }
-
-    public String getLastName()
-    {
-        return lastName;
-    }
-
-    public void setLastName(String lastName)
-    {
-        this.lastName = lastName;
-    }
-
-	public String getGender() {
-		return gender;
-	}
-
-	public void setGender(String gender) {
-		this.gender = gender;
-	}
-}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoColumnMeta.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoColumnMeta.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoColumnMeta.java
new file mode 100644
index 0000000..e90ee19
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoColumnMeta.java
@@ -0,0 +1,101 @@
+/*
+ * 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.rest.json;
+
+import java.util.LinkedHashMap;
+
+import org.apache.empire.commons.OptionEntry;
+import org.apache.empire.commons.Options;
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.data.DataType;
+import org.apache.empire.db.DBColumn;
+import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.rest.app.TextResolver;
+
+public class JsoColumnMeta extends LinkedHashMap<String, Object>
+{
+    private static final long serialVersionUID = 1L;
+    
+    public static class JsoOptions extends LinkedHashMap<Object, String>
+    {
+        private static final long serialVersionUID = 1L;
+    
+        private JsoOptions(Options options, TextResolver resolver)
+        {
+            for (OptionEntry oe : options)
+            {
+                Object val = oe.getValue();
+                if (val==null)
+                    val = "";  // Null not allowed, but empty String is!
+                String txt = resolver.resolveText(oe.getText());
+                super.put(val, txt);
+            }
+        }
+    }
+    
+    private static final String _name = "name";
+    private static final String _property = "property";
+    private static final String _dataType = "dataType";
+    private static final String _maxLength = "maxLength";
+    private static final String _required = "required";
+    private static final String _readonly = "readonly";
+    private static final String _title = "title";
+    private static final String _options = "options";
+    
+    public JsoColumnMeta(DBColumn column, TextResolver resolver, Options options, boolean required, boolean readOnly)
+    {
+        put(_name,      column.getName());
+        put(_property,  column.getBeanPropertyName());
+        put(_dataType,  column.getDataType().name());
+        put(_required,  required);
+        put(_readonly,  readOnly);
+        put(_title,     resolver.resolveText(StringUtils.coalesce(column.getTitle(), column.getName())));
+        if (column.getDataType()==DataType.TEXT)
+        {   // add maxLength
+            put(_maxLength, (int)column.getSize());
+        }
+        if (options!=null)
+        {   // add options
+            put(_options, new JsoOptions(options, resolver));
+        }
+    }
+
+    public JsoColumnMeta(DBColumn column, TextResolver resolver)
+    {
+        this(column, resolver, column.getOptions(), column.isRequired(), column.isReadOnly());
+    }
+    
+    public JsoColumnMeta(DBColumnExpr column, TextResolver resolver)
+    {
+        put(_name,      column.getName());
+        put(_property,  column.getBeanPropertyName());
+        put(_dataType,  column.getDataType().name());
+        put(_title,     resolver.resolveText(StringUtils.coalesce(column.getTitle(), column.getName())));
+        if (column.getOptions()!=null)
+        {   // add options
+            put(_options, new JsoOptions(column.getOptions(), resolver));
+        }
+    }
+    
+    public String getProperty()
+    {
+        return String.valueOf(get(_property));
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoRecordData.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoRecordData.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoRecordData.java
new file mode 100644
index 0000000..c46897f
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoRecordData.java
@@ -0,0 +1,177 @@
+/*
+ * 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.rest.json;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.data.Column;
+import org.apache.empire.db.DBRecord;
+import org.apache.empire.db.DBRecordData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import com.fasterxml.jackson.databind.node.BooleanNode;
+import com.fasterxml.jackson.databind.node.DecimalNode;
+import com.fasterxml.jackson.databind.node.IntNode;
+import com.fasterxml.jackson.databind.node.LongNode;
+import com.fasterxml.jackson.databind.node.NullNode;
+import com.fasterxml.jackson.databind.node.NumericNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+
+@JsonDeserialize(using = JsoRecordData.Deserializer.class)   
+public class JsoRecordData extends LinkedHashMap<String, Object>
+{
+    private static final long serialVersionUID = 1L;
+
+    private static final Logger log = LoggerFactory.getLogger(JsoRecordData.class);
+    
+    /**
+     * Deserializer
+     * @author doebele
+     */
+    public static class Deserializer extends StdDeserializer<JsoRecordData> { 
+     
+        private static final long serialVersionUID = 1L;
+    
+        public Deserializer() { 
+            this(null); 
+        } 
+     
+        public Deserializer(Class<?> vc) { 
+            super(vc); 
+        }
+     
+        @Override
+        public JsoRecordData deserialize(JsonParser jp, DeserializationContext ctxt) 
+          throws IOException, JsonProcessingException {
+            // read and parse
+            JsonNode node = jp.getCodec().readTree(jp);
+            return new JsoRecordData(node);
+        }
+    }
+    
+    /**
+     * Serialize to JSON
+     * @param rec
+     */
+    public JsoRecordData(DBRecordData rec)
+    {
+        super(rec.getFieldCount());
+        for (int i=0; i<rec.getFieldCount(); i++)
+        {
+            String prop = rec.getColumnExpr(i).getBeanPropertyName();
+            if (prop==null)
+                continue;
+            put(prop, rec.getValue(i));
+        }
+    }
+
+    public JsoRecordData(DBRecord rec)
+    {
+        this((DBRecordData)rec);
+        // add new flag
+        put("_newRecord", rec.isNew());
+    }
+    
+    public JsoRecordData(JsoColumnMeta[] meta)
+    {
+        super(meta.length);
+        for (int i=0; i<meta.length; i++)
+        {
+            String prop = meta[i].getProperty();
+            put(prop, null);
+        }
+    }
+    
+    /**
+     * Deserialize from JSON
+     * @param node
+     */
+    public JsoRecordData(JsonNode node)
+    {
+        Iterator<String> fields = node.fieldNames();
+        while (fields.hasNext())
+        {   // add all fields
+            String field = fields.next();
+            JsonNode vn = node.get(field);
+            final Object value;
+            if (vn instanceof NullNode)
+                value = null;
+            else if (vn instanceof TextNode)
+                value = vn.textValue();
+            else if (vn instanceof DecimalNode)
+                value = vn.decimalValue();
+            else if (vn instanceof LongNode)
+                value = vn.longValue();
+            else if (vn instanceof IntNode)
+                value = vn.intValue();
+            else if (vn instanceof NumericNode)
+                value = vn.numberValue();
+            else if (vn instanceof NumericNode)
+                value = vn.numberValue();
+            else if (vn instanceof BooleanNode)
+                value = vn.booleanValue();
+            else // default
+            {
+                log.warn("Unknown JSon Node type: {} for {}", vn.getClass().getSimpleName(), field); 
+                value = vn.asText();
+            }
+            // put value
+            put(field, value);
+        }
+    }
+    
+    /**
+     * other methos
+     */
+    public boolean hasValue(Column c)
+    {
+        return this.containsKey(c.getBeanPropertyName());
+    }
+
+    public boolean hasNonNullValue(Column c)
+    {
+        Object val = getValue(c);
+        return !ObjectUtils.isEmpty(val);
+    }
+
+    public Object getValue(Column c)
+    {
+        return this.get(c.getBeanPropertyName());
+    }
+
+    public String getString(Column c)
+    {
+        return String.valueOf(getValue(c));
+    }
+    
+    public boolean isNewRecord()
+    {
+        return ObjectUtils.getBoolean(get("_newRecord"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoResultWithMeta.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoResultWithMeta.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoResultWithMeta.java
new file mode 100644
index 0000000..afbaf8e
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/JsoResultWithMeta.java
@@ -0,0 +1,59 @@
+/*
+ * 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.rest.json;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class JsoResultWithMeta
+{
+    private final Map<String, JsoColumnMeta> meta;
+    private final Object data;
+
+    public JsoResultWithMeta(JsoRecordData record, JsoColumnMeta... columnMeta)
+    {
+        super();
+        this.meta = new LinkedHashMap<String, JsoColumnMeta>(columnMeta.length);
+        for (JsoColumnMeta c : columnMeta) {
+            meta.put(c.getProperty(), c);
+        }
+        this.data = record;
+    }
+    
+    public JsoResultWithMeta(List<JsoRecordData> list, JsoColumnMeta... columnMeta)
+    {
+        super();
+        this.meta = new LinkedHashMap<String, JsoColumnMeta>(columnMeta.length);
+        for (JsoColumnMeta c : columnMeta) {
+            meta.put(c.getProperty(), c);
+        }
+        this.data = list;
+    }
+
+    public Map<String, JsoColumnMeta> getMeta()
+    {
+        return meta;
+    }
+
+    public Object getData()
+    {
+        return data;
+    }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/ResultWithMeta.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/ResultWithMeta.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/ResultWithMeta.java
deleted file mode 100644
index 7d30fdd..0000000
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/json/ResultWithMeta.java
+++ /dev/null
@@ -1,48 +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.rest.json;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-public class ResultWithMeta
-{
-    private final Map<String, ColumnMetaData> meta;
-    private final Object data;
-    
-    public ResultWithMeta(Object data, ColumnMetaData... columnMeta)
-    {
-        super();
-        this.meta = new LinkedHashMap<String, ColumnMetaData>(columnMeta.length);
-        for (ColumnMetaData c : columnMeta) {
-            meta.put(c.getProperty(), c);
-        }
-        this.data = data;
-    }
-
-    public Map<String, ColumnMetaData> getMeta()
-    {
-        return meta;
-    }
-
-    public Object getData()
-    {
-        return data;
-    }
-}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/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 0793ff0..8525ec7 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
@@ -30,21 +30,22 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
 
+import org.apache.empire.commons.Options;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBCommand;
 import org.apache.empire.db.DBJoinType;
 import org.apache.empire.db.DBReader;
-import org.apache.empire.rest.app.EmployeeVueApp;
+import org.apache.empire.exceptions.EmpireException;
+import org.apache.empire.rest.app.SampleServiceApp;
 import org.apache.empire.rest.app.TextResolver;
-import org.apache.empire.rest.json.ColumnMetaData;
-import org.apache.empire.rest.json.EmployeeData;
-import org.apache.empire.rest.json.EmployeeSearchFilter;
-import org.apache.empire.rest.json.ResultWithMeta;
-import org.apache.empire.vuesample.model.db.SampleDB;
-import org.apache.empire.vuesample.model.db.SampleDB.TDepartments;
-import org.apache.empire.vuesample.model.db.SampleDB.TEmployees;
+import org.apache.empire.rest.json.JsoColumnMeta;
+import org.apache.empire.rest.json.JsoRecordData;
+import org.apache.empire.rest.json.JsoResultWithMeta;
+import org.apache.empire.vue.sample.db.SampleDB;
+import org.apache.empire.vue.sample.db.SampleDB.TDepartments;
+import org.apache.empire.vue.sample.db.SampleDB.TEmployees;
+import org.apache.empire.vue.sample.db.records.EmployeeRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -56,30 +57,38 @@ public class EmployeeService extends Service {
 	@GET
     @Path("/filter")
     @Produces(MediaType.APPLICATION_JSON)
-    public Response getEmployee() {
+    public Response getEmployeeFilter() {
 
-        EmployeeSearchFilter filter = new EmployeeSearchFilter(); 
-	    
-        TextResolver txtres = EmployeeVueApp.instance().getTextResolver(Locale.ENGLISH);
-        
+        TextResolver txtres = SampleServiceApp.instance().getTextResolver(Locale.ENGLISH);
+
+        // Query Department options
         SampleDB db = getDatabase();
+        DBCommand cmd = db.createCommand();
+        cmd.select(db.T_DEPARTMENTS.DEPARTMENT_ID, db.T_DEPARTMENTS.NAME);
+        cmd.join  (db.T_DEPARTMENTS.DEPARTMENT_ID, db.T_EMPLOYEES.DEPARTMENT_ID);
+        cmd.groupBy(cmd.getSelectExprList());
+        cmd.orderBy(db.T_DEPARTMENTS.NAME);
+        Options departmentOptions = db.queryOptionList(cmd, getRecordContext().getConnection());
+        
+        // Create Metadata
         TEmployees TE = db.T_EMPLOYEES;
-        ColumnMetaData[] meta = new ColumnMetaData[] { 
-          new ColumnMetaData(TE.EMPLOYEE_ID, txtres),
-          new ColumnMetaData(TE.FIRST_NAME, txtres),
-          new ColumnMetaData(TE.LAST_NAME, txtres),
-          new ColumnMetaData(TE.DEPARTMENT_ID, txtres),
-          new ColumnMetaData(TE.GENDER, txtres),
+        JsoColumnMeta[] meta = new JsoColumnMeta[] { 
+          new JsoColumnMeta(TE.EMPLOYEE_ID, txtres),
+          new JsoColumnMeta(TE.FIRST_NAME, txtres),
+          new JsoColumnMeta(TE.LAST_NAME, txtres),
+          new JsoColumnMeta(TE.DEPARTMENT_ID, txtres, departmentOptions, false, false),
+          new JsoColumnMeta(TE.GENDER, txtres),
         };
         
-        return Response.ok(new ResultWithMeta(filter, meta)).build();
+        JsoRecordData filter = new JsoRecordData(meta);
+        return Response.ok(new JsoResultWithMeta(filter, meta)).build();
     }
 
     @POST
     @Path("/list/")
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    public Response getEmployeeList(EmployeeSearchFilter filter) {
+    public Response getEmployeeList(JsoRecordData filter) {
 
         SampleDB db = getDatabase();
 
@@ -95,26 +104,37 @@ public class EmployeeService extends Service {
         cmd.select(TE.EMPLOYEE_ID, FULL_NAME, DEPARTMENT, TE.GENDER, TE.DATE_OF_BIRTH, TE.RETIRED);
         cmd.join  (TE.DEPARTMENT_ID, TD.DEPARTMENT_ID, DBJoinType.LEFT);
 
+        // apply all filters
+        if (filter.hasNonNullValue(TE.FIRST_NAME))
+            cmd.where(TE.FIRST_NAME.like(filter.getString(TE.FIRST_NAME) + "%"));
+        if (filter.hasNonNullValue(TE.LAST_NAME))
+            cmd.where(TE.LAST_NAME.like(filter.getString(TE.FIRST_NAME) + "%"));
+        if (filter.hasNonNullValue(TE.GENDER))
+            cmd.where(TE.GENDER.is(filter.getValue(TE.GENDER)));
+        if (filter.hasNonNullValue(TE.DEPARTMENT_ID))
+            cmd.where(TE.DEPARTMENT_ID.is(filter.getValue(TE.DEPARTMENT_ID)));
+        
+
         DBColumnExpr[] cols = cmd.getSelectExprList();
-        ColumnMetaData[] meta = new ColumnMetaData[cols.length]; 
-        TextResolver txtres = EmployeeVueApp.instance().getTextResolver(Locale.ENGLISH);
+        JsoColumnMeta[] meta = new JsoColumnMeta[cols.length]; 
+        TextResolver txtres = SampleServiceApp.instance().getTextResolver(Locale.ENGLISH);
         for (int i=0; i<meta.length; i++)
         {
-            meta[i] = new ColumnMetaData(cols[i], txtres);
+            meta[i] = new JsoColumnMeta(cols[i], txtres);
         }
         
         DBReader reader = new DBReader();
-        List<EmployeeData> list = new ArrayList<>();
+        List<JsoRecordData> list = new ArrayList<>();
         try {
             reader.open(cmd, getConnection());
             while (reader.moveNext()) {
-                list.add(new EmployeeData(reader));
+                list.add(new JsoRecordData(reader));
             }
         } finally {
             reader.close();
         }
         // done
-        return Response.ok(new ResultWithMeta(list, meta)).build();
+        return Response.ok(new JsoResultWithMeta(list, meta)).build();
     }
 
 	@GET
@@ -122,39 +142,28 @@ public class EmployeeService extends Service {
 	@Produces(MediaType.APPLICATION_JSON)
 	public Response getEmployee(@PathParam("employeeId") int employeeId) {
 
-		SampleDB db = getDatabase();
-
-		TEmployees TE = db.T_EMPLOYEES;
-
-		DBCommand cmd = db.createCommand();
-		cmd.select(TE.EMPLOYEE_ID, TE.LAST_NAME, TE.FIRST_NAME, TE.DATE_OF_BIRTH);
-		cmd.where(TE.EMPLOYEE_ID.is(employeeId));
-
-		DBReader reader = new DBReader();
-		try {
-			reader.open(cmd, getConnection());
-
-			if (!reader.moveNext()) {
-				// Employee not found
-				return Response.status(Status.NOT_FOUND).build();
-			}
-
-			EmployeeData emp = new EmployeeData(reader);
-            return Response.ok(emp).build();
-
-		} finally {
-			reader.close();
-		}
+	    try {
+	        // return a record
+	        EmployeeRecord rec = new EmployeeRecord(getDatabase(), getRecordContext());
+            rec.read(employeeId);
+            JsoRecordData emp = new JsoRecordData(rec);
+            return Response.ok(new JsoResultWithMeta(emp, rec.getMeta())).build();
+	        
+	    } catch(EmpireException e) {
+	        log.error("Unable to load employee with id {}", employeeId);
+	        return Response.serverError().build();
+	    }
 	}
 
     @POST
     @Path("/set")
     @Consumes(MediaType.APPLICATION_JSON)
-    public Response updateEmployee(EmployeeData employee) {
-        /*
-        SampleDB db = getDatabase();
-        TEmployees TE = db.T_EMPLOYEES;
-        */
+    public Response updateEmployee(JsoRecordData employeeData) {
+
+        EmployeeRecord rec = new EmployeeRecord(getDatabase(), getRecordContext());
+        rec.init(employeeData, employeeData.isNewRecord());
+        rec.update();
+        
         return Response.ok().build();
     }
 

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/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 c016748..2328c06 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,11 +26,16 @@ import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.container.ContainerRequestContext;
 import javax.ws.rs.core.Context;
 
-import org.apache.empire.vuesample.model.db.SampleDB;
+import org.apache.empire.vue.sample.db.RecordContext;
+import org.apache.empire.vue.sample.db.SampleDB;
 import org.glassfish.jersey.server.ContainerRequest;
 
 public abstract class Service {
 
+    /**
+     * Some constants used by the services
+     * @author doebele
+     */
     public static class Consts {
     
         public static final String  LOGIN_COOKIE_NAME       = "EmployeeVueLoginCookie";
@@ -44,6 +49,27 @@ public abstract class Service {
         public static final String  ATTRIBUTE_CONFIG        = "config";
     
     }
+
+    /**
+     * Implementation for RecordContext
+     * Holds a connection and therefore must not live for longer than the request  
+     * @author doebele
+     */
+    public static class ServiceRecordContext implements RecordContext
+    {
+        private final Connection conn;
+        
+        public ServiceRecordContext(Connection conn)
+        {
+            this.conn = conn;
+        }
+
+        @Override
+        public Connection getConnection()
+        {
+            return conn;
+        }
+    }
     
 	@Context
 	private ServletContext			context;
@@ -63,6 +89,10 @@ public abstract class Service {
 		return (Connection) containerRequest.getProperty(Service.Consts.ATTRIBUTE_CONNECTION);
 	}
 
+    public RecordContext getRecordContext() {
+        return new ServiceRecordContext(getConnection());
+    }
+
 	public ServletRequest getServletRequest() {
 		return this.req;
 	}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/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 6c91d1f..22a6007 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
@@ -30,7 +30,7 @@ import javax.ws.rs.core.Cookie;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.Provider;
 
-import org.apache.empire.rest.app.EmployeeVueApp;
+import org.apache.empire.rest.app.SampleServiceApp;
 import org.apache.empire.rest.service.Service;
 import org.glassfish.jersey.server.ContainerRequest;
 import org.slf4j.Logger;
@@ -66,7 +66,7 @@ public class ServiceRequestFilter implements ContainerRequestFilter
         ContainerRequest containerRequest = (ContainerRequest) requestContext;
 
         // get Connection from pool
-        Connection conn = EmployeeVueApp.instance().getJDBCConnection(this.servletContext);
+        Connection conn = SampleServiceApp.instance().getJDBCConnection(this.servletContext);
 
         // Add to context
         containerRequest.setProperty(Service.Consts.ATTRIBUTE_CONNECTION, conn);

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/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
deleted file mode 100644
index e9f93c8..0000000
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/rest/service/listener/AppListener.java
+++ /dev/null
@@ -1,48 +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.rest.service.listener;
-
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
-import org.apache.empire.rest.app.EmployeeVueApp;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AppListener implements ServletContextListener {
-
-	private static final Logger log = LoggerFactory.getLogger(AppListener.class);
-
-	@Override
-	public void contextInitialized(ServletContextEvent sce) {
-
-		log.debug("contextInitialized");
-		// create application
-		EmployeeVueApp.create(sce.getServletContext());
-		// done
-		log.debug("contextInitialized done");
-	}
-
-	@Override
-	public void contextDestroyed(ServletContextEvent sce) {
-		log.debug("contextDestroyed");
-		log.debug("contextDestroyed done");
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/RecordContext.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/RecordContext.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/RecordContext.java
new file mode 100644
index 0000000..8293ace
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/RecordContext.java
@@ -0,0 +1,8 @@
+package org.apache.empire.vue.sample.db;
+
+import java.sql.Connection;
+
+public interface RecordContext
+{
+    Connection getConnection();
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleDB.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleDB.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleDB.java
new file mode 100644
index 0000000..67f08f0
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleDB.java
@@ -0,0 +1,156 @@
+/*
+ * 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.vue.sample.db;
+
+import org.apache.empire.commons.Options;
+import org.apache.empire.data.DataMode;
+import org.apache.empire.data.DataType;
+import org.apache.empire.db.DBColumn;
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBTableColumn;
+
+public class SampleDB extends DBDatabase
+{
+    private final static long       serialVersionUID = 1L;
+
+    // Declare all Tables
+    public final TDepartments       T_DEPARTMENTS    = new TDepartments(this);
+    public final TEmployees         T_EMPLOYEES      = new TEmployees(this);
+
+    /**
+     * Constructor SampleDB
+     */
+    public SampleDB()
+    {
+        // Define Foreign-Key Relations
+        addRelation(T_EMPLOYEES.DEPARTMENT_ID.referenceOn(T_DEPARTMENTS.DEPARTMENT_ID));
+    }
+
+    // Needed for the DBELResolver
+    @Override
+    protected void register(String id)
+    {
+        super.register("db");
+    }
+
+    /**
+     * This class represents the definition of the Departments table.
+     */
+    public static class TDepartments extends SampleTable
+    {
+        private static final long  serialVersionUID = 1L;
+
+        public final DBTableColumn DEPARTMENT_ID;
+        public final DBTableColumn NAME;
+        public final DBTableColumn HEAD;
+        public final DBTableColumn BUSINESS_UNIT;
+        public final DBTableColumn UPDATE_TIMESTAMP;
+
+        public TDepartments(DBDatabase db)
+        {
+            super("DEPARTMENTS", db);
+            // ID
+            DEPARTMENT_ID 	= addColumn("DEPARTMENT_ID", 	DataType.AUTOINC,	 0, true, "DEP_ID_SEQUENCE");
+            NAME 			= addColumn("NAME", 			DataType.TEXT, 		80, true);
+            HEAD 			= addColumn("HEAD", 			DataType.TEXT, 		80, false);
+            BUSINESS_UNIT 	= addColumn("BUSINESS_UNIT", 	DataType.TEXT,		 4, true, "ITTK");
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,	 0, true);
+
+            // Primary Key
+            setPrimaryKey(DEPARTMENT_ID);
+            // Set other Indexes
+            addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
+            // Set timestamp column for save updates
+            setTimestampColumn(UPDATE_TIMESTAMP);
+
+        }
+    }
+
+  
+
+    /**
+     * This class represents the definition of the Employees table.
+     */
+    public static class TEmployees extends SampleTable
+    {
+        private static final long  serialVersionUID = 1L;
+
+        public final DBTableColumn EMPLOYEE_ID;
+        public final DBTableColumn SALUTATION;
+//      public final DBTableColumn PICTURE;
+        public final DBTableColumn FIRST_NAME;
+        public final DBTableColumn LAST_NAME;
+        public final DBTableColumn DATE_OF_BIRTH;
+        public final DBTableColumn DEPARTMENT_ID;
+        public final DBTableColumn GENDER;
+        public final DBTableColumn PHONE_NUMBER;
+        public final DBTableColumn EMAIL;
+        public final DBTableColumn RETIRED;
+        public final DBTableColumn UPDATE_TIMESTAMP;
+        public TEmployees(DBDatabase db)
+        {
+            super("EMPLOYEES", db);
+            // ID
+            EMPLOYEE_ID 	= addColumn("EMPLOYEE_ID", 		DataType.AUTOINC, 	 0, true, "EMPLOYEE_ID_SEQUENCE");
+            SALUTATION 		= addColumn("SALUTATION", 		DataType.TEXT, 		 5, false);
+            FIRST_NAME 		= addColumn("FIRST_NAME", 		DataType.TEXT, 		40, true);
+            LAST_NAME 		= addColumn("LAST_NAME", 		DataType.TEXT, 		40, true);
+            DATE_OF_BIRTH 	= addColumn("DATE_OF_BIRTH", 	DataType.DATE,		 0, false);
+            DEPARTMENT_ID 	= addColumn("DEPARTMENT_ID", 	DataType.INTEGER, 	 0, true);
+            GENDER 			= addColumn("GENDER", 			DataType.TEXT, 		 1, false);
+            PHONE_NUMBER 	= addColumn("PHONE_NUMBER", 	DataType.TEXT, 		40, false);
+            EMAIL 			= addColumn("EMAIL", 			DataType.TEXT, 		80, false);
+            RETIRED			= addColumn("RETIRED", 			DataType.BOOL, 		 0, true, false);
+            // PICTURE 		= addColumn("PICTURE", 			DataType.BLOB, 		 0, false);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,	 0, true);
+
+            // Primary Key
+            setPrimaryKey(EMPLOYEE_ID);
+            // Set other Indexes
+            addIndex("PERSON_NAME_IDX", true, new DBColumn[] { FIRST_NAME, LAST_NAME, DATE_OF_BIRTH });
+
+            // Set timestamp column for save updates
+            setTimestampColumn(UPDATE_TIMESTAMP);
+
+            // Create Options for GENDER column
+            Options genders = new Options();
+            genders.set("M", "!option.employee.gender.male");
+            genders.set("F", "!option.employee.gender.female");
+            GENDER.setOptions(genders);
+            GENDER.setControlType("select");
+
+            Options retired = new Options();
+            retired.set(false, "!option.employee.active");
+            retired.set(true,  "!option.employee.retired");
+            RETIRED.setOptions(retired);
+            RETIRED.setControlType("checkbox");
+            
+            // Set special control types
+            DEPARTMENT_ID.setControlType("select");
+            PHONE_NUMBER .setControlType("phone");
+            
+            // Set optional formatting attributes
+            DATE_OF_BIRTH.setAttribute("format:date", "yyyy-MM-dd");
+            
+            // PICTURE.setControlType("blob");
+
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleTable.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleTable.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleTable.java
new file mode 100644
index 0000000..abfa906
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleTable.java
@@ -0,0 +1,81 @@
+/*
+ * 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.vue.sample.db;
+
+import java.util.Locale;
+
+import org.apache.empire.data.DataType;
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBTable;
+import org.apache.empire.db.DBTableColumn;
+
+/**
+ * Base class definition for all database tables Automatically generates a message-key for the field title e.g. for the column
+ * EMPLOYEES.DATE_OF_BIRTH it generates the key "!field.title.employees.dateOfBirth";
+ */
+public class SampleTable extends DBTable
+{
+    private final static long serialVersionUID   = 1L;
+    public final String       MESSAGE_KEY_PREFIX = "!field.title.";
+
+    public SampleTable(String name, DBDatabase db)
+    {
+        super(name, db);
+    }
+
+    @Override
+    protected void addColumn(DBTableColumn column)
+    {
+        // Set Translation Title
+        String col = column.getBeanPropertyName();
+        String tbl = getName().toLowerCase();
+        String key = MESSAGE_KEY_PREFIX + tbl + "." + col;
+        column.setTitle(key);
+
+        // Set Default Control Type
+        DataType type = column.getDataType();
+        column.setControlType((type == DataType.BOOL) ? "checkbox" : "text");
+
+        // Add Column
+        super.addColumn(column);
+    }
+
+    public enum LanguageIndex {
+        DE(Locale.GERMAN),
+
+        EN(Locale.ENGLISH);
+
+        private final Locale locale;
+
+        private LanguageIndex(Locale locale)
+        {
+            this.locale = locale;
+        }
+
+        public Locale getLocale()
+        {
+            return this.locale;
+        }
+
+        public String getDBLangKey()
+        {
+            return this.name().toUpperCase();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/DepartmentRecord.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/DepartmentRecord.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/DepartmentRecord.java
new file mode 100644
index 0000000..b38e61c
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/DepartmentRecord.java
@@ -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.
+ */
+package org.apache.empire.vue.sample.db.records;
+
+import org.apache.empire.vue.sample.db.RecordContext;
+import org.apache.empire.vue.sample.db.SampleDB;
+import org.apache.empire.vue.sample.db.SampleDB.TDepartments;
+
+public class DepartmentRecord extends SampleRecord<TDepartments>
+{
+    private final static long serialVersionUID = 1L;
+
+    public DepartmentRecord(SampleDB db, RecordContext recordContext)
+    {
+        super(db.T_DEPARTMENTS, recordContext);
+    }
+  
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/EmployeeRecord.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/EmployeeRecord.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/EmployeeRecord.java
new file mode 100644
index 0000000..cffe29a
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/EmployeeRecord.java
@@ -0,0 +1,77 @@
+/*
+ * 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.vue.sample.db.records;
+
+import org.apache.empire.commons.Options;
+import org.apache.empire.data.Column;
+import org.apache.empire.db.DBColumn;
+import org.apache.empire.db.DBCommand;
+import org.apache.empire.vue.sample.db.RecordContext;
+import org.apache.empire.vue.sample.db.SampleDB;
+import org.apache.empire.vue.sample.db.SampleDB.TEmployees;
+
+public class EmployeeRecord extends SampleRecord<TEmployees>
+{
+    private final static long serialVersionUID = 1L;
+
+    public EmployeeRecord(SampleDB db, RecordContext recordContext)
+    {
+        super(db.T_EMPLOYEES, recordContext);
+    }
+    
+	/*
+	 * Add some business logic:
+	 * Make all fields read only if employee is retired (except the retired field itself!) 
+	 */
+    @Override
+    public boolean isFieldReadOnly(Column column)
+    {
+    	if (column!=T.RETIRED && getBoolean(T.RETIRED))
+    	{	/* Employee is retired */
+    		return true;
+    	}	
+    	return super.isFieldReadOnly(column);	
+    }
+
+    @Override
+    public Options getFieldOptions(DBColumn column)
+    {
+        if (column.equals(T.DEPARTMENT_ID))
+        {
+            SampleDB db = (SampleDB) getDatabase();
+            DBCommand cmd = db.createCommand();
+            cmd.select(db.T_DEPARTMENTS.DEPARTMENT_ID);
+            cmd.select(db.T_DEPARTMENTS.NAME);
+            cmd.orderBy(db.T_DEPARTMENTS.NAME);
+            return db.queryOptionList(cmd, recordContext.getConnection());
+        }
+        // base class implementation
+        return super.getFieldOptions(column);
+    }
+
+    // Sample Implementation for Department Record
+    public DepartmentRecord getDepartmentRecord()
+    {
+        DepartmentRecord rec = new DepartmentRecord((SampleDB)this.getDatabase(), recordContext);
+        SampleDB.TDepartments table = ((SampleDB)getDatabase()).T_DEPARTMENTS;
+        rec.read(table, this.getInt(T.DEPARTMENT_ID), recordContext.getConnection());
+        return rec;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/878e45c2/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/SampleRecord.java
----------------------------------------------------------------------
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/SampleRecord.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/SampleRecord.java
new file mode 100644
index 0000000..32ab8ba
--- /dev/null
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/SampleRecord.java
@@ -0,0 +1,139 @@
+/*
+ * 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.vue.sample.db.records;
+
+import java.sql.Connection;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.empire.commons.Options;
+import org.apache.empire.db.DBColumn;
+import org.apache.empire.db.DBRecord;
+import org.apache.empire.rest.app.SampleServiceApp;
+import org.apache.empire.rest.app.TextResolver;
+import org.apache.empire.rest.json.JsoColumnMeta;
+import org.apache.empire.rest.json.JsoRecordData;
+import org.apache.empire.vue.sample.db.RecordContext;
+import org.apache.empire.vue.sample.db.SampleTable;
+
+
+public abstract class SampleRecord<T extends SampleTable> extends DBRecord {
+
+	private static final long serialVersionUID = 1L;
+	
+	protected final T T; // The table
+	protected final RecordContext recordContext;
+
+	public SampleRecord(T table, RecordContext recordContext) {
+		super(table);
+		this.T = table;
+		this.recordContext = recordContext;
+	}
+
+	/**
+	 * Returns the table this record is based upon.
+	 * @return The table this record is based upon.
+	 */
+	public T getTable() {
+		return T;
+	}
+
+    public RecordContext getRecordContext()
+    {
+        return recordContext;
+    }
+    
+    public JsoColumnMeta[] getMeta()
+    {
+        List<DBColumn> columns = T.getColumns();
+        JsoColumnMeta[] meta = new JsoColumnMeta[columns.size()]; 
+        TextResolver txtres = SampleServiceApp.instance().getTextResolver(Locale.ENGLISH);
+        for (int i=0; i<meta.length; i++)
+        {
+            DBColumn col = columns.get(i);
+            if (this.isFieldVisible(col)==false)
+                continue;
+            // get Meta
+            Options  opt = this.getFieldOptions(col);
+            boolean readOnly = this.isFieldReadOnly(col);
+            boolean required = this.isFieldRequired(col);
+            meta[i] = new JsoColumnMeta(col, txtres, opt, required, readOnly);
+        }
+        return meta;
+    }
+    
+    public void init(JsoRecordData data, boolean newRecord)
+    {
+        // build the key
+        DBColumn[] kc = T.getKeyColumns();
+        Object[] key = new Object[kc.length];
+        for (int i=0; i<kc.length; i++)
+        {   // set key values
+            String prop = kc[i].getBeanPropertyName();
+            key[i] = data.get(prop);
+        }
+        // load original record
+        if (newRecord)
+        {   // init a new record
+            super.init(T, key, true);
+        }
+        else
+        {   // read the current record
+            super.read(T, key, recordContext.getConnection());
+        }
+        // set all fields
+        for (DBColumn c : T.getColumns())
+        {   // skip all key columns
+            if (T.isKeyColumn(c))
+                continue; // already set
+            if (c==T.getTimestampColumn())
+                continue;
+            // get Value 
+            String prop = c.getBeanPropertyName();
+            if (!data.containsKey(prop))
+            {   // not provided
+                continue; 
+            }
+            Object value = data.get(prop);
+            // set Value 
+            this.setValue(c, value);
+        }
+    }
+    
+    public void create(Connection conn)
+    {
+        super.create(getTable(), recordContext.getConnection());
+    }
+	
+    public void read(Object[] keys)
+    {
+        super.read(getTable(), keys, recordContext.getConnection());
+    }
+
+    public void read(Object id)
+    {
+        super.read(getTable(), id, recordContext.getConnection());
+    }
+    
+    public void update()
+    {
+        super.update(recordContext.getConnection());
+    }
+	
+}
\ No newline at end of file