EMPIREDB-362 JSF exmaple improvment
diff --git a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/HtmlGenUtil.java b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/HtmlGenUtil.java
index df2f028..bdd1e1a 100644
--- a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/HtmlGenUtil.java
+++ b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/HtmlGenUtil.java
@@ -61,28 +61,48 @@
             "int count = context.executeUpdate(cmd);\r\n" + 
             "log.info(\"{} models affected\", count);"; 
 
+    public static final String codeCodegen = "// create the config\r\n" + 
+            "CodeGenConfig config = new CodeGenConfig();\r\n" + 
+            "// use API or load from file using \r\n" + 
+            "config.setPackageName(\"com.mycompany.myproject.database\");\r\n" + 
+            "config.set(...)\r\n" + 
+            "// get the DBMS\r\n" + 
+            "DBMSHandler dbms = new DBMSHandlerOracle();\r\n" + 
+            "// get the JDBC-Connection\r\n" + 
+            "Connection conn = getJDBCConnection(config);\r\n" + 
+            "// Generate code from database\r\n" + 
+            "CodeGenerator app = new CodeGenerator();\r\n" + 
+            "app.generate(dbms, conn, config);\r\n";
     
-    public static String codeToHtml(DBDatabase db, String code, Number... literals)
+    public static String codeToHtml(DBDatabase db, String code, Object... literals)
     {
         code = prepareHtml(code);
-        // String Literals must go first
-        code = replaceFragment(code, '"', '"', true, "<span class=\"literal\">", "</span>", null);
-        // other literals
+        // replace literals
         for (int i=0; i<literals.length; i++)
-            code = replaceWord(code, literals[i].toString(), ' ', "<span class=\"literal\">", "</span>");
+        {
+            String literal;
+            if (literals[i] instanceof String)
+                literal = "\""+((String)literals[i])+"\"";
+            else
+                literal = String.valueOf(literals[i]);
+            code = replaceWord(code, literal, ' ', "<span class=\"literal\">", "</span>");
+        }
         // null
         code = replaceWord(code, "null", ' ', "<span class=\"literal\">", "</span>");
+        code = replaceWord(code, "new", ' ', "<span class=\"new\">", "</span>");
         // types
-        String[] types = new String[] { "CarSalesDB", "DBCommand", "QueryResult", "EngineType", "int ", "long ", "String " };
+        String[] types = new String[] { "CarSalesDB", "CodeGenerator", "CodeGenConfig", "DBMSHandlerOracle", "DBMSHandler ", "Connection ", "DBCommand", "QueryResult", "EngineType", "int ", "long ", "String " };
         for (int i=0; i<types.length; i++)
             code = replaceWord(code, types[i], ' ', "<span class=\"type\">", "</span>");
         // Tables and columns
-        for (DBTable t : db.getTables())
-        {
-            code = replaceWord(code, t.getName(), ' ', "<span class=\"obj\">", "</span>");
-            for (DBColumn c : t.getColumns())
+        if (db!=null)
+        {   for (DBTable t : db.getTables())
             {
-                code = replaceWord(code, "."+c.getName(), '.', "<span class=\"var\">", "</span>");
+                code = replaceWord(code, t.getName(), ' ', "<span class=\"obj\">", "</span>");
+                for (DBColumn c : t.getColumns())
+                {
+                    code = replaceWord(code, "."+c.getName(), '.', "<span class=\"var\">", "</span>");
+                }
             }
         }
         // functions
@@ -174,7 +194,14 @@
                     continue;
                 }
             }
-            int j = str.indexOf(end, ++i);
+            int n = str.indexOf('\n', i+1);
+            int j = str.indexOf(end,  ++i);
+            if (n<j)
+            {   // line-break: ignore
+                s.append(str.substring(p, n+1));
+                p = n+1;
+                continue;
+            }
             if (!include)
             {   // remove whitespace
                 while(str.charAt(j-1)==' ') j--;
diff --git a/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/SampleDBwithMeta.java b/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/SampleDBwithMeta.java
index c1dd3f2..74ef228 100644
--- a/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/SampleDBwithMeta.java
+++ b/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/SampleDBwithMeta.java
@@ -19,7 +19,9 @@
 package org.apache.empire.jsf2.websample.db;
 
 import org.apache.empire.commons.Options;
+import org.apache.empire.data.Column;
 import org.apache.empire.db.DBContext;
+import org.apache.empire.jsf2.controls.TextInputControl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,13 +34,17 @@
     public void open(DBContext context)
     {
         super.open(context);
-        // add JSF Metatada
+        // Hint about metadata 
+        log.info("Basic metadata such as Title has already been set in SampleTable.addColumn()");
+        // add additional metadata e.g. for JSF-controls
         addMeta(EMPLOYEES);
     }
     
     private void addMeta(SampleDB.TEmployees T)
     {
         log.info("Adding additional Metadata for {}", T.getName());
+        // Set custom style for SALUTATION
+        T.SALUTATION.setAttribute("styleClass", "eInpShort");
         
         // Create Options for GENDER column
         // add the message-keys instead of the enum string value
@@ -47,18 +53,32 @@
         genders.set(Gender.F, "!option.employee.gender.female");
         T.GENDER.setOptions(genders);
         T.GENDER.setControlType("select");
+        T.GENDER.setAttribute("styleClass", "eInpShort");
 
+        // RETIRED column
         Options retired = new Options();
         retired.set(false, "!option.employee.active");
         retired.set(true,  "!option.employee.retired");
         T.RETIRED.setOptions(retired);
         T.RETIRED.setControlType("checkbox");
+
+        // Hint for DATE_OF_BIRTH
+        T.DATE_OF_BIRTH.setAttribute("format:date", "yyyy-MM-dd");
+        T.DATE_OF_BIRTH.setAttribute("hint", "[yyyy-MM-dd]");
+         
+        // Salary special
+        T.SALARY.setAttribute("styleClass", "eInpDecimal")
+                .setAttribute(TextInputControl.FORMAT_UNIT_ATTRIBUTE, "USD")
+                .setAttribute(Column.COLATTR_NUMBER_TYPE, "Decimal")
+                .setAttribute(Column.COLATTR_FRACTION_DIGITS, 2)
+                .setAttribute(Column.COLATTR_NUMBER_GROUPSEP, true);
         
         // Set special control types
         T.DEPARTMENT_ID.setControlType("select");
-        T.PHONE_NUMBER .setControlType("phone");
+        // T.PHONE_NUMBER .setControlType("phone");
         
-        // Set optional formatting attributes
-        T.DATE_OF_BIRTH.setAttribute("format:date", "yyyy-MM-dd");
+        // UPDATE_TIMESTAMP
+        T.UPDATE_TIMESTAMP.setAttribute("format:date", "full");
+        // format="date-format:full" readonly="true" rendered="#{page.idParam != null}"         
     }
 }
diff --git a/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/records/EmployeeRecord.java b/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/records/EmployeeRecord.java
index 5e7f661..4862805 100644
--- a/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/records/EmployeeRecord.java
+++ b/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/records/EmployeeRecord.java
@@ -40,6 +40,18 @@
 	 * Make all fields read only if employee is retired (except the retired field itself!) 
 	 */
     @Override
+    public boolean isFieldVisible(Column column)
+    {
+        if (!super.isFieldVisible(column))
+            return false;
+        // UPDATE_TIMESTAMP
+        if (column==T.UPDATE_TIMESTAMP && isNew())
+            return false; // invisible for new records
+        // default
+        return true; 
+    }
+    
+    @Override
     public boolean isFieldReadOnly(Column column)
     {
     	if (column!=T.RETIRED && getBoolean(T.RETIRED))
diff --git a/empire-db-examples/empire-db-example-jsf2/src/main/resources/lang/messages_en.properties b/empire-db-examples/empire-db-example-jsf2/src/main/resources/lang/messages_en.properties
index d87d739..6e4d0e8 100644
--- a/empire-db-examples/empire-db-example-jsf2/src/main/resources/lang/messages_en.properties
+++ b/empire-db-examples/empire-db-example-jsf2/src/main/resources/lang/messages_en.properties
@@ -25,7 +25,7 @@
 field.title.employees.gender=Gender
 field.title.employees.phoneNumber=Phone
 field.title.employees.email=E-Mail
-field.title.employees.salary=Salary (Year)
+field.title.employees.salary=Salary p.a.
 field.title.employees.retired=Retired
 field.title.employees.updateTimestamp=Last change
 
diff --git a/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/common.css b/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/common.css
index 2e2a8b1..8a67798 100644
--- a/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/common.css
+++ b/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/common.css
@@ -16,6 +16,20 @@
  * specific language governing permissions and limitations

  * under the License.

  */

+/* 

+ * common 

+ */

+* {

+  -webkit-box-sizing: border-box;

+     -moz-box-sizing: border-box;

+          box-sizing: border-box;

+}

+*:before,

+*:after {

+  -webkit-box-sizing: border-box;

+     -moz-box-sizing: border-box;

+          box-sizing: border-box;

+}

 html, body  {

 	width: 800px;

     margin-left: 10px;

diff --git a/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/content.css b/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/content.css
index e7123df..b13f049 100644
--- a/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/content.css
+++ b/empire-db-examples/empire-db-example-jsf2/src/main/webapp/css/content.css
@@ -84,9 +84,9 @@
 	color: brown;
 	font-weight: bold;
 }
-
-span.required {
-	color: brown;
+label.eLabel.eInpReq:after {
+	content: "*";
+	color: #D00000;
 }
 select, 
 input[type=text],
@@ -95,7 +95,8 @@
 }
 select.eInpReq, 
 input[type=text].eInpReq {
-	border: 1px brown solid;
+/*	border: 1px brown solid; */
+	background-color: #FFFFE0;
 }
 select.eInpDis, 
 textarea.eInpDis,
@@ -103,6 +104,21 @@
 	border: 1px #C0C0C0 solid;
 	color: #808080;
 }
+.eInput {
+	width: 100%;
+}
+.eInput.eTypeBool {
+	width: auto;
+}
+select.eInput.eInpShort,
+input.eInput.eInpShort,
+input.eInput.eTypeDate {
+	width: 100px;
+}
+input.eInput.eInpDecimal {
+	width: 100px;
+	text-align: right;
+}
 span.eInpDis {
 	display: inline-block;
 	padding-top: 3px;
diff --git a/empire-db-examples/empire-db-example-jsf2/src/main/webapp/pages/employeeDetailPage.xhtml b/empire-db-examples/empire-db-example-jsf2/src/main/webapp/pages/employeeDetailPage.xhtml
index 5b85e04..012e78a 100644
--- a/empire-db-examples/empire-db-example-jsf2/src/main/webapp/pages/employeeDetailPage.xhtml
+++ b/empire-db-examples/empire-db-example-jsf2/src/main/webapp/pages/employeeDetailPage.xhtml
@@ -46,14 +46,14 @@
 					<tr><e:control column="#{db.EMPLOYEES.SALUTATION}" /></tr>

 					<tr><e:control column="#{db.EMPLOYEES.FIRST_NAME}" /></tr>

 					<tr><e:control column="#{db.EMPLOYEES.LAST_NAME}" /></tr>

-					<tr><e:control column="#{db.EMPLOYEES.DATE_OF_BIRTH}" hint="[yyyy-MM-dd]"/></tr>

+					<tr><e:control column="#{db.EMPLOYEES.DATE_OF_BIRTH}"/></tr>

 					<tr><e:control column="#{db.EMPLOYEES.DEPARTMENT_ID}" /></tr>

 					<tr><e:control column="#{db.EMPLOYEES.GENDER}"   /> </tr>

 					<tr><e:control column="#{db.EMPLOYEES.PHONE_NUMBER}" /></tr>

 					<tr><e:control column="#{db.EMPLOYEES.EMAIL}" /></tr>

 					<tr><e:control column="#{db.EMPLOYEES.SALARY}" /></tr>

 					<tr><e:control column="#{db.EMPLOYEES.RETIRED}" /></tr>

-					<tr><e:control column="#{db.EMPLOYEES.UPDATE_TIMESTAMP}" format="date-format:full" readonly="true" rendered="#{page.idParam != null}" /></tr> 

+					<tr><e:control column="#{db.EMPLOYEES.UPDATE_TIMESTAMP}"/></tr> 

 				</sample:formPanel>

 				</e:record>

 				

diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
index e756e31..45dccb5 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
@@ -1498,7 +1498,7 @@
         if (column==null)

         {   // Get from LinkTag

             column = getColumn();

-            required = isValueRequired(); // does only check Attribute

+            required = !readOnly && isValueRequired(); // does only check Attribute

         }

             

         // Check column