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 2016/02/01 14:18:31 UTC

[2/3] empire-db git commit: EMPIREDB-235

http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/MenuListTag.java
----------------------------------------------------------------------
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/MenuListTag.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/MenuListTag.java
index 4078ee1..a7258db 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/MenuListTag.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/MenuListTag.java
@@ -35,13 +35,16 @@ public class MenuListTag extends UIOutput implements NamingContainer
     // Logger
     // private static final Logger log = LoggerFactory.getLogger(MenuTag.class);
     
-    protected final TagEncodingHelper helper = new TagEncodingHelper(this, "eMenuList");
+    private final TagEncodingHelper helper = new TagEncodingHelper(this, "eMenuList");
     
     private String currentId = null; 
     private String currentClass = null; 
+    // private String prevMenuId = null; 
     // private String enabledClass = null; 
+    private String parentClass = null;
     private String disabledClass = null; 
     private String expandedClass = null;
+    private String itemWrapTag = null;
     private String defaultItemClass = null; // e.g. "level{}"
     private int level = 0;
 
@@ -58,7 +61,7 @@ public class MenuListTag extends UIOutput implements NamingContainer
         // call base
         super.encodeBegin(context);
         
-        initMenuAttributes();
+        initMenuAttributes(context);
 
         // render components
         ResponseWriter writer = context.getResponseWriter();
@@ -66,16 +69,19 @@ public class MenuListTag extends UIOutput implements NamingContainer
         // writeAttribute(writer, map, "id");
         helper.writeAttribute(writer, "class", helper.getTagAttributeString("styleClass"));
         helper.writeAttribute(writer, "style", helper.getTagAttributeString("style"));
+        // previousId
+        /*
+        if (prevMenuId!=null)
+            helper.writeAttribute(writer, "previousId", prevMenuId);
+        */    
     }
 
-    /*
     @Override
     public boolean getRendersChildren()
     {
         boolean test = super.getRendersChildren();
         return test;
     }
-    */
     
     @Override
     public void encodeChildren(FacesContext context)
@@ -95,29 +101,48 @@ public class MenuListTag extends UIOutput implements NamingContainer
         writer.endElement("ul");
     }
     
-    private void initMenuAttributes()
+    private void initMenuAttributes(FacesContext context)
     {        
-        currentId        = helper.getTagAttributeString("currentId"); 
-        currentClass     = helper.getTagAttributeString("currentClass"); 
-        // enabledClass  = StringUtils.toString(map.get("enabledClass")); 
-        disabledClass    = helper.getTagAttributeString("disabledClass"); 
-        expandedClass    = helper.getTagAttributeString("expandedClass");
+        currentId       = helper.getTagAttributeString("currentId"); 
+        currentClass    = helper.getTagAttributeString("currentClass"); 
+        // enabledClass = StringUtils.toString(map.get("enabledClass")); 
+        disabledClass   = helper.getTagAttributeString("disabledClass"); 
+        parentClass     = helper.getTagAttributeString("parentClass");
+        expandedClass   = helper.getTagAttributeString("expandedClass");
+        itemWrapTag     = helper.getTagAttributeString("itemWrapTag");
         defaultItemClass = helper.getTagAttributeString("defaultItemClass");
-        
+
+        // remember previousMenu (may be used by JavaScript)
+        /*
+        if (currentId!=null)
+        {   // StoreID on Session and set lastId
+            Map<String,Object> sessionMap = context.getExternalContext().getSessionMap();
+            String attrName = this.getClientId()+":prevMenuId";
+            prevMenuId = StringUtils.toString(sessionMap.get(attrName));
+            if (StringUtils.compareEqual(prevMenuId, currentId, false)==false)
+                sessionMap.put(attrName, currentId);
+        }
+        */
+
+        // find parent
         MenuListTag parent = getParentMenu();
         if (parent==null)
             return;
         
         if (currentId==null)
-            currentId = parent.getCurrentId();  
+            currentId = parent.getCurrentId();
         if (currentClass==null)
             currentClass = parent.getCurrentClass();  
         // if (enabledClass==null)
         //     enabledClass = parent.getEnabledClass();
         if (disabledClass==null)
             disabledClass = parent.getDisabledClass();
+        if (parentClass==null)
+            parentClass = parent.getParentClass();
         if (expandedClass==null)
             expandedClass = parent.getExpandedClass();
+        if (itemWrapTag==null)
+            itemWrapTag = parent.itemWrapTag;
         if (defaultItemClass==null)
             defaultItemClass = parent.defaultItemClass;
         
@@ -149,6 +174,13 @@ public class MenuListTag extends UIOutput implements NamingContainer
     {
         return currentClass;
     }
+    
+    /*
+    public String getPreviousMenuId()
+    {
+        return prevMenuId;
+    }
+    */
 
     /*
     public String getEnabledClass()
@@ -162,10 +194,20 @@ public class MenuListTag extends UIOutput implements NamingContainer
         return disabledClass;
     }
 
+    public String getParentClass()
+    {
+        return parentClass;
+    }
+
     public String getExpandedClass()
     {
         return expandedClass;
     }
+
+    public String getItemWrapTag()
+    {
+        return itemWrapTag;
+    }
     
     public int getLevel()
     {
@@ -204,9 +246,34 @@ public class MenuListTag extends UIOutput implements NamingContainer
         this.disabledClass = disabledClass;
     }
 
+    public void setParentClass(String parentClass)
+    {
+        this.parentClass = parentClass;
+    }
+
     public void setExpandedClass(String expandedClass)
     {
         this.expandedClass = expandedClass;
     }
 
+    public void setItemWrapTag(String itemWrapTag)
+    {
+        this.itemWrapTag = itemWrapTag;
+    }
+
+    /*
+    protected void writeAttribute(ResponseWriter writer, Map<String, Object> map, String attribute, String targetName)
+        throws IOException
+    {
+        Object value = map.get(attribute);
+        if (value != null)
+            writer.writeAttribute(targetName, value, null);
+    }
+    protected void writeAttribute(ResponseWriter writer, Map<String, Object> map, String attribute)
+        throws IOException
+    {
+        writeAttribute(writer, map, attribute, attribute);
+    }
+    */
+
 }

http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java
----------------------------------------------------------------------
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java
index 41c47cf..635234b 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java
@@ -19,12 +19,17 @@
 package org.apache.empire.jsf2.components;
 
 import java.io.IOException;
+import java.util.List;
 import java.util.Map;
 
 import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
 import javax.faces.component.UIInput;
 import javax.faces.component.html.HtmlSelectOneMenu;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
 import javax.faces.context.FacesContext;
+import javax.faces.view.AttachedObjectHandler;
 
 import org.apache.empire.commons.ObjectUtils;
 import org.apache.empire.commons.Options;
@@ -42,6 +47,8 @@ public class SelectTag extends UIInput implements NamingContainer
     // Logger
     private static final Logger log = LoggerFactory.getLogger(SelectTag.class);
 
+    private SelectInputControl control = null;
+    
     public SelectTag()
     {
         log.trace("component select created");
@@ -52,6 +59,32 @@ public class SelectTag extends UIInput implements NamingContainer
     {
         return "javax.faces.NamingContainer";
     }
+    
+    /**
+     * remember original clientId
+     * necessary only inside UIData
+     */
+    private String treeClientId = null;
+    
+    @Override
+    public boolean visitTree(VisitContext visitContext, VisitCallback callback) 
+    {
+        FacesContext context = visitContext.getFacesContext();
+        treeClientId = getClientId(context);
+        return super.visitTree(visitContext, callback);
+    }
+
+    @Override
+    public String getClientId(FacesContext context)
+    {
+        // Check if dynamic components are being created
+        if (this.treeClientId!=null && control!=null && control.isCreatingComponents())
+        {   // return the original tree client id
+            return treeClientId; 
+        }
+        // default behavior
+        return super.getClientId(context);
+    }
 
     @Override
     public void encodeBegin(FacesContext context)
@@ -65,18 +98,18 @@ public class SelectTag extends UIInput implements NamingContainer
             inputComponent = getInputComponent();
             if (inputComponent instanceof HtmlSelectOneMenu)
             {
-                SelectInputControl control = (SelectInputControl)InputControlManager.getControl(SelectInputControl.NAME);
+                this.control = (SelectInputControl) InputControlManager.getControl(SelectInputControl.NAME);
                 // disabled
                 boolean disabled = isDisabled();
-                ((HtmlSelectOneMenu)inputComponent).setDisabled(disabled);
+                ((HtmlSelectOneMenu) inputComponent).setDisabled(disabled);
                 // Options (sync)
                 Options options = getOptionList();
                 boolean hasEmpty = isAllowNull() && !options.contains("");
-                control.syncOptions((HtmlSelectOneMenu)inputComponent, textResolver, options, hasEmpty, getNullText());
-                setInputValue((HtmlSelectOneMenu)inputComponent);
+                control.syncOptions((HtmlSelectOneMenu) inputComponent, textResolver, options, hasEmpty, getNullText(), false);
+                setInputValue((HtmlSelectOneMenu) inputComponent);
             }
             else
-            {   // Something's wrong here?
+            { // Something's wrong here?
                 log.warn("WARN: Unexpected child node for {}! Child item type is {}.", getClass().getName(), inputComponent.getClass().getName());
                 inputComponent = null;
             }
@@ -85,6 +118,8 @@ public class SelectTag extends UIInput implements NamingContainer
         {
             inputComponent = createSelectOneMenu(textResolver);
             this.getChildren().add(0, inputComponent);
+            // attach events
+            attachEvents(context, inputComponent);
         }
         // render components
         inputComponent.encodeAll(context);
@@ -93,14 +128,24 @@ public class SelectTag extends UIInput implements NamingContainer
     }
 
     @Override
+    public void decode(FacesContext context)
+    {
+        for (UIComponent c : getChildren())
+        {
+            c.decode(context);
+        }
+        super.decode(context);
+    }
+
+    @Override
     public void updateModel(FacesContext context)
     {
         // check read only
         if (!isDisabled())
         {
             UIInput inputComponent = getInputComponent();
-            
-            Object value = inputComponent == null ?  "" :  inputComponent.getValue();
+
+            Object value = (inputComponent==null ? "" : inputComponent.getValue());
             if (value == null)
                 value = "";
             setValue(value);
@@ -133,7 +178,7 @@ public class SelectTag extends UIInput implements NamingContainer
         {
             return null;
         }
-        
+
         return (UIInput) getChildren().get(0);
     }
 
@@ -141,7 +186,9 @@ public class SelectTag extends UIInput implements NamingContainer
     {
         Object options = getAttributes().get("options");
         if (!(options instanceof Options))
+        {
             return new Options();
+        }
         return ((Options) options);
     }
 
@@ -165,11 +212,11 @@ public class SelectTag extends UIInput implements NamingContainer
 
     private UIInput createSelectOneMenu(TextResolver textResolver)
     {
-        SelectInputControl control = (SelectInputControl)InputControlManager.getControl(SelectInputControl.NAME);
+        this.control = (SelectInputControl) InputControlManager.getControl(SelectInputControl.NAME);
         HtmlSelectOneMenu input = control.createMenuComponent(this);
         // css style
         String userStyle = StringUtils.toString(getAttributes().get("styleClass"));
-        String cssStyle  = TagEncodingHelper.getTagStyleClass("eSelect", null, null, userStyle);
+        String cssStyle = TagEncodingHelper.getTagStyleClass("eSelect", null, null, userStyle);
         input.setStyleClass(cssStyle);
         // other attributes
         copyAttributes(input);
@@ -187,14 +234,14 @@ public class SelectTag extends UIInput implements NamingContainer
         setInputValue(input);
         return input;
     }
-    
+
     private void setInputValue(HtmlSelectOneMenu input)
     {
         Object value = getValue();
-        if (value!=null)
+        if (value != null)
         {
             if (value.getClass().isEnum())
-                value = ((Enum<?>)value).name();
+                value = ((Enum<?>) value).name();
             else
                 value = String.valueOf(value);
         }
@@ -203,14 +250,49 @@ public class SelectTag extends UIInput implements NamingContainer
 
     private void copyAttributes(HtmlSelectOneMenu input)
     {
+        // set id
+        String inputId = this.getId();
+        if (StringUtils.isNotEmpty(inputId))
+        { // remove trailing underscore (workaround since parent and child may not have the same name)
+            if (inputId.endsWith("_"))
+            {
+                inputId = inputId.substring(0, inputId.length() - 1);
+            }
+            input.setId(inputId);
+        }
+
         Map<String, Object> attr = getAttributes();
         Object value;
         if ((value = attr.get("style")) != null)
+        {
             input.setStyle(StringUtils.toString(value));
+        }
         if ((value = attr.get("tabindex")) != null)
+        {
             input.setTabindex(StringUtils.toString(value));
+        }
         if ((value = attr.get("onchange")) != null)
+        {
             input.setOnchange(StringUtils.toString(value));
+        }
+    }
+
+    protected void attachEvents(FacesContext context, UIInput inputComponent)
+    {
+        // Events available?
+        @SuppressWarnings("unchecked")
+        List<AttachedObjectHandler> result = (List<AttachedObjectHandler>) getAttributes().get("javax.faces.RetargetableHandlers");
+        if (result == null)
+        {
+            return;
+        }
+        // Attach Events
+        for (AttachedObjectHandler aoh : result)
+        {
+            aoh.applyAttachedObject(context, inputComponent);
+        }
+        // remove
+        result.clear();
+        getAttributes().remove("javax.faces.RetargetableHandlers");
     }
-    
 }

http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/TabPageTag.java
----------------------------------------------------------------------
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/TabPageTag.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/TabPageTag.java
new file mode 100644
index 0000000..5d847f0
--- /dev/null
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/TabPageTag.java
@@ -0,0 +1,92 @@
+/*
+ * 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.jsf2.components;
+
+import java.io.IOException;
+
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UINamingContainer;
+import javax.faces.component.UIOutput;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.empire.jsf2.controls.InputControl;
+import org.apache.empire.jsf2.utils.TagEncodingHelper;
+
+public class TabPageTag extends UIOutput implements NamingContainer
+{
+    // Logger
+    // private static final Logger log = LoggerFactory.getLogger(MenuTag.class);
+    
+    private final TagEncodingHelper helper = new TagEncodingHelper(this, "eTabPage");
+
+    @Override
+    public String getFamily()
+    {
+        return UINamingContainer.COMPONENT_FAMILY; 
+    }
+        
+    @Override
+    public void encodeBegin(FacesContext context)
+        throws IOException
+    {
+        // call base
+        super.encodeBegin(context);
+        
+        // render components
+        ResponseWriter writer = context.getResponseWriter();
+        writer.startElement(InputControl.HTML_TAG_TR, this);
+        writer.writeAttribute(InputControl.HTML_ATTR_ID, getClientId(), null);
+        helper.writeAttribute(writer, InputControl.HTML_ATTR_CLASS, helper.getTagAttributeString("styleClass"));
+        helper.writeAttribute(writer, InputControl.HTML_ATTR_STYLE, helper.getTagAttributeString("style"));
+        // TabPage
+        writer.startElement(InputControl.HTML_TAG_TD, this);
+        writer.writeAttribute(InputControl.HTML_ATTR_CLASS, "eTabPage", null);
+    }
+
+    @Override
+    public boolean getRendersChildren()
+    {
+        return super.getRendersChildren();
+    }
+    
+    @Override
+    public void encodeChildren(FacesContext context)
+        throws IOException
+    {
+        super.encodeChildren(context);
+    }
+
+    @Override
+    public void encodeEnd(FacesContext context)
+        throws IOException
+    {
+        // call base
+        super.encodeEnd(context);
+        // close
+        ResponseWriter writer = context.getResponseWriter();
+        writer.endElement(InputControl.HTML_TAG_TD);
+        writer.endElement(InputControl.HTML_TAG_TR);
+    }
+
+    public String getTabLabel()
+    {
+        return helper.getTagAttributeString("title");
+    }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/TabViewTag.java
----------------------------------------------------------------------
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/TabViewTag.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/TabViewTag.java
new file mode 100644
index 0000000..23046c1
--- /dev/null
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/TabViewTag.java
@@ -0,0 +1,387 @@
+/*
+ * 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.jsf2.components;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+import javax.faces.component.NamingContainer;
+import javax.faces.component.StateHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UINamingContainer;
+import javax.faces.component.UIOutput;
+import javax.faces.component.html.HtmlCommandLink;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.ActionEvent;
+import javax.faces.event.ActionListener;
+
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.exceptions.UnexpectedReturnValueException;
+import org.apache.empire.jsf2.app.FacesUtils;
+import org.apache.empire.jsf2.controls.InputControl;
+import org.apache.empire.jsf2.controls.InputControlManager;
+import org.apache.empire.jsf2.utils.TagEncodingHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TabViewTag extends UIOutput implements NamingContainer
+{
+    // Logger
+    // private static final Logger log = LoggerFactory.getLogger(MenuTag.class);
+    private static final Logger     log                    = LoggerFactory.getLogger(TabViewTag.class);
+
+    private final String            TAB_STYLE_CLASS        = "eTabView";
+
+    private final String            TAB_ACTIVE_INDEX       = "activeIndex";
+
+    private final String            TABLINK_ID_PREFIX      = "tabLink";
+
+    private final String            TAB_RENDERED_ATTRIBUTE = "visible";
+
+    private final TagEncodingHelper helper                 = new TagEncodingHelper(this, this.TAB_STYLE_CLASS);
+
+    public static class TabPageActionListener implements ActionListener, StateHolder
+    {
+
+        // private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
+        // private static final Object[] EMPTY_PARAMS = new Object[0];
+
+        private String  clientId;
+        private boolean isTransient = false;
+
+        /** Creates a new instance of MethodExpressionActionListener */
+        public TabPageActionListener()
+        {
+            // constructor for state-saving 
+        }
+
+        public TabPageActionListener(String clientId)
+        {
+            // constructor for state-saving
+            this.clientId = clientId;
+        }
+
+        @Override
+        public void processAction(ActionEvent actionEvent)
+            throws AbortProcessingException
+        {
+            // UIComponent findBase = ComponentUtils.findComponent(null, clientId, separatorChar);
+            FacesContext fc = FacesContext.getCurrentInstance();
+            UIComponent tabView = FacesUtils.getWebApplication().findComponent(fc, this.clientId, null);
+            if (!(tabView instanceof TabViewTag))
+            {
+                throw new UnexpectedReturnValueException(tabView, "findComponent");
+            }
+            // Invoke
+            TabViewTag tvt = (TabViewTag) tabView;
+            tvt.setActiveTab(actionEvent);
+        }
+
+        @Override
+        public void restoreState(FacesContext context, Object state)
+        {
+            // clientId = (String) ((Object[]) state)[0];
+            this.clientId = (String) state;
+        }
+
+        @Override
+        public Object saveState(FacesContext context)
+        {
+            // return new Object[] { clientId };
+            return this.clientId;
+        }
+
+        @Override
+        public void setTransient(boolean newTransientValue)
+        {
+            this.isTransient = newTransientValue;
+        }
+
+        @Override
+        public boolean isTransient()
+        {
+            return this.isTransient;
+        }
+    }
+    
+    public TabViewTag()
+    {
+        log.trace("TabViewTag created");
+    }
+
+    @Override
+    public String getFamily()
+    {
+        return UINamingContainer.COMPONENT_FAMILY;
+    }
+
+    @Override
+    public void encodeBegin(FacesContext context)
+        throws IOException
+    {
+        // call base
+        super.encodeBegin(context);
+
+        // registerTabViewBean
+        // context.getExternalContext().getRequestMap().put("tabView", this);
+
+        // render components
+        ResponseWriter writer = context.getResponseWriter();
+        writer.startElement(InputControl.HTML_TAG_DIV, this);
+        writer.writeAttribute(InputControl.HTML_ATTR_ID, getClientId(), null);
+        writer.writeAttribute(InputControl.HTML_ATTR_CLASS, this.helper.getTagStyleClass(), null);
+        this.helper.writeAttribute(writer, InputControl.HTML_ATTR_STYLE, this.helper.getTagAttributeString("style"));
+
+        // The Tabs
+        writer.startElement(InputControl.HTML_TAG_TABLE, this);
+        writer.writeAttribute(InputControl.HTML_ATTR_CLASS, "eTabBar", null);
+        writer.startElement(InputControl.HTML_TAG_TR, this);
+        encodeTabs(context, writer);
+        writer.startElement(InputControl.HTML_TAG_TD, this);
+        writer.writeAttribute(InputControl.HTML_ATTR_CLASS, "eTabBarEmpty", null);
+        writer.endElement(InputControl.HTML_TAG_TD);
+        writer.endElement(InputControl.HTML_TAG_TR);
+        writer.endElement(InputControl.HTML_TAG_TABLE);
+
+        // The Pages
+        writer.startElement(InputControl.HTML_TAG_TABLE, this);
+        writer.writeAttribute(InputControl.HTML_ATTR_CLASS, "eTabPanel", null);
+        String minHeight = this.helper.getTagAttributeString("minHeight");
+        if (StringUtils.isNotEmpty(minHeight))
+        {
+            writer.writeAttribute(InputControl.HTML_ATTR_STYLE, "min-height:" + minHeight, null);
+        }
+    }
+
+    @Override
+    public boolean getRendersChildren()
+    {
+        return super.getRendersChildren();
+    }
+
+    @Override
+    public void encodeChildren(FacesContext context)
+        throws IOException
+    {
+        super.encodeChildren(context);
+    }
+
+    @Override
+    public void encodeEnd(FacesContext context)
+        throws IOException
+    {
+        // call base
+        super.encodeEnd(context);
+        // close
+        ResponseWriter writer = context.getResponseWriter();
+        writer.endElement(InputControl.HTML_TAG_TABLE);
+        writer.endElement(InputControl.HTML_TAG_DIV);
+    }
+
+    @Override
+    public void decode(FacesContext context)
+    {
+        for (UIComponent c : getChildren())
+        {
+            c.decode(context);
+        }
+        super.decode(context);
+    }
+
+    /*
+    @Override
+    public void processDecodes(FacesContext context)
+    {
+        super.processDecodes(context);
+    }
+    */
+
+    private void encodeTabs(FacesContext context, ResponseWriter writer)
+        throws IOException
+    {
+        Iterator<UIComponent> ci = getFacetsAndChildren();
+        if (ci.hasNext() == false)
+        {
+            log.warn("Invalid TabPage definition!");
+            return;
+        }
+        UIComponent panel = ci.next();
+        int index = 0;
+        int activeIndex = getActivePageIndex();
+        // Patch for MOJARRA: Remove HtmlCommandLinks
+        List<UIComponent> chk = panel.getChildren();
+        for (int i = chk.size()-1; i>=0; i--)
+        {
+            if ((chk.get(i) instanceof HtmlCommandLink))
+                chk.remove(i);
+        }
+        // Create Page Links
+        for (UIComponent c : panel.getChildren())
+        { // Find Tab pages
+            if (!(c instanceof TabPageTag))
+            {
+                continue;
+            }
+            // found
+            boolean active = (index == activeIndex);
+            TabPageTag page = (TabPageTag) c;
+
+            // render tab-link? default is true
+            boolean rendered = ObjectUtils.getBoolean(ObjectUtils.coalesce(page.getAttributes().get(this.TAB_RENDERED_ATTRIBUTE), true));
+            if (!rendered)
+            {
+                // dont render content
+                page.setRendered(false);
+                continue;
+            }
+
+            boolean disabled = ObjectUtils.getBoolean(TagEncodingHelper.getTagAttributeValue(page, "disabled"));
+            writer.startElement(InputControl.HTML_TAG_TD, this);
+            // tab label
+            String styleClass = "eTabLabel";
+            if (active)
+            {
+                styleClass += " eTabActive";
+            }
+            else if (disabled)
+            {
+                styleClass += " eTabDisabled";
+            }
+            writer.writeAttribute(InputControl.HTML_ATTR_CLASS, styleClass, null);
+            // encode Link
+            encodeTabLink(context, writer, index, page, (active || disabled));
+            writer.endElement(InputControl.HTML_TAG_TD);
+            // set rendered
+            page.setRendered(active);
+            // next
+            index++;
+        }
+    }
+
+    private void encodeTabLink(FacesContext context, ResponseWriter writer, int index, TabPageTag page, boolean disabled)
+        throws IOException
+    {
+        // Add component
+        HtmlCommandLink link = null;
+        List<UIComponent> tabLinks = getChildren();
+        if (tabLinks.size() > index)
+        {
+            UIComponent c = tabLinks.get(index);
+            if (c instanceof HtmlCommandLink)
+            {
+                link = (HtmlCommandLink) c;
+            }
+            else
+            { // Something's wrong here?
+                log.error("INFO: Unexpected child node for {}! Child item type is {}.", getClass().getName(), c.getClass().getName());
+                // encode anyway
+                c.setRendered(true);
+                c.encodeAll(context);
+                c.setRendered(false); // Don't render twice!
+                return;
+            }
+        }
+        if (link == null)
+        {   // create the tab-Link   
+            String linkId = this.TABLINK_ID_PREFIX + String.valueOf(index);
+            link = createCommandLink(context, linkId);
+            tabLinks.add(index, link);
+            // Set TabPageActionListener
+            TabPageActionListener tpal = new TabPageActionListener(this.getClientId());
+            link.addActionListener(tpal);
+        }
+        // init linkComponent
+        link.setValue(page.getTabLabel());
+        link.setDisabled(disabled);
+        // Set Style
+        String styleClass = "eTabLink";
+        link.setStyleClass(styleClass);
+
+        // encode link
+        link.setRendered(true);
+        link.encodeAll(context);
+        link.setRendered(false); // Don't render twice!
+    }
+
+    private HtmlCommandLink createCommandLink(FacesContext context, String linkId)
+    {
+        // CommandLink link 
+        HtmlCommandLink link = InputControlManager.createComponent(context, HtmlCommandLink.class);
+        link.setId(linkId);
+        return link;
+    }
+
+    public int getActivePageIndex()
+    {
+        Object active = this.helper.getTagAttributeValue(this.TAB_ACTIVE_INDEX);
+        return ObjectUtils.getInteger(active);
+    }
+
+    public void setActivePageIndex(int activeIndex)
+    {
+        ValueExpression ve = this.getValueExpression(this.TAB_ACTIVE_INDEX);
+        if (ve != null)
+        { // set active index
+            FacesContext fc = FacesUtils.getContext();
+            ve.setValue(fc.getELContext(), activeIndex);
+        }
+        else
+        { // save activeIndex
+            getAttributes().put(this.TAB_ACTIVE_INDEX, activeIndex);
+        }
+    }
+
+    public void setActiveTab(ActionEvent event)
+    {
+        log.debug("setActiveTab");
+        // done
+        UIComponent comp = event.getComponent();
+        String tabNo = comp.getId().substring(this.TABLINK_ID_PREFIX.length());
+        int pageIndex = ObjectUtils.getInteger(tabNo);
+        if (pageIndex == getActivePageIndex())
+        {   // already set
+            log.warn("setActiveTab is called for active page!");
+            return;
+        }
+        
+        // set new Page
+        setActivePageIndex(pageIndex);
+
+        // TabChangeListener
+        Object tcl = getAttributes().get("tabChangedListener");
+        if (tcl != null)
+        {
+            if (!(tcl instanceof MethodExpression))
+            {
+                log.error("tabChangedListener is not a valid method expression!");
+                return;
+            }
+            FacesContext fc = FacesUtils.getContext();
+            MethodExpression methodExpression = (MethodExpression) tcl;
+            methodExpression.invoke(fc.getELContext(), new Object[] { pageIndex });
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/CheckboxInputControl.java
----------------------------------------------------------------------
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/CheckboxInputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/CheckboxInputControl.java
index fba03fd..9ab268b 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/CheckboxInputControl.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/CheckboxInputControl.java
@@ -27,14 +27,13 @@ import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 
 import org.apache.empire.commons.ObjectUtils;
-import org.apache.empire.exceptions.InternalException;
 import org.apache.empire.exceptions.UnexpectedReturnValueException;
 
 public class CheckboxInputControl extends InputControl
 {
     public static final String NAME = "checkbox";
 
-    private Class<? extends javax.faces.component.html.HtmlSelectBooleanCheckbox> inputComponentClass;
+    private final Class<? extends javax.faces.component.html.HtmlSelectBooleanCheckbox> inputComponentClass;
 
     public CheckboxInputControl(Class<? extends HtmlSelectBooleanCheckbox> inputComponentClass)
     {
@@ -47,57 +46,69 @@ public class CheckboxInputControl extends InputControl
         this(javax.faces.component.html.HtmlSelectBooleanCheckbox.class);
     }
 
-	@Override
-	public void renderValue(ValueInfo vi, ResponseWriter writer)
-		throws IOException
-	{
-		boolean value = (Boolean) vi.getValue(true);
-		writer.startElement("div", null);
-		writer.writeAttribute("class", value ? "eTypeBoolTrue" : "eTypeBoolFalse", null);
-		writer.append("&nbsp;");
-		writer.endElement("div");
-	}
-	
+    @Override
+    public void renderValue(ValueInfo vi, ResponseWriter writer)
+        throws IOException
+    {
+        boolean value = (Boolean) vi.getValue(true);
+        writer.startElement(HTML_TAG_DIV, null);
+        writer.writeAttribute(HTML_ATTR_CLASS, value ? "eTypeBoolTrue" : "eTypeBoolFalse", null);
+        writer.append(HTML_EXPR_NBSP);
+        writer.endElement(HTML_TAG_DIV);
+    }
+
     @Override
     protected void createInputComponents(UIComponent parent, InputInfo ii, FacesContext context, List<UIComponent> compList)
     {
         HtmlSelectBooleanCheckbox input;
-        if (compList.size()==0)
-        {   try {
-                input = inputComponentClass.newInstance();
-            } catch (InstantiationException e1) {
-                throw new InternalException(e1);
-            } catch (IllegalAccessException e2) {
-                throw new InternalException(e2);
-            }
+        if (compList.size() == 0)
+        { // create component
+            input = InputControlManager.createComponent(context, this.inputComponentClass);
+            // copy attributes
             copyAttributes(parent, ii, input);
             // add
             compList.add(input);
         }
         else
-        {   // check type
+        { // check type
             UIComponent comp = compList.get(0);
             if (!(comp instanceof HtmlSelectBooleanCheckbox))
                 throw new UnexpectedReturnValueException(comp.getClass().getName(), "compList.get");
             // cast
-            input = (HtmlSelectBooleanCheckbox)comp;
+            input = (HtmlSelectBooleanCheckbox) comp;
         }
 
         // disabled
-        boolean disabled = ii.isDisabled(); 
+        boolean disabled = ii.isDisabled();
         input.setDisabled(disabled);
 
         // style
         addRemoveDisabledStyle(input, input.isDisabled());
-        
+
         // Set Value
         setInputValue(input, ii);
     }
-    
+
+    @Override
+    protected void updateInputState(List<UIComponent> compList, InputInfo ii, FacesContext context)
+    {
+        UIComponent comp = compList.get(0);
+        if (!(comp instanceof HtmlSelectBooleanCheckbox))
+        {
+            throw new UnexpectedReturnValueException(comp.getClass().getName(), "compList.get(0)");
+        }
+        HtmlSelectBooleanCheckbox input = (HtmlSelectBooleanCheckbox) comp;
+        // disabled
+        boolean disabled = ii.isDisabled();
+        input.setDisabled(disabled);
+        // style
+        addRemoveDisabledStyle(input, input.isDisabled());
+    }
+
     @Override
     protected Object parseInputValue(String value, InputInfo ii)
     {
         return ObjectUtils.getBoolean(value);
     }
-    
+
 }

http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
----------------------------------------------------------------------
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
index de9de79..190777e 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
@@ -42,38 +42,60 @@ import org.slf4j.LoggerFactory;
 
 public abstract class InputControl
 {
-    private static final Logger log = LoggerFactory.getLogger(InputControl.class);
-    
-    // Special Input Column Attributes
-    public static final String NUMBER_TYPE_ATTRIBUTE      = "numberType";   // "Integer", "Currency", "Percent"  
-    public static final String NUMBER_GROUPSEP_ATTRIBUTE  = "numberGroupSeparator"; // boolean
-    public static final String NUMBER_FRACTION_DIGITS     = "numberFractionDigits"; // integer
-    public static final String MINVALUE_ATTRIBUTE         = "minValue";
-    public static final String MAXVALUE_ATTRIBUTE         = "maxValue";
-    public static final String CURRENCY_CODE_ATTRIBUTE    = "currencyCode";   // "ISO 4217 code of the currency"  
+
+    private static final Logger log                   = LoggerFactory.getLogger(InputControl.class);
 
     // format attributes
-    public static final String FORMAT_NULL = "null:";
-    public static final String FORMAT_NULL_ATTRIBUTE = "format:null";
+    public static final String  FORMAT_NULL           = "null:";
+    public static final String  FORMAT_NULL_ATTRIBUTE = "format:null";
+    
+    // HTML-TAGS
+    public static final String  HTML_TAG_DIV          = "div"; 
+    public static final String  HTML_TAG_SPAN         = "span";
+    public static final String  HTML_TAG_TABLE        = "table";
+    public static final String  HTML_TAG_TR           = "tr";
+    public static final String  HTML_TAG_TD           = "td";
+    public static final String  HTML_TAG_INPUT        = "input";
+    public static final String  HTML_TAG_LABEL        = "label";
+    
+    // HTML-ATTRIBUTES
+    public static final String  HTML_ATTR_ID          = "id";
+    public static final String  HTML_ATTR_CLASS       = "class";
+    public static final String  HTML_ATTR_STYLE       = "style";
+    public static final String  HTML_ATTR_TYPE        = "type";
+    public static final String  HTML_ATTR_DISABLED    = "disabled";
+    public static final String  HTML_ATTR_CHECKED     = "checked";
     
+    // HTML
+    public static String HTML_EXPR_NBSP = "&nbsp;";
+
     public InputControl()
     {
-        log.info("InputControl of class {} created.", getClass().getName());
+        InputControl.log.info("InputControl of class {} created.", getClass().getName());
     }
-    
+
     /**
      * This interface allows access to a value and its metainformation
      * used with the renderData function
-     */ 
+     */
     public interface ValueInfo
     {
         Column getColumn();
+
         Options getOptions();
+
         Object getValue(boolean evalExpression);
-        String getFormat();    // Custom Formatting options specific to each InputControl-type
+
+        String getFormat(); // Custom Formatting options specific to each InputControl-type
+
         Locale getLocale();
+
         String getText(String key);
+
         TextResolver getTextResolver();
+
+        String getStyleClass(String addlStyle);
+
         /*
         Object getNullValue();
         String getOnclick();
@@ -82,24 +104,32 @@ public abstract class InputControl
         String getCssStyle();
         String getId();
         */
+        
+        boolean isInsideUIData();
     }
 
     /**
      * This interface extends the value information by information about the input control
      * used with the renderInput function
-     */ 
+     */
     public interface InputInfo extends ValueInfo
     {
         // perform action 
         void setValue(Object value);
+
         void validate(Object value);
+
         boolean isRequired();
+
         boolean isDisabled(); // disabled or readOnly
+
         boolean isFieldReadOnly(); // not disabled only readOnly (for input[type=text] only!)
         // input
+
         String getInputId();
-        String getStyleClass(String addlStyle);
+
         boolean hasError();
+
         /*
         String getName();
         String getTabindex();
@@ -109,74 +139,105 @@ public abstract class InputControl
         String getOnfocus();
         String getOnblur();
         */
-        Object getAttribute(String name);   /* gets tag attribute only */
+        Object getAttribute(String name); /* gets tag attribute only */
+
         Object getAttributeEx(String name); /* check Column attributes too, and resolves references to other columns. */
     }
-    
+
     private String name;
-    
+
     protected InputControl(String name)
     {
         this.name = name;
     }
-    
+
     public final String getName()
     {
-        return name;
+        return this.name;
     }
-    
+
     public String getLabelForId(InputInfo ii)
     {
         return ii.getInputId();
     }
-
+    
+    /**
+     * Flag indicating whether child components are being created
+     */
+    private boolean creatingComponents = false;
+    public boolean isCreatingComponents()
+    {
+        return this.creatingComponents;
+    }
+    
     /* Value */
     public void renderValue(ValueInfo vi, ResponseWriter writer)
         throws IOException
     {
         String text = formatValue(vi);
-        writer.append((StringUtils.isEmpty(text) ? "&nbsp;" : text));
+        writer.append((StringUtils.isEmpty(text) ? HTML_EXPR_NBSP : text));
     }
 
-    /* Input */
+    /* renderInput */ 
     public void renderInput(UIComponent comp, InputInfo ii, FacesContext context, boolean encode)
         throws IOException
     {
-        // createInputComponents 
-        createInputComponents(comp, ii, context, comp.getChildren());
+        boolean resetChildId = comp.getChildren().isEmpty();
+        // createInputComponents
+        try {
+            this.creatingComponents = true;
+            createInputComponents(comp, ii, context, comp.getChildren());
+        } finally {
+            this.creatingComponents = false;
+        }
+        
         // Encode all
         if (!encode)
             return;
         for (UIComponent child : comp.getChildren())
-        {
+        {   // reset child-id
+            // necessary only inside UIData
+            if (resetChildId && child.getId()!=null)
+                child.setId(child.getId());
+            // encode now
             child.encodeAll(context);
         }
     }
     
+    public void updateInputState(UIComponent parent, InputInfo ii, FacesContext context)
+    {
+        List<UIComponent> cl = parent.getChildren(); 
+        if (cl.isEmpty())
+            return;
+        updateInputState(cl, ii, context);
+    }
+    
     public void postUpdateModel(UIComponent comp, InputInfo ii, FacesContext fc)
     {
         UIInput input = getInputComponent(comp);
-        if (input==null)
+        if (input == null)
             return; /* May want to override this */
         // Clear submitted value
         clearSubmittedValue(input);
     }
-    
+
     public Object getInputValue(UIComponent comp, InputInfo ii, boolean submitted)
     {
         UIInput input = getInputComponent(comp);
-        if (input==null)
+        if (input == null)
         {   // throw new ObjectNotValidException(this);
             return null; // ignore
-        }    
+        }
         
         // Get value from Input
         Object value;
         if (submitted)
         {   // get submitted value
             value = input.getSubmittedValue();
-            if (value == null && input.isLocalValueSet()) // MyFaces Patch!
+            if (value == null && input.isLocalValueSet()) // required for MyFaces!
             {   // take local value
+                if (log.isDebugEnabled())
+                    log.debug("No submitted value but local value available for InputComponent {}. Local value is '{}'", input.getClientId(), input.getLocalValue());
                 value = input.getLocalValue();
                 if (value == null)
                 {   // Empty-String
@@ -222,43 +283,43 @@ public abstract class InputControl
 
     protected void setInputValue(UIInput input, InputInfo ii)
     {
-
         // Restore submitted value
         FacesContext fc = FacesContext.getCurrentInstance();
         Map<String, Object> reqMap = fc.getExternalContext().getRequestMap();
         String clientId = input.getClientId();
         if (reqMap.containsKey(clientId))
-        {   // Set the local value from the request map
+        { // Set the local value from the request map
             Object value = reqMap.get(clientId);
-            if (input.isLocalValueSet()==false)  // Patch for MyFaces?  
-                input.setSubmittedValue(value);  // Always for Mojarra!
+            if (input.isLocalValueSet() == false)
+                input.setSubmittedValue(value);
             return;
         }
-        else if (input.getSubmittedValue()!=null) //  && FacesUtils.isClearSubmittedValues(fc)
-        {   // Clear submitted value   
-            if (log.isDebugEnabled())
-                log.debug("clearing submitted value for {}. value is {}.", ii.getColumn().getName(), input.getSubmittedValue());
+        else if (input.getSubmittedValue() != null) //  && FacesUtils.isClearSubmittedValues(fc)
+        { // Clear submitted value   
+            if (InputControl.log.isDebugEnabled())
+                InputControl.log.debug("clearing submitted value for {}. value is {}.", ii.getColumn().getName(), input.getSubmittedValue());
             input.setSubmittedValue(null);
         }
-        
+
         /* -------------------------------------- */
 
         // Assign value
         Object value = ii.getValue(false);
         if (value instanceof ValueExpression)
-        {   input.setValue(null);
+        {
+            input.setValue(null);
             input.setLocalValueSet(false);
-            input.setValueExpression("value", (ValueExpression)value);
-            
+            input.setValueExpression("value", (ValueExpression) value);
+
             // Object check = ((ValueExpression)value).getValue(FacesContext.getCurrentInstance().getELContext());
             // log.info("Expression value is {}.", check);
-        }    
+        }
         else
-        {   // Set the value
+        { // Set the value
             value = formatInputValue(value, ii);
             input.setValue(value);
-        }    
-    }    
+        }
+    }
 
     protected void clearSubmittedValue(UIInput input)
     {
@@ -269,10 +330,11 @@ public abstract class InputControl
         String clientId = input.getClientId();
         if (reqMap.containsKey(clientId))
             reqMap.remove(clientId);
-    }    
+    }
 
     /**
      * Override this to format a value for output
+     * 
      * @param value
      * @param ii
      * @return
@@ -281,12 +343,12 @@ public abstract class InputControl
     {
         return value;
     }
-    
+
     protected Object parseInputValue(String value, InputInfo ii)
     {
         return value;
     }
-    
+
     /* validate 
     public boolean validateValue(UIComponent comp, InputInfo ii, FacesContext context)
     {
@@ -325,31 +387,28 @@ public abstract class InputControl
         return true;
     }
     */
-    
+
     /* Input helpers */
     protected abstract void createInputComponents(UIComponent parent, InputInfo ii, FacesContext context, List<UIComponent> compList);
+
+    protected abstract void updateInputState(List<UIComponent> compList, InputInfo ii, FacesContext context);
     
-    /**
-     * returns the first UIInput component that is a direct child of the parent component
-     * @param parent the parent component which node to search for
-     * @return the first child that is a UIInput
-     */
     protected UIInput getInputComponent(UIComponent parent)
     {
         // default implementation
-        int count = parent.getChildCount(); 
-        if (count<1)
+        int count = parent.getChildCount();
+        if (count < 1)
             return null;
-        // find the UIInput component (only one allowed)
+        // find the UIInput component (only one allowed here)
         UIInput inp = null;
-        for (int i=0; i<count; i++)
-        {	// check UIInput 
-        	UIComponent comp = parent.getChildren().get(i);
-	        if (comp instanceof UIInput)
-	        {	if (inp!=null)
-		        	throw new UnexpectedReturnValueException(comp, "comp.getChildren().get("+String.valueOf(i)+")");
-		        inp = (UIInput)comp;
-	        }
+        for (int i = 0; i < count; i++)
+        { // check UIInput 
+            UIComponent comp = parent.getChildren().get(i);
+            if (comp instanceof UIInput)
+            {   if (inp != null)
+                    throw new UnexpectedReturnValueException(comp, "comp.getChildren().get(" + String.valueOf(i) + ")");
+                inp = (UIInput) comp;
+            }
         }
         // No UIInput found
         if (inp == null)
@@ -364,26 +423,21 @@ public abstract class InputControl
             // Should not happen!
             throw new UnexpectedReturnValueException(null, "comp.getChildren().get()");
         }
-        // done
+        // found one
         return inp;
     }
 
-    /**
-     * copies standard input attributes such as styleClass, style, tabindex and event handlers (onclick, onblur, etc.) from the parent component to the input  
-     * @param parent (not used) 
-     * @param ii the input info from which to obtain the attribute values 
-     * @param input the input component on which to set the attributes 
-     * @param additonalStyle additional style classes 
-     */
     protected void copyAttributes(UIComponent parent, InputInfo ii, UIInput input, String additonalStyle)
     {
         String inputId = ii.getInputId();
         if (StringUtils.isNotEmpty(inputId))
+        {
             input.getAttributes().put("id", inputId);
-        
+        }
+
         String styleClass = ii.getStyleClass(additonalStyle);
         input.getAttributes().put("styleClass", styleClass);
-        
+
         copyAttribute(ii, input, "style");
         copyAttribute(ii, input, "tabindex");
         copyAttribute(ii, input, "onchange");
@@ -395,62 +449,52 @@ public abstract class InputControl
 
         // immediate
         Object immediate = ii.getAttribute("immediate");
-        if (immediate!=null && ObjectUtils.getBoolean(immediate))
+        if (immediate != null && ObjectUtils.getBoolean(immediate))
         {
-            log.warn("Immediate attribute is not yet supported for {}!", ii.getColumn().getName());
+            InputControl.log.warn("Immediate attribute is not yet supported for {}!", ii.getColumn().getName());
             // input.setImmediate(true);
-        }    
+        }
 
         // validator
         // input.addValidator(new ColumnValueValidator(ii.getColumn()));
     }
 
-    /**
-     * copies standard input attributes such as styleClass, style, tabindex and event handlers (onclick, onblur, etc.) from the parent component to the input
-     * @param parent (not used) 
-     * @param ii the input info 
-     * @param input the input component on which to set the attributes 
-     */
     protected final void copyAttributes(UIComponent parent, InputInfo ii, UIInput input)
     {
         copyAttributes(parent, ii, input, (ii.isRequired() ? "eInpReq" : null));
     }
 
-    /**
-     * copies a single attribute
-     * @param ii
-     * @param input
-     * @param name
-     */
     protected void copyAttribute(InputInfo ii, UIInput input, String name)
     {
-        if (ii==null)
+        if (ii == null)
             throw new InvalidArgumentException("InputInfo", ii);
         // get Attribute
         Object value = ii.getAttribute(name);
-        if (value!=null)
-            input.getAttributes().put(name, value);
+        if (value == null)
+            value = ii.getColumn().getAttribute(name);
+        if (value != null)
+            input.getAttributes().put(name, String.valueOf(value));
     }
-    
+
     public void addRemoveDisabledStyle(UIInput input, boolean disabled)
     {
         addRemoveStyle(input, " eInpDis", disabled);
     }
-    
+
     public void addRemoveInvalidStyle(UIInput input, boolean invalid)
     {
         addRemoveStyle(input, " eInvalid", invalid);
     }
-    
+
     public void addRemoveStyle(UIInput input, String styleName, boolean setStyle)
     {
         String styleClass = StringUtils.toString(input.getAttributes().get("styleClass"), "");
-        boolean hasStyle = (styleClass.indexOf(styleName)>=0);
-        if (setStyle==hasStyle)
+        boolean hasStyle = (styleClass.indexOf(styleName) >= 0);
+        if (setStyle == hasStyle)
             return; // Nothing to do
         // Special IceFaces patch
         if (styleClass.endsWith("-dis"))
-            styleClass = styleClass.substring(0, styleClass.length()-4);
+            styleClass = styleClass.substring(0, styleClass.length() - 4);
         // add or remove disabled style
         if (setStyle)
             styleClass += styleName;
@@ -459,20 +503,30 @@ public abstract class InputControl
         // add Style
         input.getAttributes().put("styleClass", styleClass);
     }
-    
+
     /**
      * Returns the value formated as a string
      * this is a simple default implementation that does no type-secific formatting
      * Derived classes may override formatString an provide further formmatting
      * see TextInputControl for details
      * 
-     * @param value the value to be formatted
-     * @param vi Meta-information about the value
-     *
-     * @return the formatted value 
+     * @param value
+     *            the value to be formatted
+     * @param vi
+     *            Meta-information about the value
+     * @return the formatted value
      */
     protected String formatValue(Object value, ValueInfo vi)
     {
+        // For Enums use toString() to retrieve Value
+        if (value != null && value.getClass().isEnum() && !hasFormatOption(vi, "nolookup"))
+        { // Handle enum
+            String text = ((Enum<?>) value).toString();
+            if (text != null)
+                return vi.getText(text);
+            // Error
+            InputControl.log.error("The enum '" + ((Enum<?>) value).name() + "' has no text!");
+        }
         // Lookup and Print value
         Options options = vi.getOptions();
         if (options != null && !options.isEmpty() && !hasFormatOption(vi, "nolookup"))
@@ -481,11 +535,11 @@ public abstract class InputControl
             if (text != null)
                 return vi.getText(text);
             // Error
-            log.error("The element '" + String.valueOf(value) + "' is not part of the supplied option list.");
+            InputControl.log.error("The element '" + String.valueOf(value) + "' is not part of the supplied option list.");
         }
         // value
-        if (value==null)
-            value = getFormatOption(vi, FORMAT_NULL, FORMAT_NULL_ATTRIBUTE);
+        if (value == null)
+            value = getFormatOption(vi, InputControl.FORMAT_NULL, InputControl.FORMAT_NULL_ATTRIBUTE);
         // Convert to String
         String s = StringUtils.toString(value, "");
         if (hasFormatOption(vi, "noencode"))
@@ -504,9 +558,10 @@ public abstract class InputControl
         // boolean hasError = ((vi instanceof InputInfo) && !((InputInfo)vi).isValid()); 
         return formatValue(vi.getValue(true), vi);
     }
-    
+
     /**
      * escapes a String for html
+     * 
      * @param text
      * @return the escaped html String
      */
@@ -515,24 +570,27 @@ public abstract class InputControl
         // TODO
         return text;
     }
-    
+
     /**
      * checks if a particular formating option has been specified.
-     * @param vi the value info
-     * @param option the formating option to check
-     * @return true if the requested formating option has been specified or false otherwise 
+     * 
+     * @param vi
+     *            the value info
+     * @param option
+     *            the formating option to check
+     * @return true if the requested formating option has been specified or false otherwise
      */
     protected boolean hasFormatOption(ValueInfo vi, String option)
     {
         String format = vi.getFormat();
-        return (format!=null ? format.indexOf(option)>=0 : false);
+        return (format != null ? format.indexOf(option) >= 0 : false);
     }
-    
+
     protected String getFormatOption(ValueInfo vi, String option)
     {
         // Is unit supplied with format
         String format = vi.getFormat();
-        if (format==null)
+        if (format == null)
             return null;
         // Check for option
         int beg = format.indexOf(option);
@@ -540,7 +598,7 @@ public abstract class InputControl
             return null;
         // Find
         beg = beg + option.length();
-        int end = format.indexOf(';', beg+1);
+        int end = format.indexOf(';', beg + 1);
         if (end < beg)
             return format.substring(beg);
         // The cbValue
@@ -550,7 +608,7 @@ public abstract class InputControl
     protected Object getFormatOption(ValueInfo vi, String option, String columnAttributeName)
     {
         String format = getFormatOption(vi, option);
-        return (format!=null) ? format : vi.getColumn().getAttribute(columnAttributeName); 
+        return (format != null) ? format : vi.getColumn().getAttribute(columnAttributeName);
     }
 
     protected String getFormatString(ValueInfo vi, String option, String columnAttributeName)
@@ -562,5 +620,5 @@ public abstract class InputControl
     {
         return ObjectUtils.getInteger(getFormatOption(vi, option, columnAttributeName));
     }
-    
+
 }

http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControlManager.java
----------------------------------------------------------------------
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControlManager.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControlManager.java
index c9e13a0..c2fc8f7 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControlManager.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControlManager.java
@@ -18,12 +18,26 @@
  */
 package org.apache.empire.jsf2.controls;
 
+import java.lang.reflect.Field;
 import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.exceptions.InternalException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public final class InputControlManager
 {
+    private static final Logger log = LoggerFactory.getLogger(InputControlManager.class);
+
     private static Class<? extends javax.faces.component.html.HtmlOutputLabel> labelComponentClass = javax.faces.component.html.HtmlOutputLabel.class;
     
+    private static boolean showLabelRequiredMark = false;
+
     public static Class<? extends javax.faces.component.html.HtmlOutputLabel> getLabelComponentClass()
     {
         return labelComponentClass;
@@ -33,39 +47,110 @@ public final class InputControlManager
     {
         InputControlManager.labelComponentClass = labelComponentClass;
     }
+    
+    public static boolean isShowLabelRequiredMark()
+    {
+        return showLabelRequiredMark;
+    }
+    
+    public static void setShowLabelRequiredMark(boolean showLabelRequiredMark)
+    {
+        InputControlManager.showLabelRequiredMark = showLabelRequiredMark;
+    }
 
     static HashMap<String, InputControl> controlMap = null;
-    
-    static {
-        
+
+    static
+    {
+
         controlMap = new HashMap<String, InputControl>();
-        
+
         registerControl(new TextInputControl());
         registerControl(new SelectInputControl());
         registerControl(new TextAreaInputControl());
         registerControl(new CheckboxInputControl());
+        registerControl(new RadioInputControl());
         /*
-        registerControl("phone",    new PhoneInputControl());
-        registerControl("radio",    new RadioInputControl());
-        registerControl("email",    new EMailInputControl());
-        registerControl("hlink",    new HLinkInputControl());
-        registerControl("password", new PasswordInputControl());
+        registerControl(new PhoneInputControl());
+        registerControl(new EMailInputControl());
+        registerControl(new HLinkInputControl());
+        registerControl(new PasswordInputControl());
         */
     }
-    
+
     private InputControlManager()
     {
         // Default Constructor
     }
-    
+
     public static void registerControl(InputControl control)
     {
         controlMap.put(control.getName(), control);
     }
-    
+
     public static InputControl getControl(String name)
     {
         return controlMap.get(name);
     }
-    
+
+    private static Map<Class<? extends UIComponent>, String> componentTypeMap = new HashMap<Class<? extends UIComponent>, String>();
+
+    @SuppressWarnings("unchecked")
+    public static <T extends UIComponent> T createComponent(FacesContext context, Class<T> clazz)
+    {
+        // Get component type from class
+        String type = componentTypeMap.get(clazz);
+        if (type == null)
+        { // Detect type
+            try
+            { // Detect component type
+                Field field = clazz.getDeclaredField("COMPONENT_TYPE");
+                if (field != null)
+                    type = StringUtils.toString(field.get(null), ""); // Empty string is default
+                else
+                    type = ""; // Empty string is default
+                // show
+                log.debug("Component-Type for class {} is {}", clazz.getName(), type);
+            }
+            catch (SecurityException e)
+            {
+                throw new InternalException(e);
+            }
+            catch (NoSuchFieldException e)
+            {   // No COMPONENT_TYPE field
+                log.debug("No Component-Type available for class {}!", clazz.getName());
+                type = ""; // Empty string is default
+            }
+            catch (IllegalArgumentException e)
+            {
+                throw new InternalException(e);
+            }
+            catch (IllegalAccessException e)
+            {
+                throw new InternalException(e);
+            }
+            // put in map
+            componentTypeMap.put(clazz, type);
+        }
+        // Now, create the instance
+        if (StringUtils.isEmpty(type))
+        {
+            try
+            { // create instance directly
+                return clazz.newInstance();
+            }
+            catch (InstantiationException e)
+            {
+                throw new InternalException(e);
+            }
+            catch (IllegalAccessException e)
+            {
+                throw new InternalException(e);
+            }
+        }
+        // otherwise ask the application
+        return (T) context.getApplication().createComponent(type);
+
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/empire-db/blob/9176b225/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/RadioInputControl.java
----------------------------------------------------------------------
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/RadioInputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/RadioInputControl.java
new file mode 100644
index 0000000..9726bc5
--- /dev/null
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/RadioInputControl.java
@@ -0,0 +1,437 @@
+/*
+ * 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.jsf2.controls;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.el.ValueExpression;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.UISelectItem;
+import javax.faces.component.html.HtmlSelectOneRadio;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.OptionEntry;
+import org.apache.empire.commons.Options;
+import org.apache.empire.data.Column;
+import org.apache.empire.exceptions.InternalException;
+import org.apache.empire.exceptions.ItemNotFoundException;
+import org.apache.empire.exceptions.UnexpectedReturnValueException;
+import org.apache.empire.jsf2.app.TextResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RadioInputControl extends InputControl
+{
+    private static final Logger                      log                   = LoggerFactory.getLogger(RadioInputControl.class);
+
+    public static final String                       COLATTR_ABBR_OPTIONS  = "ABBR_OPTIONS";                                   // Option list for abbreviations
+
+    public static final String                       VALUE_EXPRESSION_FLAG = "VALUE_EXPRESSION_FLAG";
+
+    public static final String                       NAME                  = "radio";
+
+    private final Class<? extends HtmlSelectOneRadio> inputComponentClass;
+
+    public RadioInputControl(Class<? extends HtmlSelectOneRadio> inputComponentClass)
+    {
+        super(RadioInputControl.NAME);
+        this.inputComponentClass = inputComponentClass;
+    }
+
+    public RadioInputControl()
+    {
+        this(HtmlSelectOneRadio.class);
+    }
+
+    /* Value */
+    @Override
+    public void renderValue(ValueInfo vi, ResponseWriter writer)
+        throws IOException
+    {
+        Object value = vi.getValue(true);
+        String style = vi.getStyleClass("eCtlRadio")+" eInpDis";
+        writer.startElement(HTML_TAG_DIV, null);
+        writer.writeAttribute(HTML_ATTR_CLASS, style, null);
+        writer.startElement(HTML_TAG_TABLE, null);
+        writer.writeAttribute(HTML_ATTR_CLASS, style, null);
+        writer.startElement(HTML_TAG_TR, null);
+        Options o = vi.getOptions();
+        for (OptionEntry e : o)
+        {
+            writer.startElement(HTML_TAG_TD, null);
+            // input
+            writer.startElement(HTML_TAG_INPUT, null);
+            writer.writeAttribute(HTML_ATTR_TYPE, "radio", null);
+            writer.writeAttribute(HTML_ATTR_DISABLED, "disabled", null);
+            if (ObjectUtils.compareEqual(e.getValue(), value))
+                writer.writeAttribute(HTML_ATTR_CHECKED, "checked", null);
+            writer.endElement(HTML_TAG_INPUT);
+            // label
+            writer.startElement(HTML_TAG_LABEL, null);
+            writer.writeAttribute(HTML_ATTR_CLASS, "eCtlRadio", null);
+            String text = e.getText();
+            text = vi.getTextResolver().resolveText(text);
+            writer.writeText(text, null);
+            writer.endElement(HTML_TAG_LABEL);
+            // end
+            writer.endElement(HTML_TAG_TD);
+        }
+        writer.endElement(HTML_TAG_TR);
+        writer.endElement(HTML_TAG_TABLE);
+        writer.endElement(HTML_TAG_DIV);
+    }
+
+    @Override
+    protected void createInputComponents(UIComponent parent, InputInfo ii, FacesContext context, List<UIComponent> compList)
+    {
+        HtmlSelectOneRadio input;
+        if (compList.size() == 0)
+        {   // create component
+            input = InputControlManager.createComponent(context, this.inputComponentClass);
+            // setValueExpressionFlag
+            Object value = ii.getValue(false);
+            input.getAttributes().put(RadioInputControl.VALUE_EXPRESSION_FLAG, (value instanceof ValueExpression));
+            // copy Attributes
+            copyAttributes(parent, ii, input);
+            // disabled
+            boolean disabled = ii.isDisabled();
+            input.setDisabled(disabled);
+            // Options
+            Options options = ii.getOptions();
+            boolean addEmpty = getEmptyEntryRequired(ii, disabled) && !options.contains("");
+            String nullText = (addEmpty) ? getNullText(ii) : "";
+            initOptions(input, ii.getTextResolver(), options, addEmpty, nullText);
+            // add
+            compList.add(input);
+        }
+        else
+        { // check type
+            UIComponent comp = compList.get(0);
+            if (!(comp instanceof HtmlSelectOneRadio))
+            {
+                throw new UnexpectedReturnValueException(comp.getClass().getName(), "compList.get");
+            }
+            // cast
+            input = (HtmlSelectOneRadio) comp;
+            // disabled
+            boolean disabled = ii.isDisabled();
+            input.setDisabled(disabled);
+            // Options (sync)
+            Options options = ii.getOptions();
+            boolean addEmpty = getEmptyEntryRequired(ii, disabled) && !options.contains("");
+            String nullText = (addEmpty) ? getNullText(ii) : "";
+            syncOptions(input, ii.getTextResolver(), options, addEmpty, nullText);
+        }
+
+        // style
+        addRemoveDisabledStyle(input, input.isDisabled());
+        addRemoveInvalidStyle(input, ii.hasError());
+
+        // Set Value
+        setInputValue(input, ii);
+    }
+    
+    @Override
+    protected void copyAttributes(UIComponent parent, InputInfo ii, UIInput input, String additonalStyle)
+    {
+        if (additonalStyle!=null)
+            additonalStyle = additonalStyle+" eCtlRadio";
+        else
+            additonalStyle = "eCtlRadio"; 
+        // copy
+        super.copyAttributes(parent, ii, input, additonalStyle);
+    }
+    
+    @Override
+    protected void updateInputState(List<UIComponent> compList, InputInfo ii, FacesContext context)
+    {
+        UIComponent comp = compList.get(0);
+        if (!(comp instanceof HtmlSelectOneRadio))
+        {
+            throw new UnexpectedReturnValueException(comp.getClass().getName(), "parent.getChildren()");
+        }
+        HtmlSelectOneRadio input = (HtmlSelectOneRadio)comp;
+        // disabled
+        boolean disabled = ii.isDisabled();
+        input.setDisabled(disabled);
+        // Options (sync)
+        Options options = ii.getOptions();
+        boolean addEmpty = getEmptyEntryRequired(ii, disabled) && !options.contains("");
+        String nullText = (addEmpty) ? getNullText(ii) : "";
+        syncOptions(input, ii.getTextResolver(), options, addEmpty, nullText);
+    }
+
+    private boolean getEmptyEntryRequired(InputInfo ii, boolean disabled)
+    {
+        if (!ii.isRequired() && !(disabled && ii.getColumn().isRequired()))
+        {
+            return true;
+        }
+        // Check Value
+        return (ii.getValue(true) == null);
+    }
+
+    public void initOptions(HtmlSelectOneRadio input, TextResolver textResolver, Options options, boolean addEmpty, String nullText)
+    {
+        if (addEmpty)
+        { // Empty entry
+            addSelectItem(input, textResolver, new OptionEntry(null, nullText));
+        }
+        if (options != null && options.size() > 0)
+        { // Add options
+            for (OptionEntry e : options)
+            { // Option entries
+                addSelectItem(input, textResolver, e);
+            }
+        }
+    }
+    
+    public void syncOptions(HtmlSelectOneRadio input, TextResolver textResolver, Options options, boolean hasEmpty, String nullText)
+    {
+        // Compare child-items with options
+        Iterator<OptionEntry> ioe = options.iterator();
+        OptionEntry oe = (ioe.hasNext() ? ioe.next() : null);
+        List<UIComponent> childList = input.getChildren();
+        Iterator<UIComponent> ico = childList.iterator();
+        int lastIndex = 0;
+        while (ico.hasNext())
+        {
+            lastIndex++;
+            UIComponent co = ico.next();
+            if (!(co instanceof UISelectItem))
+            {
+                continue;
+            }
+            UISelectItem si = (UISelectItem) co;
+            Object ov = si.getItemValue();
+            if (ObjectUtils.isEmpty(ov) && hasEmpty)
+            {
+                continue;
+            }
+            if (oe == null)
+            { // remove obsolete items
+                lastIndex--;
+                for (int index = childList.size() - 1; index >= lastIndex; index--)
+                {
+                    childList.remove(index);
+                }
+                // done
+                return;
+            }
+            if (ObjectUtils.compareEqual(ov, oe.getValue()))
+            { // next
+                oe = (ioe.hasNext() ? ioe.next() : null);
+                continue;
+            }
+            // Not equal - do a full reload
+            input.getChildren().clear();
+            if (hasEmpty)
+            {
+                addSelectItem(input, textResolver, new OptionEntry("", nullText));
+            }
+            for (OptionEntry e : options)
+            { // Option entries
+                addSelectItem(input, textResolver, e);
+            }
+            // done
+            return;
+        }
+        // Are there any items left?
+        while (oe != null)
+        { // add missing item
+            addSelectItem(input, textResolver, oe);
+            oe = (ioe.hasNext() ? ioe.next() : null);
+        }
+    }
+
+    public void addSelectItem(UIComponent input, TextResolver textResolver, OptionEntry e)
+    {
+        UISelectItem selectItem = new UISelectItem();
+        // set value
+        Object value;
+        Object valueExpressionFlag = input.getAttributes().get(RadioInputControl.VALUE_EXPRESSION_FLAG);
+        if (ObjectUtils.getBoolean(valueExpressionFlag))
+        { // Use value as is
+            value = e.getValue();
+        }
+        else
+        { // Convert to String
+            value = e.getValueString();
+        }
+        selectItem.setItemValue(value);
+        // set text
+        String text = e.getText();
+        text = textResolver.resolveText(text);
+        selectItem.setItemLabel(text);
+        // add item
+        input.getChildren().add(selectItem);
+    }
+
+    private String getNullText(InputInfo ii)
+    {
+        String nullText = getFormatString(ii, InputControl.FORMAT_NULL, InputControl.FORMAT_NULL_ATTRIBUTE);
+        return (nullText != null) ? ii.getText(nullText) : "";
+    }
+
+    @Override
+    protected String formatValue(Object value, ValueInfo vi)
+    {
+        // Lookup and Print value
+        if (vi.getOptions() == null)
+        {
+            RadioInputControl.log.warn("Select field {} has no Option list attached!", vi.getColumn().getName());
+            return super.formatValue(value, vi);
+        }
+        // Check for Abbreviation
+        if (hasFormatOption(vi, "short"))
+        {
+            Column column = vi.getColumn();
+            if (column != null)
+            { // Check for Abbreviation option list
+                Object attrValue = column.getAttribute(RadioInputControl.COLATTR_ABBR_OPTIONS);
+                if (attrValue instanceof Options)
+                { // Check for Options
+                    String text = ((Options) attrValue).get(value);
+                    if (text != null)
+                    {
+                        return vi.getText(text);
+                    }
+                    // Error
+                    RadioInputControl.log.error("The element '" + String.valueOf(value) + "' is not part of the supplied option list.");
+                }
+            }
+        }
+        return super.formatValue(value, vi);
+    }
+
+    @Override
+    protected Object formatInputValue(Object value, InputInfo ii)
+    {
+        // the enum Value
+        if (value != null && value.getClass().isEnum())
+        {
+            return ((Enum<?>) value).name();
+        }
+        // the value
+        return value;
+    }
+
+    @Override
+    protected Object parseInputValue(String value, InputInfo ii)
+    {
+        Object enumType = ii.getColumn().getAttribute(Column.COLATTR_ENUMTYPE);
+        if (enumType != null)
+        {   try
+            { // get enum
+                Class<?> enumClass = (Class<?>) enumType;
+                Field field = enumClass.getDeclaredField(value);
+                return field.get(null);
+            }
+            catch (NoSuchFieldException e)
+            {
+                throw new ItemNotFoundException(value);
+            }
+            catch (SecurityException e)
+            {
+                throw new InternalException(e);
+            }
+            catch (IllegalArgumentException e)
+            {
+                throw new InternalException(e);
+            }
+            catch (IllegalAccessException e)
+            {
+                throw new InternalException(e);
+            }
+        }
+        return value;
+    }
+
+    /*
+    @Override
+    public void renderInput(ResponseWriter writer, ControlInfo ci)
+    {
+        boolean disabled = ci.getDisabled();
+    
+        HtmlTag input = writer.startTag("select");
+        input.addAttribute("id",    ci.getId());
+        input.addAttribute("class", ci.getCssClass());
+        input.addAttribute("style", ci.getCssStyle());
+        if (disabled)
+        {
+            input.addAttribute("disabled");
+        } else
+        {
+            input.addAttribute("name", ci.getName());
+        }
+        // Event Attributes
+        input.addAttribute("onclick",   ci.getOnclick());
+        input.addAttribute("onchange",  ci.getOnchange());
+        input.addAttribute("onfocus",   ci.getOnfocus());
+        input.addAttribute("onblur",    ci.getOnblur());
+        input.beginBody(true);
+        // Render List of Options
+        Options options = ci.getOptions();
+        if (options!=null)
+        {   // Render option list
+            Object current = ci.getValue();
+            if (hasFormatOption(ci, "allownull") && options.contains(null)==false)
+            {   // add an empty entry
+                addEmtpyEntry(writer, ObjectUtils.isEmpty(current));
+            }
+            for (OptionEntry entry : options)
+            {
+                Object value = entry.getValue();
+                boolean isCurrent = ObjectUtils.compareEqual(current, value);
+                if (isCurrent == false && disabled)
+                    continue; // 
+                // Add Option entry
+                HtmlTag option = writer.startTag("option");
+                option.addAttributeNoCheck("value", value, true);
+                option.addAttribute("selected", isCurrent);
+                option.beginBody(ci.getTranslation(entry.getText()));
+                option.endTag(true);
+            }
+        }
+        else
+        {   // No Option list available
+            log.error("No options available for select input control.");
+        }
+        // done
+        input.endTag();
+    }
+    
+    private void addEmtpyEntry(HtmlWriter writer, boolean isCurrent)
+    {
+        // Add Option entry
+        HtmlTag option = writer.startTag("option");
+        option.addAttributeNoCheck("value", "", false);
+        option.addAttribute("selected", isCurrent);
+        option.beginBody("");
+        option.endTag(true);
+    }
+    */
+
+}