empire-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From doeb...@apache.org
Subject svn commit: r1326123 [1/4] - in /empire-db/trunk/empire-db-jsf2/src: ./ main/ main/java/ main/java/org/ main/java/org/apache/ main/java/org/apache/empire/ main/java/org/apache/empire/jsf2/ main/java/org/apache/empire/jsf2/app/ main/java/org/apache/empi...
Date Sat, 14 Apr 2012 14:57:30 GMT
Author: doebele
Date: Sat Apr 14 14:57:28 2012
New Revision: 1326123

URL: http://svn.apache.org/viewvc?rev=1326123&view=rev
Log:
EMPIREDB-140
checkin

Added:
    empire-db/trunk/empire-db-jsf2/src/
    empire-db/trunk/empire-db-jsf2/src/main/
    empire-db/trunk/empire-db-jsf2/src/main/java/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppRequestPhaseListener.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppStartupListener.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/DBELResolver.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesApplication.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/TextResolver.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LabelTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LinkTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/MenuItemTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/MenuListTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/NbspTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/RecordTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/SelectTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/TitleTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ValueTag.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/FieldRenderer.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/FieldRendererManager.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/SelectFieldRenderer.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextAreaFieldRenderer.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextFieldRenderer.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/BeanListPageElement.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/ListPageElement.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/RecordPageElement.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/StaticListPageElement.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageDefinition.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageDefinitions.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageELResolver.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageElement.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageNavigationHandler.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PageOutcome.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PagePhaseListener.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/PagesELResolver.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ListColumnFinder.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ListItemSelection.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ParameterMap.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/StringResponseWriter.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagRenderHelper.java   (with props)
    empire-db/trunk/empire-db-jsf2/src/main/resources/
    empire-db/trunk/empire-db-jsf2/src/test/
    empire-db/trunk/empire-db-jsf2/src/test/java/
    empire-db/trunk/empire-db-jsf2/src/test/resources/

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppRequestPhaseListener.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppRequestPhaseListener.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppRequestPhaseListener.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppRequestPhaseListener.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,87 @@
+/*
+ * 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.app;
+
+import javax.faces.application.Application;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+public class AppRequestPhaseListener implements PhaseListener
+{
+    private static final long   serialVersionUID = 1L;
+    final Logger                log              = LoggerFactory.getLogger(AppRequestPhaseListener.class);
+
+    /*
+    private static final String ACTION_PARAM     = "action";
+    private static final String REDIRECT_PARAM   = "redirect";
+    private static final String REDIRECT_RESULT  = "redirect:";
+    */
+
+    public AppRequestPhaseListener()
+    {
+        // foo
+    }
+
+    @Override
+    public PhaseId getPhaseId()
+    {
+        return PhaseId.ANY_PHASE;
+    }
+
+    @Override
+    public void beforePhase(PhaseEvent pe)
+    {
+        // Check for action param
+        /*
+        if (pe.getPhaseId().equals(PhaseId.RESTORE_VIEW))
+        {
+            beforeRestoreView(pe.getFacesContext());
+        }
+        */
+    }
+
+    /** 
+     * VERY VERY IMPORTANT FUNCTION: Release Connection on End of request! 
+     **/
+    @Override
+    public void afterPhase(PhaseEvent pe)
+    {
+        // Cleanup
+        FacesContext ctx = pe.getFacesContext();
+        if (pe.getPhaseId() == PhaseId.RENDER_RESPONSE || ctx.getResponseComplete())
+        {
+            Application app = ctx.getApplication();
+            if (!(app instanceof FacesApplication))
+                throw new AbortProcessingException("Error: Application is not a JsfApplication instance. Please create a ApplicationFactory!");
+            // Cast and release 
+            FacesApplication jsfApp = (FacesApplication)app;
+            jsfApp.releaseAllConnections(ctx);
+        }
+            
+    }
+
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppRequestPhaseListener.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppStartupListener.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppStartupListener.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppStartupListener.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppStartupListener.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,71 @@
+/*
+ * 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.app;
+
+import javax.faces.application.Application;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.PostConstructApplicationEvent;
+import javax.faces.event.PreDestroyApplicationEvent;
+import javax.faces.event.SystemEvent;
+import javax.faces.event.SystemEventListener;
+import javax.servlet.ServletContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+
+public class AppStartupListener implements SystemEventListener
+{
+    final Log log = LogFactory.getLog(AppStartupListener.class);
+
+    @Override
+    public boolean isListenerForSource(Object source)
+    {
+        return (source instanceof Application);
+    }
+
+    @Override
+    public void processEvent(SystemEvent event)
+        throws AbortProcessingException
+    {
+        log.info("ApplicationStartupListener:processEvent");
+        if (event instanceof PostConstructApplicationEvent)
+        {
+            Application app = ((PostConstructApplicationEvent) event).getApplication();
+            if (!(app instanceof FacesApplication))
+                throw new AbortProcessingException("Error: Application is not a JsfApplication instance. Please create a ApplicationFactory!");
+            // Create an Init application
+            ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
+            FacesApplication jsfApp = (FacesApplication)app;
+            jsfApp.init(servletContext);
+            // Set Servlet Attribute
+            servletContext.setAttribute(jsfApp.getApplicationBeanName(), jsfApp);
+            // done
+            log.info("Fin2Application initialization complete!");
+        }
+        else if (event instanceof PreDestroyApplicationEvent)
+        {
+            log.info("Processing PreDestroyApplicationEvent");
+        }
+
+    }
+
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/AppStartupListener.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/DBELResolver.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/DBELResolver.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/DBELResolver.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/DBELResolver.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,129 @@
+/*
+ * 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.app;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.faces.context.FacesContext;
+
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.db.DBColumn;
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBRowSet;
+import org.apache.empire.exceptions.NotSupportedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DBELResolver extends ELResolver
+{
+    private static final Logger log = LoggerFactory.getLogger(DBELResolver.class);
+    
+    @Override
+    public Class<?> getCommonPropertyType(ELContext context, Object base)
+    {
+        if (base==null)
+            log.warn("DBELResolver:getCommonPropertyType is not implemented!");
+        return null;
+    }
+
+    @Override
+    public Class<?> getType(ELContext context, Object base, Object property)
+    {
+        if ((base instanceof DBRowSet) ||
+            (base instanceof DBDatabase) ||
+            (base==null && property.equals("db")))
+            log.warn("DBELResolver:getType is not implemented!");
+        return null;
+    }
+
+    @Override
+    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext arg0, Object arg1)
+    {
+        log.warn("DBELResolver:getFeatureDescriptors is not implemented!");
+        return null;
+    }
+
+    @Override
+    public Object getValue(ELContext context, Object base, Object property)
+    {
+        // Resolve database, table/view or column
+        if (base instanceof DBRowSet)
+        {   // Find matching column
+            String   name = StringUtils.toString(property);
+            DBColumn column = ((DBRowSet)base).getColumn(name);
+            if (column!=null)
+                context.setPropertyResolved(true); 
+            else
+                log.error("ELResolver error: Column '{}' cannot be resolved for table/view '{}'.", name.toUpperCase(), ((DBRowSet)base).getName());
+            // done
+            return column;
+        }
+        else if (base instanceof DBDatabase)
+        {   // Lookup RowSet
+            String   name = StringUtils.toString(property);
+            DBRowSet rset = ((DBDatabase)base).getRowSet(name);
+            if (rset!=null)
+                context.setPropertyResolved(true);
+            else
+                log.error("ELResolver error: Table/View '{}' cannot be resolved.", name.toUpperCase());
+            // done
+            return rset;
+        }
+        else if (base==null)
+        {   // LookupDatabase
+            String name = StringUtils.toString(property);
+            DBDatabase db = DBDatabase.findById(name);
+            if (db!=null)
+                context.setPropertyResolved(true);
+            // done
+            return db;
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isReadOnly(ELContext context, Object base, Object property)
+    {
+        // is it our's?
+        if ((base instanceof DBRowSet) ||
+            (base instanceof DBDatabase) ||
+            (base==null && property.equals("db")))
+        {   // read only
+            log.info("ELResolver: property {} is read only.", property);
+            return true;
+        }
+        // not our business
+        return false;
+    }
+
+    @Override
+    public void setValue(ELContext context, Object base, Object property, Object value)
+    {
+        if (isReadOnly(context, base, property))
+        {
+            RuntimeException e = new NotSupportedException(this, "setValue");
+            FacesContext.getCurrentInstance().getExternalContext().log(e.getMessage(), e);
+            throw e;
+        }    
+    }
+
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/DBELResolver.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesApplication.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesApplication.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesApplication.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesApplication.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,418 @@
+/*
+ * 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.app;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.application.FacesMessage.Severity;
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.servlet.ServletContext;
+import javax.sql.DataSource;
+
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.data.Column;
+import org.apache.empire.data.DataType;
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.exceptions.InternalException;
+import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.NotSupportedException;
+import org.apache.empire.jsf2.controls.FieldRenderer;
+import org.apache.empire.jsf2.controls.FieldRendererManager;
+import org.apache.empire.jsf2.controls.SelectFieldRenderer;
+import org.apache.empire.jsf2.controls.TextAreaFieldRenderer;
+import org.apache.empire.jsf2.controls.TextFieldRenderer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.faces.application.ApplicationImpl;
+
+public abstract class FacesApplication extends ApplicationImpl
+{
+    private static final Logger    log    = LoggerFactory.getLogger(FacesApplication.class);
+    
+    public final String APPLICATION_ATTRIBUTE   = "app";
+    public final String CONNECTION_ATTRIBUTE    = "dbConnections";
+    
+    protected TextResolver[] textResolvers = null; 
+    
+    protected FacesApplication()
+    {
+    }
+    
+    public String getApplicationBeanName()
+    {
+        return APPLICATION_ATTRIBUTE;
+    }
+
+    protected abstract DataSource getAppDataSource(DBDatabase db);
+    
+    public abstract void init(ServletContext fc);
+    
+    /* Context handling */
+
+    public void addJavascriptCall(final FacesContext fc, String function)
+    {
+        throw new NotSupportedException(this, "addJavascriptCall");
+    }
+    
+    public Locale getContextLocale(final FacesContext ctx)
+    {
+        UIViewRoot root;
+        // Start out with the default locale
+        Locale locale;
+        Locale defaultLocale = Locale.getDefault();
+        locale = defaultLocale;
+        // See if this FacesContext has a ViewRoot
+        if (null != (root = ctx.getViewRoot())) {
+            // If so, ask it for its Locale
+            if (null == (locale = root.getLocale())) {
+                // If the ViewRoot has no Locale, fall back to the default.
+                locale = defaultLocale;
+            }
+        }
+        return locale;
+    }
+    
+    /**
+     * checks if the current context contains an error
+     * @param fc the FacesContext
+     * @return true if the context has an error set or false otherwise
+     */
+    public boolean hasError(final FacesContext fc)
+    {
+        Iterator<FacesMessage> msgIterator = fc.getMessages();
+        if (msgIterator!=null)
+        {   // Check Messages
+            while (msgIterator.hasNext())
+            {   // Check Severity
+                Severity fms = msgIterator.next().getSeverity();
+                if (fms==FacesMessage.SEVERITY_ERROR ||
+                    fms==FacesMessage.SEVERITY_FATAL)
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * finds a component from with a given id from a given start component
+     * @param fc the FacesContext
+     * @param componentId
+     * @param nearComponent a component within the same naming container
+     * @return
+     */
+    public UIComponent findComponent(FacesContext fc, String componentId, UIComponent nearComponent)
+    {
+        if (StringUtils.isEmpty(componentId))
+        	throw new InvalidArgumentException("forComponentId", componentId);
+        // Search for compoent
+        UIComponent forComponent = null;
+        if (nearComponent!=null)
+        {
+	        // Look for the 'for' component in the nearest parental naming container 
+	        // of the UIComponent (there's actually a bit more to this search - see
+	        // the docs for the findComponent method
+	        forComponent = nearComponent.findComponent(componentId);
+	        // Since the nearest naming container may be nested, search the 
+	        // next-to-nearest parental naming container in a recursive fashion, 
+	        // until we get to the view root
+	        if (forComponent == null)
+	        {
+	            UIComponent nextParent = nearComponent;
+	            while (true)
+	            {
+	                nextParent = nextParent.getParent();
+	                // avoid extra searching by going up to the next NamingContainer
+	                // (see the docs for findComponent for an information that will
+	                // justify this approach)
+	                while (nextParent != null && !(nextParent instanceof NamingContainer))
+	                {
+	                    nextParent = nextParent.getParent();
+	                }
+	                if (nextParent == null)
+	                {
+	                    break;
+	                }
+	                else
+	                {
+	                    forComponent = nextParent.findComponent(componentId);
+	                }
+	                if (forComponent != null)
+	                {
+	                    break;
+	                }
+	            }
+	        }
+        }
+        // There is one other situation to cover: if the 'for' component 
+        // is not situated inside a NamingContainer then the algorithm above
+        // will not have found it. We need, in this case, to search for the 
+        // component from the view root downwards
+        if (forComponent == null)
+        {
+            forComponent = searchDownwardsForChildComponentWithId(fc.getViewRoot(), componentId);
+        }
+        return forComponent;
+    }
+
+    private static UIComponent searchDownwardsForChildComponentWithId(UIComponent parent, String searchChildId)
+    {
+        UIComponent foundChild = null;
+        if (parent.getChildCount() == 0)
+            return foundChild;
+        Iterator<UIComponent> children = parent.getChildren().iterator();
+        while (children.hasNext())
+        {
+            UIComponent nextChild = children.next();
+            if (nextChild instanceof NamingContainer)
+            {
+                foundChild = nextChild.findComponent(searchChildId);
+            }
+            if (foundChild == null)
+            {
+                searchDownwardsForChildComponentWithId(nextChild, searchChildId);
+            }
+            if (foundChild != null)
+            {
+                break;
+            }
+        }
+        return foundChild;
+    }
+    
+    public FieldRenderer getFieldRenderer(Column column)
+    {
+        // Get Renderer from column
+        String controlType = column.getControlType();
+        FieldRenderer renderer = null;
+        if (StringUtils.isNotEmpty(controlType))
+        	renderer = FieldRendererManager.getRenderer(controlType);
+        if (renderer == null)
+        { // Auto-detect
+        	if (column.getOptions()!=null)
+        		controlType = SelectFieldRenderer.NAME;
+        	else
+        		controlType = getDefaultControlType(column.getDataType());
+            // get default renderer
+            renderer = FieldRendererManager.getRenderer(controlType);
+        	// Still not? Use Text Renderer
+		    if (renderer == null)
+		    	renderer = FieldRendererManager.getRenderer(TextFieldRenderer.NAME);
+            // debug
+            if (log.isDebugEnabled() && !controlType.equals(TextFieldRenderer.NAME))
+                log.debug("Auto-detected field renderer for " + column.getName() + " is " + controlType);
+        }
+        return renderer;
+    }
+
+    /**
+     * returns the default control type for a given data Type
+     * @param dataType
+     * @return
+     */
+    protected String getDefaultControlType(DataType dataType)
+    {
+        switch (dataType)
+        {
+            case CLOB:
+                return TextAreaFieldRenderer.NAME;
+            default:
+            	return TextFieldRenderer.NAME;
+        }
+    }
+    
+    /* Message handling */
+    
+    protected void initTextResolvers()
+    {
+        ResourceBundle rb = ResourceBundle.getBundle("lang.messages", Locale.getDefault());
+        textResolvers = new TextResolver[] { new TextResolver(rb) }; 
+    }
+    
+    public TextResolver getTextResolver(Locale locale)
+    {
+        // No text Resolvers provided
+        if (textResolvers==null || textResolvers.length==0)
+        {
+            throw new NotSupportedException(this, "getTextResolver");
+        }
+        // Lookup resolver for locale
+        for (int i=0; i<textResolvers.length; i++)
+            if (locale.equals(textResolvers[i].getLocale()))
+                return textResolvers[i];
+        // locale not found: return default
+        return textResolvers[0];
+    }
+    
+    public TextResolver getTextResolver(FacesContext ctx)
+    {
+        return getTextResolver(getContextLocale(ctx));
+    }
+    
+    /**
+     * @see javax.faces.application.Application#getResourceBundle(javax.faces.context.FacesContext, String)
+     */
+    @Override
+    public ResourceBundle getResourceBundle(FacesContext fc, String var) 
+    {
+        if (var.equals("msg"))
+        {
+            TextResolver resolver = getTextResolver(fc);
+            return resolver.getResourceBundle();
+        }
+        return null;
+    }
+    
+    /**
+     * returns a connection from the connection pool
+     * @return
+     */
+    protected Connection getConnection(DBDatabase db)
+    {
+        // Get From Pool
+        try
+        { // Obtain a connection
+            Connection conn = getAppDataSource(db).getConnection();
+            conn.setAutoCommit(false);
+            return conn;
+        }
+        catch (SQLException e)
+        {
+            log.error("Failed to get connection from pool.", e);
+            throw new InternalException(e);
+        }
+    }
+
+    /**
+     * releases a connection from the connection pool
+     */
+    protected void releaseConnection(DBDatabase db, Connection conn, boolean commit)
+    {
+        try
+        { // release connection
+            if (conn == null)
+            {
+                return;
+            }
+            // Commit or rollback connection depending on the exit code
+            if (commit)
+            { // success: commit all changes
+                db.commit(conn);
+                log.debug("REQUEST {}: commited.");
+            }
+            else
+            { // failure: rollback all changes
+                db.rollback(conn);
+                log.debug("REQUEST {}: rolled back.");
+            }
+            // Release Connection
+            conn.close();
+            // done
+            if (log.isDebugEnabled())
+                log.debug("REQUEST {}: returned connection to pool.");
+        }
+        catch (SQLException e)
+        {
+            log.error("Error releasing connection", e);
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Returns a connection for the current Request
+     * Method should only be called by BeforeRestoreViewListener once per request!
+     */
+    public Connection getConnectionForRequest(FacesContext fc, DBDatabase db)
+    {
+        if (fc==null)
+            throw new InvalidArgumentException("FacesContext", fc);
+        if (db==null)
+            throw new InvalidArgumentException("DBDatabase", db);
+        // Get Conneciton map
+        @SuppressWarnings("unchecked")
+        Map<DBDatabase, Connection> connMap = (Map<DBDatabase, Connection>)FacesUtils.getRequestAttribute(fc, CONNECTION_ATTRIBUTE);
+        if (connMap!=null && connMap.containsKey(db))
+            return connMap.get(db);
+        // Pooled Connection
+        Connection conn = getConnection(db);
+        if (conn==null)
+            return null;
+        // Add to map
+        if (connMap==null)
+        {   connMap= new HashMap<DBDatabase, Connection>();
+            FacesUtils.setRequestAttribute(fc, CONNECTION_ATTRIBUTE, connMap);
+        }    
+        connMap.put(db, conn);    
+        return conn;
+    }
+    
+    /**
+     * Releases the current request connection
+     * @param fc
+     * @param commit
+     */
+    public void releaseAllConnections(final FacesContext fc, boolean commit)
+    {
+        @SuppressWarnings("unchecked")
+        Map<DBDatabase, Connection> connMap = (Map<DBDatabase, Connection>)FacesUtils.getRequestAttribute(fc, CONNECTION_ATTRIBUTE);
+        if (connMap != null)
+        {   // Walk the connection map
+            for (Map.Entry<DBDatabase, Connection> e : connMap.entrySet())
+            {
+                releaseConnection(e.getKey(), e.getValue(), commit);
+            }
+            // remove from request map
+            FacesUtils.setRequestAttribute(fc, CONNECTION_ATTRIBUTE, null);
+        }
+    }
+
+    public void releaseAllConnections(final FacesContext fc)
+    {
+        releaseAllConnections(fc, !hasError(fc));
+    }
+
+    public void releaseConnection(final FacesContext fc, DBDatabase db, boolean commit)
+    {
+        @SuppressWarnings("unchecked")
+        Map<DBDatabase, Connection> connMap = (Map<DBDatabase, Connection>)FacesUtils.getRequestAttribute(fc, CONNECTION_ATTRIBUTE);
+        if (connMap != null && connMap.containsKey(db))
+        {   // Walk the connection map
+            releaseConnection(db, connMap.get(db), commit);
+            connMap.remove(db);
+            if (connMap.size()==0)
+                FacesUtils.setRequestAttribute(fc, CONNECTION_ATTRIBUTE, null);
+        }
+    }
+
+    public void releaseConnection(final FacesContext fc, DBDatabase db)
+    {
+        releaseConnection(fc, db, !hasError(fc));
+    }
+    
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesApplication.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,222 @@
+/*
+ * 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.app;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.faces.FactoryFinder;
+import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.jsf2.pages.Page;
+import org.apache.empire.jsf2.utils.ParameterMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FacesUtils
+{
+
+    private static final Logger log = LoggerFactory.getLogger(FacesUtils.class);
+
+    /* App */
+
+    public static FacesApplication getFacesApplication()
+    {
+        ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
+        Application app = appFactory.getApplication();
+        return (FacesApplication) app;
+    }
+    
+    public static FacesContext getContext()
+    {
+        return FacesContext.getCurrentInstance();
+    }
+
+    /* Request */
+
+    public static HttpServletRequest getHttpRequest(final FacesContext fc)
+    {
+        return (HttpServletRequest) fc.getExternalContext().getRequest();
+    }
+
+    public static Object getRequestAttribute(final FacesContext fc, final String key)
+    {
+        return getHttpRequest(fc).getAttribute(key);
+    }
+
+    public static void setRequestAttribute(final FacesContext fc, final String key, Object value)
+    {
+        if (value!=null)
+            getHttpRequest(fc).setAttribute(key, value);
+        else
+            getHttpRequest(fc).removeAttribute(key);
+    }
+
+    public static String getRequestParam(final FacesContext context, final String param)
+    {
+        return context.getExternalContext().getRequestParameterMap().get(param);
+    }
+
+    public static void redirectDirectly(final FacesContext fc,final String url)
+    {
+        try
+        {
+            fc.getExternalContext().redirect(url);
+            fc.responseComplete();
+        }
+        catch (IOException e)
+        {
+            log.error("Unable to redirect to " + url);
+        }
+    }
+
+    /* Connection */
+    
+    public Connection getConnection(final FacesContext fc, DBDatabase db) 
+    {
+        return getFacesApplication().getConnectionForRequest(fc, db);
+    }
+    
+    public void releaseAllConnections(final FacesContext fc, boolean commit)
+    {
+        getFacesApplication().releaseAllConnections(fc, commit);
+    }
+    
+    public void releaseAllConnections(final FacesContext fc, DBDatabase db, boolean commit)
+    {
+        getFacesApplication().releaseConnection(fc, db, commit);
+    }
+    
+    /* Pages */
+
+    public static Page getPage(final FacesContext fc)
+    {
+        Page page = (Page) getManagedBean(fc, "page");
+        if (page==null)
+            log.error("Page bean {} does not exist!");
+        return page; 
+    }
+
+    /* Pages */
+    public static final String PARAMETER_MAP_ATTRIBUTE = ParameterMap.class.getSimpleName();
+    
+    public static ParameterMap getParameterMap(final FacesContext fc)
+    {
+        Map<String, Object> sm = fc.getExternalContext().getSessionMap();
+        Object pm = sm.get(PARAMETER_MAP_ATTRIBUTE);
+        if (pm==null)
+        {   pm = new ParameterMap();
+            sm.put(PARAMETER_MAP_ATTRIBUTE, pm);
+        }
+        return (ParameterMap)pm;
+    }
+    
+    /* Managed Beans */
+    
+    public static Object getManagedBean(final FacesContext fc, final String name)
+    {
+        if (fc == null)
+        {
+            throw new NullPointerException("context must not be null");
+        }
+        if (name == null)
+        {
+            throw new NullPointerException("name must not be null");
+        }
+
+        final ELContext elcontext = fc.getELContext();
+        final Application application = fc.getApplication();
+
+        return application.getELResolver().getValue(elcontext, null, name);
+    }
+    
+    public static <T> T getManagedBean(final FacesContext fc, final Class<T> cls)
+    {
+        String name = cls.getName();
+        int i = name.lastIndexOf('.')+1;
+        name  = name.substring(i, i+1).toLowerCase()+name.substring(i+1);
+        T bean = (T)getManagedBean(fc, name);
+        if (bean==null)
+            log.warn("Managed Bean {} ist not available.", name);
+        return bean;
+    }
+
+    /*
+    @SuppressWarnings("unchecked") 
+    public static <T> T findBean(String beanName) { 
+        FacesContext context = FacesContext.getCurrentInstance(); 
+        return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class); 
+    } 
+    */
+    
+    /* file */
+    
+    public static String getRealPath(final FacesContext fc, String path)
+    {
+        return (((ServletContext)fc.getExternalContext().getContext())).getRealPath(path);
+    }
+
+    public static String getFilePath(final FacesContext fc, String path, String file)
+    {
+        String realPath = getRealPath(fc, path);
+        return realPath.endsWith(File.separator) ? realPath+file : realPath + File.separator + file ;
+    }
+
+    /* Messages */
+    
+    public static TextResolver getTextResolver(final FacesContext fc)
+    {
+        return ((FacesApplication)fc.getApplication()).getTextResolver(fc);
+    }
+    
+    public static String getMessage(final FacesContext fc, String key)
+    {
+        return getTextResolver(fc).resolveKey(key);
+    }
+
+    public static void addInfoMessage(FacesContext fc, String clientId, String msg)
+    {
+        fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg));
+    }
+    
+    public static void addInfoMessage(FacesContext fc, String msg)
+    {
+        addInfoMessage(fc, null, msg);
+    }
+
+    public static void addErrorMessage(FacesContext fc, String clientId, String msg)
+    {
+        fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg));
+    }
+
+    public static void addErrorMessage(FacesContext fc, String msg)
+    {
+        addErrorMessage(fc, null, msg);
+    }
+    
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/TextResolver.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/TextResolver.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/TextResolver.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/TextResolver.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,122 @@
+/*
+ * 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.app;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.apache.empire.exceptions.EmpireException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TextResolver
+{
+    private static final Logger log = LoggerFactory.getLogger(TextResolver.class);
+    
+    public static String MSG_KEY_INDICATOR = "!";
+
+    private final ResourceBundle resBundle;
+
+    public TextResolver(ResourceBundle resBundle)
+    {
+        this.resBundle = resBundle;
+    }
+    
+    public final ResourceBundle getResourceBundle()
+    {
+        return resBundle;
+    }
+    
+    public final Locale getLocale()
+    {
+        return resBundle.getLocale();
+    }
+
+    public String resolveKey(String key)
+    {
+        try
+        {
+            String res = resBundle.getString(key);
+            if (res==null)
+                throw new MissingResourceException("Message Key not found.", String.class.getSimpleName(), key);
+            return res;
+        }
+        catch (MissingResourceException e)
+        {
+            log.error("Message key missing '{}'.", key);
+            return "["+key+"]";
+        }
+        catch (Exception e)
+        {
+            log.error("Error resolving text: {}", e);
+            return "["+key+"]";
+        }
+    }
+    
+    public String resolveText(String text)
+    {
+        // Translate
+        if (text != null && text.startsWith(MSG_KEY_INDICATOR))
+        {
+            String key = text.substring(1);
+            return resolveKey(key);
+        }
+        return text;
+    }
+    
+    public String getExceptionMessage(Exception e)
+    {
+        if (e instanceof EmpireException)
+        {
+            EmpireException ee = (EmpireException)e;
+            String key = ee.getErrorType().getKey();
+            // get Pattern 
+            String pattern;
+            if (resBundle.containsKey(key))
+            {   // Get Pattern
+                pattern = resBundle.getString(key); 
+            }
+            else
+            {   // No error message pattern provided. Using default
+                pattern = ee.getErrorType().getMessagePattern();
+                log.error("Error resolving error messsage pattern: {}", key);
+            }
+            // get Params
+            String[] params = ee.getErrorParams();
+            Object[] values = null;
+            if (params!=null)
+            {   values = new Object[params.length];
+                for (int i=0; i<params.length; i++)
+                    values[i] = resolveText(params[i]);
+            }
+            // Format message
+            return MessageFormat.format(pattern, values);            
+        }
+        else
+        {   // Other exception try to resolve by class name
+            String key = "exception."+e.getClass().getName();
+            if (resBundle.containsKey(key))
+                return resBundle.getString(key);
+            // not provided
+            return e.getLocalizedMessage();
+        }
+    }
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/TextResolver.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,411 @@
+/*
+ * 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.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.component.UIInput;
+import javax.faces.component.UIOutput;
+import javax.faces.component.html.HtmlOutputLabel;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.data.Column;
+import org.apache.empire.jsf2.controls.FieldRenderer;
+import org.apache.empire.jsf2.utils.TagRenderHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ControlTag extends UIInput implements NamingContainer
+{
+    public static abstract class ControlSeparatorComponent extends javax.faces.component.UIComponentBase
+    {
+        protected String tagName = null;
+
+        @Override
+        public String getFamily()
+        {
+            return UIOutput.COMPONENT_FAMILY;
+        }
+        
+        @Override
+        public void encodeBegin(FacesContext context)
+            throws IOException
+        {
+            super.encodeBegin(context);
+            
+            UIComponent parent = getParent();
+            if (!(parent instanceof ControlTag))
+            {   log.error("Invalid parent component for "+getClass().getName());
+                return;
+            }
+            
+            ControlTag control = (ControlTag)parent;
+            TagRenderHelper helper = control.helper;
+            
+            tagName = helper.getTagAttribute("tag", "td");
+            
+            // render components
+            ResponseWriter writer = context.getResponseWriter();
+            writer.startElement(tagName, this);
+            writeAttributes(writer, helper);
+        }
+        
+        protected abstract void writeAttributes(ResponseWriter writer, TagRenderHelper helper) throws IOException;
+        
+        @Override
+        public void encodeChildren(FacesContext context)
+            throws IOException
+        {
+            super.encodeChildren(context);
+        }
+        
+        @Override
+        public void encodeEnd(FacesContext context)
+            throws IOException
+        {
+            // render components
+            ResponseWriter writer = context.getResponseWriter();
+            writer.endElement(tagName);
+
+            super.encodeEnd(context);
+        }
+    }
+
+    public static class LabelSeparatorComponent extends ControlSeparatorComponent
+    {
+        @Override
+        protected void writeAttributes(ResponseWriter writer, TagRenderHelper helper) 
+            throws IOException
+        {
+            String styleClass = helper.getTagAttribute("labelClass", "eCtlLabel");
+            if (StringUtils.isNotEmpty(styleClass))
+                writer.writeAttribute("class", styleClass, null);
+        }
+    }
+
+    public static class InputSeparatorComponent extends ControlSeparatorComponent
+    {
+        @Override
+        protected void writeAttributes(ResponseWriter writer, TagRenderHelper helper) 
+            throws IOException
+        {
+            String styleClass = helper.getTagAttribute("inputClass", "eCtlInput");
+            if (StringUtils.isNotEmpty(styleClass))
+                writer.writeAttribute("class", styleClass, null);
+            String colSpan = helper.getTagAttribute("colspan");
+            if (StringUtils.isNotEmpty(colSpan) && tagName.equalsIgnoreCase("td"))
+                writer.writeAttribute("colspan", colSpan, null);
+        }
+    }
+    
+    public static class ValueOutputComponent extends javax.faces.component.UIComponentBase
+    {
+        private final String tagName = "span";
+        
+        public ValueOutputComponent()
+        {
+        }
+
+        @Override
+        public String getFamily()
+        {
+            return UIOutput.COMPONENT_FAMILY;
+        }
+        
+        @Override
+        public void encodeBegin(FacesContext context)
+            throws IOException
+        {
+            super.encodeBegin(context);
+            
+            UIComponent parent = getParent();
+            if (parent instanceof ControlSeparatorComponent)
+                parent = parent.getParent();
+            if (!(parent instanceof ControlTag))
+            {   log.error("Invalid parent component for "+getClass().getName());
+                return;
+            }
+            
+            ControlTag control = (ControlTag)parent;
+            TagRenderHelper helper = control.helper;
+
+            FieldRenderer renderer = helper.getFieldRenderer();
+            FieldRenderer.ValueInfo valInfo = helper.getValueInfo(context);
+            String styleClass = helper.getTagStyleClass("eInpDis");
+            String tooltip    = helper.getValueTooltip(helper.getTagAttribute("title"));
+            
+            // render components
+            ResponseWriter writer = context.getResponseWriter();
+            writer.startElement(tagName, this);
+            if (StringUtils.isNotEmpty(styleClass))
+                writer.writeAttribute("class", styleClass, null);
+            if (StringUtils.isNotEmpty(tooltip))
+                writer.writeAttribute("title", tooltip, null);
+            // render Value
+            renderer.renderValue(valInfo, writer);
+            writer.endElement(tagName);
+        }
+    }
+    
+    // Logger
+    private static final Logger  log          = LoggerFactory.getLogger(ControlTag.class);
+    
+    // private static final String fieldRendererPropName = FieldRenderer.class.getSimpleName();
+    // private static final String inputInfoPropName  = FieldRenderer.InputInfo.class.getSimpleName();
+    private static final String readOnlyState  = "readOnlyState";
+
+    protected final TagRenderHelper helper = new TagRenderHelper(this, "eInput");
+
+    protected FieldRenderer renderer = null;
+    protected FieldRenderer.InputInfo inpInfo = null;
+
+    public ControlTag()
+    {
+        super();
+    }
+
+    @Override
+    public String getFamily()
+    {
+        return "javax.faces.NamingContainer";
+    }
+
+    private void saveState()
+    {
+        // getStateHelper().put(fieldRendererPropName, renderer);
+        // getStateHelper().put(inputInfoPropName, inpInfo);
+        getStateHelper().put(readOnlyState, (inpInfo==null));
+    }
+
+    private boolean initState(FacesContext context)
+    {
+        Boolean ros = (Boolean)getStateHelper().get(readOnlyState);
+        if (ros!=null && ros.booleanValue())
+            return false;
+        // renderer = ;
+        renderer = helper.getFieldRenderer();
+        inpInfo  = helper.getInputInfo(context);
+        return (renderer!=null && inpInfo!=null);
+    }
+
+    @Override
+    public void encodeBegin(FacesContext context)
+        throws IOException
+    {
+        // add label and input components when the view is loaded for the first time
+        super.encodeBegin(context);
+        
+        // init
+        helper.encodeBegin();
+        renderer = helper.getFieldRenderer();
+        
+        ControlSeparatorComponent labelSepTag = null; 
+        ControlSeparatorComponent inputSepTag = null; 
+        
+        // get existing
+        if (getChildCount() > 0)
+            labelSepTag = (ControlSeparatorComponent) getChildren().get(0);
+        if (getChildCount() > 1)
+            inputSepTag = (ControlSeparatorComponent) getChildren().get(1);
+
+        // create children
+        if (labelSepTag == null)
+        {
+            labelSepTag = new LabelSeparatorComponent();
+            getChildren().add(labelSepTag);
+            encodeLabel(context, labelSepTag);
+        }    
+        if (inputSepTag == null && !isCustomInput())
+        {
+            inputSepTag = new InputSeparatorComponent();
+            getChildren().add(inputSepTag);
+            encodeInput(context, inputSepTag);
+        }    
+        saveState();
+    }
+    
+    @Override 
+    public void encodeChildren(FacesContext context) 
+        throws IOException 
+    {
+        if (isCustomInput())
+        {
+            String tagName = helper.getTagAttribute("tag", "td");
+            String styleClass = helper.getTagAttribute("inputClass", "eCtlInput");
+            String colSpan = helper.getTagAttribute("colspan");
+
+            ResponseWriter writer = context.getResponseWriter();
+            writer.startElement(tagName, this);
+            if (StringUtils.isNotEmpty(styleClass))
+                writer.writeAttribute("class", styleClass, null);
+            if (StringUtils.isNotEmpty(colSpan) && tagName.equalsIgnoreCase("td"))
+                writer.writeAttribute("colspan", colSpan, null);
+            
+            super.encodeChildren(context);
+            writer.endElement(tagName);
+        }    
+    }
+
+    @Override
+    public void encodeEnd(FacesContext context)
+        throws IOException 
+    {
+        super.encodeEnd(context);
+    }
+    
+    private boolean isCustomInput()
+    {
+        Object custom = getAttributes().get("custom");
+        if (custom != null)
+            return ObjectUtils.getBoolean(custom);
+        return false;
+    }
+    
+    private void encodeLabel(FacesContext context, UIComponentBase parent)
+        throws IOException
+    {
+        // render components
+        HtmlOutputLabel labelComponent = null;
+        if (parent.getChildCount() > 0)
+        {
+            labelComponent = (HtmlOutputLabel) parent.getChildren().get(0);
+        }
+        if (labelComponent == null)
+        {
+            String forInput = isCustomInput() ? helper.getTagAttribute("for") : "*";
+            // createLabelComponent 
+            labelComponent = helper.createLabelComponent(context, forInput, "eLabel", null, true);
+            parent.getChildren().add(labelComponent);
+        }
+        // render components
+        parent.encodeAll(context);
+    }
+    
+    private void encodeInput(FacesContext context, UIComponentBase parent)
+        throws IOException
+    {
+        // render components
+        if (helper.isRecordReadOnly())
+        {
+            ValueOutputComponent valueComp = new ValueOutputComponent();
+            parent.getChildren().add(valueComp);
+        }
+        else
+        {
+            inpInfo = helper.getInputInfo(context);
+            // render input
+            renderer.renderInput(parent, inpInfo, context, false);
+        }
+        parent.encodeAll(context);
+    }
+
+    @Override
+    public Object getValue()
+    {
+        // check for record
+        if (helper.getRecord()!=null)
+            helper.getDataValue();
+        // default
+        return super.getValue();
+    }
+
+    @Override
+    public Object getSubmittedValue()
+    {   // Check state
+        if (renderer==null || inpInfo==null)
+            return null;
+        // get Input Value
+        return renderer.getInputValue(this, inpInfo, true);
+    }
+
+    @Override
+    public void validateValue(FacesContext context, Object value)
+    {   // Check state
+        if (inpInfo==null)
+            return;
+        // Validate value
+        inpInfo.validate(value);
+        setValid(true);
+        // call base class 
+        super.validateValue(context, value);
+    }    
+    
+    @Override
+    public void validate(FacesContext context)
+    {
+        if (initState(context)==false)
+            return;
+        // check disabled
+        if (inpInfo.isDisabled())
+            return;
+        // get submitted value and validate
+        if (log.isDebugEnabled())
+            log.debug("Validating input for {}.", inpInfo.getColumn().getName());
+        
+        // Validate value
+        try {
+            // Will internally call getSubmittedValue() and validateValue() 
+            super.validate(context);
+            
+        } catch(Exception e) {
+            // Value is not valid
+            helper.addErrorMessage(context, e);
+            setValid(false);
+        }
+    }
+
+    @Override
+    public void updateModel(FacesContext context)
+    {
+        if (initState(context)==false)
+            return;
+        // check disabled
+        if (inpInfo.isDisabled())
+            return;
+        // No Action
+        if (!isValid() || !isLocalValueSet())
+            return; 
+        // super.updateModel(context);
+        log.debug("Updating model input for {}.", inpInfo.getColumn().getName());
+        inpInfo.setValue(getLocalValue());
+        setValue(null);
+        setLocalValueSet(false);
+    }
+    
+    public Column getInputColumn()
+    {
+        return helper.getColumn();
+    }
+    
+    public boolean isInputReadOnly()
+    {
+        return helper.isRecordReadOnly();
+    }
+    
+    public boolean isInputRequired()
+    {
+        return helper.isValueRequired();
+    }
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,220 @@
+/*
+ * 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.Map;
+
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIInput;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.empire.data.Column;
+import org.apache.empire.jsf2.controls.FieldRenderer;
+import org.apache.empire.jsf2.utils.TagRenderHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InputTag extends UIInput implements NamingContainer
+{
+    // Logger
+    private static final Logger log          = LoggerFactory.getLogger(InputTag.class);
+    
+    // private static final String fieldRendererPropName = FieldRenderer.class.getSimpleName();
+    // private static final String inputInfoPropName  = FieldRenderer.InputInfo.class.getSimpleName();
+    private static final String readOnlyState  = "readOnlyState";
+
+    private final TagRenderHelper helper = new TagRenderHelper(this, "eInput");
+
+    private FieldRenderer renderer = null;
+    private FieldRenderer.InputInfo inpInfo = null;
+
+    public InputTag()
+    {
+        super();
+    }
+
+    @Override
+    public String getFamily()
+    {
+        return "javax.faces.NamingContainer";
+    }
+
+    private void saveState()
+    {
+        // getStateHelper().put(fieldRendererPropName, renderer);
+        // getStateHelper().put(inputInfoPropName, inpInfo);
+        getStateHelper().put(readOnlyState, (inpInfo==null));
+    }
+
+    private boolean initState(FacesContext context)
+    {
+        Boolean ros = (Boolean)getStateHelper().get(readOnlyState);
+        if (ros!=null && ros.booleanValue())
+            return false;
+        // renderer = ;
+        renderer = helper.getFieldRenderer();
+        inpInfo  = helper.getInputInfo(context);
+        return (renderer!=null && inpInfo!=null);
+    }
+
+    @Override
+    public void encodeBegin(FacesContext context)
+        throws IOException
+    {
+        // add label and input components when the view is loaded for the first time
+        super.encodeBegin(context);
+        
+        // init
+        helper.encodeBegin();
+        renderer = helper.getFieldRenderer();
+        
+        // render components
+        if (helper.isRecordReadOnly())
+        {
+            FieldRenderer.ValueInfo valInfo = helper.getValueInfo(context);
+            // render value
+            ResponseWriter writer = context.getResponseWriter();
+            String tag = writeStartElement(valInfo, writer);
+            renderer.renderValue(valInfo, writer);
+            writer.endElement(tag);
+        }
+        else
+        {
+            inpInfo = helper.getInputInfo(context);
+            // render input
+            renderer.renderInput(this, inpInfo, context, true);
+        }
+        saveState();
+    }
+
+    @Override
+    public Object getValue()
+    {
+        // check for record
+        if (helper.getRecord()!=null)
+            helper.getDataValue();
+        // default
+        return super.getValue();
+    }
+
+    @Override
+    public Object getSubmittedValue()
+    {   // Check state
+        if (renderer==null || inpInfo==null)
+            return null;
+        // get Input Value
+        return renderer.getInputValue(this, inpInfo, true);
+    }
+
+    @Override
+    public void validateValue(FacesContext context, Object value)
+    {   // Check state
+        if (inpInfo==null)
+            return;
+        // Validate value
+        inpInfo.validate(value);
+        setValid(true);
+        // call base class 
+        super.validateValue(context, value);
+    }    
+    
+    @Override
+    public void validate(FacesContext context)
+    {
+        if (initState(context)==false)
+            return;
+        // check disabled
+        if (inpInfo.isDisabled())
+            return;
+        // get submitted value and validate
+        if (log.isDebugEnabled())
+            log.debug("Validating input for {}.", inpInfo.getColumn().getName());
+        
+        // Validate value
+        try {
+            // Will internally call getSubmittedValue() and validateValue() 
+            super.validate(context);
+            
+        } catch(Exception e) {
+            // Value is not valid
+            helper.addErrorMessage(context, e);
+            setValid(false);
+        }
+    }
+
+    @Override
+    public void updateModel(FacesContext context)
+    {
+        if (initState(context)==false)
+            return;
+        // check disabled
+        if (inpInfo.isDisabled())
+            return;
+        // No Action
+        if (!isValid() || !isLocalValueSet())
+            return; 
+        // super.updateModel(context);
+        log.debug("Updating model input for {}.", inpInfo.getColumn().getName());
+        inpInfo.setValue(getLocalValue());
+        setValue(null);
+        setLocalValueSet(false);
+    }
+    
+    public Column getInputColumn()
+    {
+        return helper.getColumn();
+    }
+    
+    public boolean isInputReadOnly()
+    {
+        return helper.isRecordReadOnly();
+    }
+    
+    public boolean isInputRequired()
+    {
+        return helper.isValueRequired();
+    }
+
+    /**
+     * write value element
+     * @param vi
+     * @param writer
+     * @return
+     * @throws IOException
+     */
+    protected String writeStartElement(FieldRenderer.ValueInfo vi, ResponseWriter writer)
+        throws IOException
+    {
+        // tag and class name
+        String tagName = "span";
+        String className = helper.getTagStyleClass("eInpDis");
+        // other attributes
+        Map<String, Object> map = getAttributes();
+        Object style = map.get("style");
+        Object title = map.get("title");
+        // Write tag
+        writer.startElement(tagName, this);
+        helper.writeAttribute(writer, "class", className);
+        helper.writeAttribute(writer, "style", style);
+        helper.writeAttribute(writer, "title", helper.getValueTooltip(title));
+        return tagName;
+    }
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LabelTag.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LabelTag.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LabelTag.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LabelTag.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.jsf2.components;
+
+import java.io.IOException;
+
+import javax.faces.component.UIOutput;
+import javax.faces.component.html.HtmlOutputLabel;
+import javax.faces.context.FacesContext;
+
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.data.DataType;
+import org.apache.empire.jsf2.utils.TagRenderHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LabelTag extends UIOutput // implements NamingContainer
+{
+    // Logger
+    private static final Logger log = LoggerFactory.getLogger(LabelTag.class);
+    
+    private final TagRenderHelper helper = new TagRenderHelper(this, "eLabel");
+
+    public LabelTag()
+    {
+        log.trace("component LabelTag created");
+    }
+
+    @Override
+    public String getFamily()
+    {
+        return "javax.faces.NamingContainer";
+    }
+
+    @Override
+    public void encodeBegin(FacesContext context)
+        throws IOException
+    {
+        // add label and input components when the view is loaded for the first time
+        super.encodeBegin(context);
+        
+        // render components
+        HtmlOutputLabel labelComponent = null;
+        if (getChildCount() > 0)
+        {
+            labelComponent = (HtmlOutputLabel) getChildren().get(0);
+        }
+        if (labelComponent == null)
+        {
+            String forInput   = helper.getTagAttribute("for");
+            String styleClass = helper.getTagStyleClass(DataType.UNKNOWN);
+            String style      = helper.getTagAttribute("style");
+            // createLabelComponent 
+            labelComponent = helper.createLabelComponent(context, forInput, styleClass, style, getColon());
+            this.getChildren().add(labelComponent);
+        }
+
+        // render components
+        labelComponent.encodeAll(context);
+    }
+    
+    protected boolean getColon()
+    {
+        Object colon = getAttributes().get("colon");
+        if (colon!=null)
+            return ObjectUtils.getBoolean(colon);
+        // See if we have a record parent
+        return true;
+    }
+
+    /*
+    protected boolean isRequired(Column column)
+    {
+        Object required = getAttributes().get("required");
+        if (required!=null)
+            return ObjectUtils.getBoolean(required);
+        // See if we have a record parent
+        if (helper.isReadOnly())
+            return false;
+        // Required
+        return column.isRequired();
+    }
+    */
+    
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LabelTag.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LinkTag.java
URL: http://svn.apache.org/viewvc/empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LinkTag.java?rev=1326123&view=auto
==============================================================================
--- empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LinkTag.java (added)
+++ empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LinkTag.java Sat Apr 14 14:57:28 2012
@@ -0,0 +1,242 @@
+/*
+ * 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.List;
+import java.util.Map;
+
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UINamingContainer;
+import javax.faces.component.UIOutput;
+import javax.faces.component.UIParameter;
+import javax.faces.component.html.HtmlOutcomeTargetLink;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.data.DataType;
+import org.apache.empire.jsf2.controls.FieldRenderer;
+import org.apache.empire.jsf2.utils.StringResponseWriter;
+import org.apache.empire.jsf2.utils.TagRenderHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LinkTag extends UIOutput implements NamingContainer
+{
+    // or HtmlOutcomeTargetLink
+    // or HtmlOutputLink
+    // or rather extend UIOutcomeTarget ?
+
+    /*
+    <h:link value="#{msg.menu_bookinglist}"
+            outcome="/pages/bookings/bookingList.xhtml?faces-redirect=true" >
+        <f:param name="action" value="doInit"/>
+    </h:link>
+     */
+
+    // Logger
+    private static final Logger log = LoggerFactory.getLogger(LinkTag.class);
+    
+    private final TagRenderHelper helper = new TagRenderHelper(this, "eLink");
+
+    public LinkTag()
+    {
+        log.trace("component link created");
+    }
+
+    @Override
+    public String getFamily()
+    {
+        return UINamingContainer.COMPONENT_FAMILY; 
+    }
+
+    @Override
+    public void encodeBegin(FacesContext context)
+        throws IOException
+    {
+        // add label and input components when the view is loaded for the first time
+        super.encodeBegin(context);
+
+        // begin
+        helper.encodeBegin();
+        if (isLinkDisabled())
+        {   // render as span
+            // render components
+            ResponseWriter writer = context.getResponseWriter();
+            String tag = writeStartElement(writer);
+            writer.write(StringUtils.toString(getLinkValue(helper.hasColumn()), ""));
+            writer.endElement(tag);
+        }
+        else
+        {   // Add component
+            HtmlOutcomeTargetLink linkComponent = null;
+            if (getChildCount() > 0)
+            {
+                UIComponent c = getChildren().get(0);
+                if (c instanceof HtmlOutcomeTargetLink)
+                    linkComponent = (HtmlOutcomeTargetLink)c;
+                else
+                    log.info("TODO: handle Child nodes!");
+            }
+            if (linkComponent == null)
+            {
+                linkComponent = new HtmlOutcomeTargetLink();
+                this.getChildren().add(linkComponent);
+            }
+            // set params
+            setLinkProperties(linkComponent);
+            addOrSetParam(linkComponent, "idparam", "id");
+            // encode link
+            linkComponent.setRendered(true);
+            linkComponent.encodeAll(context);
+            linkComponent.setRendered(false); // Don't render twice!
+        }
+    }
+    
+    @Override 
+    public void encodeChildren(FacesContext context) throws IOException 
+    {
+        if (!isLinkDisabled())
+            super.encodeChildren(context);
+    }
+    
+    protected String getLinkStyleClass()
+    {
+        return StringUtils.toString(getAttributes().get("styleClass"));
+    }
+    
+    private boolean isLinkDisabled()
+    {
+        Object v = getAttributes().get("disabled");
+        if (v==null)
+            return false;
+        // return disabled attribute
+        return ObjectUtils.getBoolean(v); 
+    }
+    
+    private Object getLinkValue(boolean hasColumn)
+    {
+        // Is a column provided?
+        if (hasColumn)
+        {
+            FieldRenderer renderer = helper.getFieldRenderer();
+            FieldRenderer.ValueInfo vi = helper.getValueInfo(FacesContext.getCurrentInstance());
+            // render value
+            StringResponseWriter srw = new StringResponseWriter();
+            try
+            {
+                renderer.renderValue(vi, srw);
+            }
+            catch (IOException e)
+            {   // Error rendering value
+                log.error("Failed to render value for "+vi.getColumn().getName()+" error is:"+e.getMessage(), e);
+            }
+            return srw.toString();
+        }
+        else
+        {   // An ordinary link
+            Object value = getValue();
+            return value;
+        }
+    }
+
+    private void setLinkProperties(HtmlOutcomeTargetLink link)
+    {
+        boolean hasColumn = helper.hasColumn();
+        Object value = getLinkValue(hasColumn);
+        link.setValue(value);
+        // css Style
+        DataType dataType = (hasColumn ? helper.getColumn().getDataType() : DataType.UNKNOWN);
+        link.setStyleClass(helper.getTagStyleClass(dataType, null, getLinkStyleClass()));
+        // Set Attributes
+        Map<String,Object> attr = getAttributes();
+        // Set outcome
+        String outcome = StringUtils.toString(attr.get("page"));
+        link.setOutcome(outcome);
+        // Copy attributes
+        if ((value=attr.get("style"))!=null)
+            link.setStyle(StringUtils.toString(value));
+        if ((value=attr.get("tabindex"))!=null)
+            link.setTabindex(StringUtils.toString(value));
+        if ((value=attr.get("onclick"))!=null)
+            link.setOnclick(StringUtils.toString(value));
+        // include view param
+        link.setIncludeViewParams(false);
+    }
+    
+    private void addOrSetParam(HtmlOutcomeTargetLink link, String attribute, String paramName)
+    {
+        // Get Attribute
+        String paramValue = StringUtils.toString(getAttributes().get(attribute));
+        if (StringUtils.isEmpty(paramValue))
+            return; 
+        // find attribute
+        List<UIComponent> l = link.getChildren();
+        for (UIComponent c : l)
+        {
+            if (!(c instanceof UIParameter))
+                continue;
+            UIParameter p = (UIParameter)c; 
+            if (p.getName().equalsIgnoreCase(paramName))
+            {   // param existis
+                p.setValue(paramValue);
+                return;
+            }
+        }
+        // Not found, hence add
+        UIParameter param = new UIParameter();
+        param.setName(paramName);
+        param.setValue(paramValue);
+        link.getChildren().add(param);
+    }
+
+    protected String writeStartElement(ResponseWriter writer)
+        throws IOException
+    {
+        Map<String, Object> map = getAttributes();
+        String tagName  = StringUtils.coalesce(StringUtils.toString(map.get("tag")), "span");
+        String cssClass = helper.getTagStyleClass();
+        Object style = map.get("style");
+        Object title = map.get("title");
+        // Write tag
+        writer.startElement(tagName, this);
+        helper.writeAttribute(writer, "class", cssClass);
+        helper.writeAttribute(writer, "style", style);
+        helper.writeAttribute(writer, "title", helper.hasColumn() ? helper.getValueTooltip(title) : title);
+        return tagName;
+    }
+    
+    /*
+     * public String getLabelValue()
+     * {
+     * return StringUtils.toString(getValue());
+     * }
+     * public String getPageValue()
+     * {
+     * return (String) getAttributes().get("page");
+     * }
+     * public String getActionValue()
+     * {
+     * return (String) getAttributes().get("action");
+     * }
+     */
+}

Propchange: empire-db/trunk/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/LinkTag.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message