You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2010/03/29 03:18:22 UTC

svn commit: r928556 [1/5] - in /myfaces/tomahawk/trunk/core20: ./ src/main/conf/META-INF/ src/main/java/org/apache/myfaces/custom/calendar/ src/main/java/org/apache/myfaces/custom/inputHtml/ src/main/java/org/apache/myfaces/custom/inputTextHelp/ src/ma...

Author: lu4242
Date: Mon Mar 29 01:18:21 2010
New Revision: 928556

URL: http://svn.apache.org/viewvc?rev=928556&view=rev
Log:
TOMAHAWK-1472 Add Support for new Resource API in tomahawk 2.0 module (use jsf resource api as first choice)

Added:
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/calendar/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/calendar/HtmlCalendarRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputHtml/InputHtmlRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputTextHelp/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputTextHelp/HtmlTextHelpRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/jslistener/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/jslistener/JsValueChangeListenerRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/htmlnavmenu/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/htmlnavmenu/HtmlNavigationMenuRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/jscookmenu/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/jscookmenu/HtmlJSCookMenuRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/picklist/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/picklist/HtmlPicklistRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/popup/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/popup/HtmlPopupRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/schedule/AbstractCompactScheduleRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/schedule/AbstractScheduleRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/schedule/ScheduleDelegatingRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/swapimage/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/swapimage/HtmlSwapImageRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/tabbedpane/HtmlTabbedPaneRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/toggle/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/toggle/TogglePanelRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/tree2/HtmlTreeRenderer.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/tomahawk/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/tomahawk/application/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/tomahawk/application/PreRenderViewAddResourceEvent.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/tomahawk/application/ResourceViewHandlerWrapper.java
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/tomahawk/util/
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/tomahawk/util/TomahawkResourceUtils.java
Modified:
    myfaces/tomahawk/trunk/core20/pom.xml
    myfaces/tomahawk/trunk/core20/src/main/conf/META-INF/faces-config-base.xml
    myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputHtml/InputHtml.java

Modified: myfaces/tomahawk/trunk/core20/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/pom.xml?rev=928556&r1=928555&r2=928556&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core20/pom.xml (original)
+++ myfaces/tomahawk/trunk/core20/pom.xml Mon Mar 29 01:18:21 2010
@@ -390,7 +390,68 @@
                   <artifactId>tomahawk12</artifactId>
                   <version>${pom.version}</version>                                   
                   <outputDirectory>${project.build.directory}/tomahawk12_resources</outputDirectory>
-                  <excludes>**/*.class,**/META-INF/**</excludes>
+                  <excludes>**/*.class,**/META-INF/**,
+                  org/apache/myfaces/component/**,
+                  org/apache/myfaces/convert/**,
+                  org/apache/myfaces/converter/**,
+                  org/apache/myfaces/custom/aliasbean/**,
+                  org/apache/myfaces/custom/buffer/**,
+                  org/apache/myfaces/custom/calendar/**,
+                  org/apache/myfaces/custom/captcha/**,
+                  org/apache/myfaces/custom/checkbox/**,
+                  org/apache/myfaces/custom/collapsiblepanel/**,
+                  org/apache/myfaces/custom/column/**,
+                  org/apache/myfaces/custom/creditcardvalidator/**,
+                  org/apache/myfaces/custom/crosstable/**,
+                  org/apache/myfaces/custom/datalist/**,
+                  org/apache/myfaces/custom/datascroller/**,
+                  org/apache/myfaces/custom/date/**,
+                  org/apache/myfaces/custom/div/**,
+                  org/apache/myfaces/custom/document/**,
+                  org/apache/myfaces/custom/emailvalidator/**,
+                  org/apache/myfaces/custom/equalvalidator/**,
+                  org/apache/myfaces/custom/fieldset/**,
+                  org/apache/myfaces/custom/fileupload/**,
+                  org/apache/myfaces/custom/htmlTag/**,
+                  org/apache/myfaces/custom/inputHtml/**,
+                  org/apache/myfaces/custom/inputTextHelp/**,
+                  org/apache/myfaces/custom/jslistener/**,
+                  org/apache/myfaces/custom/jsvalueset/**,
+                  org/apache/myfaces/custom/layout/**,
+                  org/apache/myfaces/custom/navigation/**,
+                  org/apache/myfaces/custom/navmenu/**,
+                  org/apache/myfaces/custom/newspaper/**,
+                  org/apache/myfaces/custom/panelstack/**,
+                  org/apache/myfaces/custom/picklist/**,
+                  org/apache/myfaces/custom/popup/**,
+                  org/apache/myfaces/custom/prototype/**,
+                  org/apache/myfaces/custom/radio/**,
+                  org/apache/myfaces/custom/regexprvalidator/**,
+                  org/apache/myfaces/custom/savestate/**,
+                  org/apache/myfaces/custom/schedule/**,
+                  org/apache/myfaces/custom/selectitems/**,
+                  org/apache/myfaces/custom/selectOneCountry/**,
+                  org/apache/myfaces/custom/selectOneLanguage/**,
+                  org/apache/myfaces/custom/selectOneRow/**,
+                  org/apache/myfaces/custom/sortheader/**,
+                  org/apache/myfaces/custom/stylesheet/**,
+                  org/apache/myfaces/custom/subform/**,
+                  org/apache/myfaces/custom/swapimage/**,
+                  org/apache/myfaces/custom/tabbedpane/**,
+                  org/apache/myfaces/custom/toggle/**,
+                  org/apache/myfaces/custom/transform/**,
+                  org/apache/myfaces/custom/tree/**,
+                  org/apache/myfaces/custom/tree2/**,
+                  org/apache/myfaces/custom/updateactionlistener/**,
+                  org/apache/myfaces/dateformat/**,
+                  org/apache/myfaces/generated/**,
+                  org/apache/myfaces/renderkit/html/ext/**,
+                  org/apache/myfaces/renderkit/html/jsf/**,
+                  org/apache/myfaces/shared_tomahawk/**,
+                  org/apache/myfaces/taglib/**,
+                  org/apache/myfaces/tomahawk/**,
+                  org/apache/myfaces/validator/**,
+                  org/apache/myfaces/webapp/**</excludes>
                 </artifactItem>
               </artifactItems>
             </configuration>

Modified: myfaces/tomahawk/trunk/core20/src/main/conf/META-INF/faces-config-base.xml
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/conf/META-INF/faces-config-base.xml?rev=928556&r1=928555&r2=928556&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/conf/META-INF/faces-config-base.xml (original)
+++ myfaces/tomahawk/trunk/core20/src/main/conf/META-INF/faces-config-base.xml Mon Mar 29 01:18:21 2010
@@ -23,7 +23,10 @@
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" 
               version="2.0">
-
+  <name>tomahawk</name>
+  <application>
+      <view-handler>org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper</view-handler>
+  </application>
   <lifecycle>
 
       <phase-listener>org.apache.myfaces.webapp.filter.ServeResourcePhaseListener</phase-listener>

Added: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/calendar/HtmlCalendarRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/calendar/HtmlCalendarRenderer.java?rev=928556&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/calendar/HtmlCalendarRenderer.java (added)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/calendar/HtmlCalendarRenderer.java Mon Mar 29 01:18:21 2010
@@ -0,0 +1,1274 @@
+/*
+ * 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.myfaces.custom.calendar;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.component.UserRoleUtils;
+import org.apache.myfaces.custom.inputTextHelp.HtmlInputTextHelp;
+import org.apache.myfaces.custom.prototype.PrototypeResourceLoader;
+import org.apache.myfaces.dateformat.SimpleDateFormatter;
+import org.apache.myfaces.renderkit.html.util.AddResource;
+import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
+import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
+import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.util.JavascriptUtils;
+import org.apache.myfaces.shared_tomahawk.util.MessageUtils;
+import org.apache.myfaces.tomahawk.application.PreRenderViewAddResourceEvent;
+import org.apache.myfaces.tomahawk.util.TomahawkResourceUtils;
+
+import javax.faces.application.Application;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.UIParameter;
+import javax.faces.component.html.HtmlCommandLink;
+import javax.faces.component.html.HtmlOutputText;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import javax.faces.convert.DateTimeConverter;
+import javax.faces.event.ComponentSystemEvent;
+import javax.faces.event.ComponentSystemEventListener;
+import javax.faces.event.ListenerFor;
+import javax.faces.render.Renderer;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Render a "calendar" which the user can use to choose a specific day.
+ * <p>
+ * This renderer behaves quite differently for "inline" and "popup" calendars.
+ * <p>
+ * When inline, this component automatically creates child components (text and
+ * link components) to represent all the dates, scrollers, etc. within itself and
+ * renders those children. Clicking on any link in the component causes the
+ * surrounding form to immediately submit.
+ * <p>
+ * When popup, this component just renders an empty span with the component id,
+ * and a dozen or so lines of javascript which create an instance of a
+ * "tomahawk calendar object", set its properties from the properties on the
+ * associated HtmlInputCalendar component, and then invoke it. That javascript
+ * object then dynamically builds DOM objects and attaches them to the empty span.
+ * This component also renders a button or image that toggles the visibility of
+ * that empty span, thereby making the popup appear and disappear.
+ * <p>
+ * Note that the two ways of generating the calendar use totally different code;
+ * one implementation is here and the other is in a javascript resource file. For
+ * obvious reasons the appearance of the two calendars should be similar, so if a
+ * feature is added in one place it is recommended that the other be updated also. 
+ * <p>
+ * The behaviour of both of the Calendar objects varies depending upon the 
+ * "current locale". This is derived from getViewRoot().getLocale(), which is
+ * normally set according to the browser preferences; users whose browsers
+ * have "english" as the preferred language will get the "en" locale, while
+ * users with "deutsch" as the preferred language will get the "de" locale.
+ * One specific example is the "first day of week" (ie the day displayed at
+ * the left of each week row); this is "sunday" for the english locale, and
+ * "monday" for the german locale. There is currently no way for the
+ * calendar component to be configured to force a specific firstDayOfWeek
+ * to be used for all users.
+ * <p>
+ * 
+ * @JSFRenderer
+ *   renderKitId = "HTML_BASIC" 
+ *   family = "javax.faces.Input"
+ *   type = "org.apache.myfaces.Calendar"
+ * 
+ * @author Martin Marinschek (latest modification by $Author: lu4242 $)
+ * @version $Revision: 784635 $ $Date: 2009-06-14 18:49:00 -0500 (dom, 14 jun 2009) $
+ */
+@ListenerFor(systemEventClass=PreRenderViewAddResourceEvent.class)
+public class HtmlCalendarRenderer
+        extends HtmlRenderer implements ComponentSystemEventListener
+{
+    private final Log log = LogFactory.getLog(HtmlCalendarRenderer.class);
+
+    private static final String JAVASCRIPT_ENCODED = "org.apache.myfaces.calendar.JAVASCRIPT_ENCODED";
+
+    // TODO: move this to HtmlRendererUtils in shared
+    private static final String RESOURCE_NONE = "none";
+
+    public void processEvent(ComponentSystemEvent event)
+    {
+        HtmlInputCalendar inputCalendar = (HtmlInputCalendar) event.getComponent();
+        
+        if (inputCalendar.isRenderAsPopup() && inputCalendar.isAddResources())
+        {
+            addScriptAndCSSResources(FacesContext.getCurrentInstance(), inputCalendar);
+        }
+    }
+
+    public void encodeEnd(FacesContext facesContext, UIComponent component)
+            throws IOException
+    {
+        RendererUtils.checkParamValidity(facesContext, component, HtmlInputCalendar.class);
+
+        HtmlInputCalendar inputCalendar = (HtmlInputCalendar) component;
+
+        Locale currentLocale = facesContext.getViewRoot().getLocale();
+        log.debug("current locale:" + currentLocale.toString());
+
+        Date value;
+
+        try
+        {
+            // value = RendererUtils.getDateValue(inputCalendar);
+            Converter converter = getConverter(inputCalendar);
+            if (converter instanceof DateConverter)
+            {
+                value = ((DateConverter) converter).getAsDate(facesContext, component);
+            }
+            else
+            {
+                //value = RendererUtils.getDateValue(inputCalendar);
+                Object objectValue = RendererUtils.getObjectValue(component);
+                if (objectValue == null || objectValue instanceof Date)
+                {
+                    value = (Date) objectValue;
+                }
+                else
+                {
+                    //Use Converter.getAsString and convert to date using 
+                    String stringValue = converter.getAsString(facesContext, component, objectValue);
+
+                    if(stringValue ==null || stringValue.trim().length()==0 ||stringValue.equals(getHelperString(inputCalendar)))
+                    {
+                        value = null;
+                    }
+                    else
+                    {
+                        String formatStr = CalendarDateTimeConverter.createJSPopupFormat(facesContext, inputCalendar.getPopupDateFormat());
+                        Calendar timeKeeper = Calendar.getInstance(currentLocale);
+                        int firstDayOfWeek = timeKeeper.getFirstDayOfWeek() - 1;
+                        org.apache.myfaces.dateformat.DateFormatSymbols symbols = new org.apache.myfaces.dateformat.DateFormatSymbols(currentLocale);
+    
+                        SimpleDateFormatter dateFormat = new SimpleDateFormatter(formatStr, symbols, firstDayOfWeek);
+                        value = dateFormat.parse(stringValue);
+                    }
+                }
+            }
+        }
+        catch (IllegalArgumentException illegalArgumentException)
+        {
+            value = null;
+        }
+
+
+        Calendar timeKeeper = Calendar.getInstance(currentLocale);
+        timeKeeper.setTime(value!=null?value:new Date());
+
+        DateFormatSymbols symbols = new DateFormatSymbols(currentLocale);
+
+        if(inputCalendar.isRenderAsPopup())
+        {
+            renderPopup(facesContext, inputCalendar, value, timeKeeper, symbols);
+        }
+        else
+        {
+            renderInline(facesContext, inputCalendar, value, timeKeeper, symbols);
+        }
+
+        component.getChildren().removeAll(component.getChildren());
+    }
+
+    private void renderPopup(
+            FacesContext facesContext, 
+            HtmlInputCalendar inputCalendar,
+            Date value,
+            Calendar timeKeeper,
+            DateFormatSymbols symbols) throws IOException
+    {
+        //if(inputCalendar.isAddResources())
+        //    addScriptAndCSSResources(facesContext, inputCalendar);
+
+         // Check for an enclosed converter:
+         UIInput uiInput = (UIInput) inputCalendar;
+         Converter converter = uiInput.getConverter();
+         String dateFormat = null;
+         if (converter != null && converter instanceof DateTimeConverter) {
+             dateFormat = ((DateTimeConverter) converter).getPattern();
+         }
+         if (dateFormat == null) {
+             dateFormat = CalendarDateTimeConverter.createJSPopupFormat(facesContext,
+                                                                        inputCalendar.getPopupDateFormat());
+         }
+
+        Application application = facesContext.getApplication();
+
+        HtmlInputTextHelp inputText = getOrCreateInputTextChild(inputCalendar, application);
+
+        RendererUtils.copyHtmlInputTextAttributes(inputCalendar, inputText);
+
+        inputText.setConverter(null); // value for this transient component will already be converted
+        inputText.setTransient(true);
+        inputText.setHelpText(inputCalendar.getHelpText());
+        inputText.setSelectText(true);
+
+        if (value == null && inputCalendar.getSubmittedValue() != null)
+        {
+            inputText.setValue(inputCalendar.getSubmittedValue());
+        }
+        else
+        {
+            inputText.setValue(getConverter(inputCalendar).getAsString(
+                    facesContext,inputCalendar,value));
+        }
+        inputText.setDisabled(inputCalendar.isDisabled());
+        inputText.setReadonly(inputCalendar.isReadonly());
+        inputText.setEnabledOnUserRole(inputCalendar.getEnabledOnUserRole());
+        inputText.setVisibleOnUserRole(inputCalendar.getVisibleOnUserRole());
+
+        //This is where two components with the same id are in the tree,
+        //so make sure that during the rendering the id is unique.
+
+        inputCalendar.setId(inputCalendar.getId()+"tempId");
+
+        inputCalendar.getChildren().add(inputText);
+
+        RendererUtils.renderChild(facesContext, inputText);
+
+        inputCalendar.getChildren().remove(inputText);
+
+        //Set back the correct id to the input calendar
+        inputCalendar.setId(inputText.getId());
+
+        ResponseWriter writer = facesContext.getResponseWriter();
+
+        writer.startElement(HTML.SPAN_ELEM,inputCalendar);
+        writer.writeAttribute(HTML.ID_ATTR,inputCalendar.getClientId(facesContext)+"Span",
+                              JSFAttr.ID_ATTR);
+        writer.endElement(HTML.SPAN_ELEM);
+
+        if (!isDisabled(facesContext, inputCalendar) && !inputCalendar.isReadonly())
+        {
+            writer.startElement(HTML.SCRIPT_ELEM, inputCalendar);
+            writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR,HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT,null);
+
+            String calendarVar = JavascriptUtils.getValidJavascriptName(
+                    inputCalendar.getClientId(facesContext)+"CalendarVar",false);
+
+            writer.writeText(calendarVar+"=new org_apache_myfaces_PopupCalendar();\n",null);
+            writer.writeText(getLocalizedLanguageScript(facesContext,symbols,
+                                                        timeKeeper.getFirstDayOfWeek(),inputCalendar,calendarVar)+"\n",null);
+            // pass the selectMode attribute
+            StringBuffer script = new StringBuffer();
+            setStringVariable(script, calendarVar +".initData.selectMode",inputCalendar.getPopupSelectMode());
+            writer.writeText(script.toString(), null);
+
+            writer.writeText(calendarVar+".init(document.getElementById('"+
+                             inputCalendar.getClientId(facesContext)+"Span"+"'));\n",null);
+            writer.endElement(HTML.SCRIPT_ELEM);
+            if(!inputCalendar.isDisplayValueOnly())
+            {
+                getScriptBtn(writer, facesContext, inputCalendar,
+                                              dateFormat,inputCalendar.getPopupButtonString(), new FunctionCallProvider(){
+                    public String getFunctionCall(FacesContext facesContext, UIComponent uiComponent, String dateFormat)
+                    {
+                        String clientId = uiComponent.getClientId(facesContext);
+
+                        String clientVar = JavascriptUtils.getValidJavascriptName(clientId+"CalendarVar",true);
+
+                        return clientVar+"._popUpCalendar(this,document.getElementById('"+clientId+"'),'"+dateFormat+"')";
+                    }
+                });
+            }
+        }
+    }
+
+    private void renderInline(
+            FacesContext facesContext, 
+            HtmlInputCalendar inputCalendar,
+            Date value,
+            Calendar timeKeeper,
+            DateFormatSymbols symbols) throws IOException
+    {
+        String[] weekdays = mapShortWeekdays(symbols);
+        String[] months = mapMonths(symbols);
+
+        int lastDayInMonth = timeKeeper.getActualMaximum(Calendar.DAY_OF_MONTH);
+
+        int currentDay = timeKeeper.get(Calendar.DAY_OF_MONTH);
+
+        if (currentDay > lastDayInMonth)
+            currentDay = lastDayInMonth;
+
+        timeKeeper.set(Calendar.DAY_OF_MONTH, 1);
+
+        int weekDayOfFirstDayOfMonth = mapCalendarDayToCommonDay(timeKeeper.get(Calendar.DAY_OF_WEEK));
+
+        int weekStartsAtDayIndex = mapCalendarDayToCommonDay(timeKeeper.getFirstDayOfWeek());
+
+        ResponseWriter writer = facesContext.getResponseWriter();
+
+        HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+        HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+
+        writer.startElement(HTML.TABLE_ELEM, inputCalendar);
+        HtmlRendererUtils.renderHTMLAttributes(writer, inputCalendar, HTML.UNIVERSAL_ATTRIBUTES);
+        HtmlRendererUtils.renderHTMLAttributes(writer, inputCalendar, HTML.EVENT_HANDLER_ATTRIBUTES);
+        HtmlRendererUtils.renderHTMLAttributes(writer, inputCalendar, HTML.COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE);
+        writer.flush();
+
+        HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+
+        writer.startElement(HTML.TR_ELEM, inputCalendar);
+
+        if(inputCalendar.getMonthYearRowClass() != null)
+            writer.writeAttribute(HTML.CLASS_ATTR, inputCalendar.getMonthYearRowClass(), null);
+
+        writeMonthYearHeader(facesContext, writer, inputCalendar, timeKeeper,
+                             currentDay, weekdays, months);
+
+        writer.endElement(HTML.TR_ELEM);
+
+        HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+
+        writer.startElement(HTML.TR_ELEM, inputCalendar);
+
+        if(inputCalendar.getWeekRowClass() != null)
+            writer.writeAttribute(HTML.CLASS_ATTR, inputCalendar.getWeekRowClass(), null);
+
+        writeWeekDayNameHeader(weekStartsAtDayIndex, weekdays,
+                               facesContext, writer, inputCalendar);
+
+        writer.endElement(HTML.TR_ELEM);
+
+        HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+
+        writeDays(facesContext, writer, inputCalendar, timeKeeper,
+                  currentDay, weekStartsAtDayIndex, weekDayOfFirstDayOfMonth,
+                  lastDayInMonth, weekdays);
+
+        writer.endElement(HTML.TABLE_ELEM);
+    }
+
+    private HtmlInputTextHelp getOrCreateInputTextChild(HtmlInputCalendar inputCalendar, Application application)
+    {
+        HtmlInputTextHelp inputText = null;
+
+        List li = inputCalendar.getChildren();
+
+        for (int i = 0; i < li.size(); i++)
+        {
+            UIComponent uiComponent = (UIComponent) li.get(i);
+
+            if(uiComponent instanceof HtmlInputTextHelp)
+            {
+                inputText = (HtmlInputTextHelp) uiComponent;
+                break;
+            }
+        }
+
+        if(inputText == null)
+        {
+            inputText = (HtmlInputTextHelp) application.createComponent(HtmlInputTextHelp.COMPONENT_TYPE);
+        }
+        return inputText;
+    }
+
+    /**
+     * Used by the x:inputDate renderer : HTMLDateRenderer
+     */
+    static public void addScriptAndCSSResources(FacesContext facesContext, UIComponent component){
+        // Check to see if javascript has already been written (which could happen if more than one calendar
+        // on the same page). Note that this means that if two calendar controls in the same page have
+        // different styleLocation or scriptLocation settings then all but the first one get ignored.
+        // Having different settings for calendars on the same page would be unusual, so ignore this
+        // for now..
+        if (facesContext.getExternalContext().getRequestMap().containsKey(JAVASCRIPT_ENCODED))
+        {
+            return;
+        }
+
+        AddResource addresource = AddResourceFactory.getInstance(facesContext);
+        // Add the javascript and CSS pages
+
+        String styleLocation = HtmlRendererUtils.getStyleLocation(component);
+
+        if(styleLocation==null)
+        {
+            //addresource.addStyleSheet(facesContext, AddResource.HEADER_BEGIN, HtmlCalendarRenderer.class, "WH/theme.css");
+            TomahawkResourceUtils.addOutputStylesheetResource(facesContext, "oam.custom.calendar.WH", "theme.css");
+            //addresource.addStyleSheet(facesContext, AddResource.HEADER_BEGIN, HtmlCalendarRenderer.class, "DB/theme.css");
+            TomahawkResourceUtils.addOutputStylesheetResource(facesContext, "oam.custom.calendar.DB", "theme.css");
+        }
+        else if (!RESOURCE_NONE.equals(styleLocation))
+        {
+            addresource.addStyleSheet(facesContext, AddResource.HEADER_BEGIN, styleLocation+"/theme.css");
+        }
+        else
+        {
+            // output nothing; presumably the page directly references the necessary stylesheet
+        }
+
+        String javascriptLocation = HtmlRendererUtils.getJavascriptLocation(component);
+
+        if(javascriptLocation==null)
+        {
+            //addresource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, PrototypeResourceLoader.class, "prototype.js");
+            TomahawkResourceUtils.addOutputScriptResource(facesContext, "oam.custom.prototype", "prototype.js");
+            //addresource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, HtmlCalendarRenderer.class, "date.js");
+            TomahawkResourceUtils.addOutputScriptResource(facesContext, "oam.custom.calendar", "date.js");
+            //addresource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, HtmlCalendarRenderer.class, "popcalendar.js");
+            TomahawkResourceUtils.addOutputScriptResource(facesContext, "oam.custom.calendar", "popcalendar.js");
+        }
+        else if (!RESOURCE_NONE.equals(javascriptLocation))
+        {
+            addresource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, javascriptLocation+ "/prototype.js");
+            addresource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, javascriptLocation+ "/date.js");
+            addresource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, javascriptLocation+ "/popcalendar.js");
+        }
+        else
+        {
+            // output nothing; presumably the page directly references the necessary javascript
+        }
+
+        facesContext.getExternalContext().getRequestMap().put(JAVASCRIPT_ENCODED, Boolean.TRUE);
+    }
+    
+    
+    /**
+     * Creates and returns a String which contains the initialisation data for
+     * the popup calendar control as a sequence of javascript commands that
+     * assign values to properties of a javascript object whose name is in
+     * parameter popupCalendarVariable.
+     * <p>
+     * 
+     * @param firstDayOfWeek
+     *            is in java.util.Calendar form, ie Sun=1, Mon=2, Sat=7
+     */
+    public static String getLocalizedLanguageScript(FacesContext facesContext,
+            DateFormatSymbols symbols, int firstDayOfWeek, UIComponent uiComponent,
+            String popupCalendarVariable)
+    {
+
+        // Convert day value to java.util.Date convention (Sun=0, Mon=1, Sat=6).
+        // This is the convention that javascript Date objects use.
+        int realFirstDayOfWeek = firstDayOfWeek - 1;
+
+        String[] weekDays;
+
+        if (realFirstDayOfWeek == 0)
+        {
+            // Sunday
+            weekDays = mapShortWeekdaysStartingWithSunday(symbols);
+        }
+        else if (realFirstDayOfWeek == 1)
+        {
+            // Monday
+            weekDays = mapShortWeekdays(symbols);
+        }
+        else if (realFirstDayOfWeek == 6)
+        {
+            // Saturday. Often used in Arabic countries
+            weekDays = mapShortWeekdaysStartingWithSaturday(symbols);
+        }
+        else
+        {
+            throw new IllegalStateException("Week may only start with saturday, sunday or monday.");
+        }
+
+        StringBuffer script = new StringBuffer();
+        AddResource ar = AddResourceFactory.getInstance(facesContext);
+
+        if (uiComponent instanceof HtmlInputCalendar)
+        {
+            HtmlInputCalendar calendar = (HtmlInputCalendar) uiComponent;
+            // Set the themePrefix variable
+            String popupTheme = calendar.getPopupTheme();
+            if (popupTheme == null)
+            {
+                popupTheme = "DB";
+            }
+            setStringVariable(script, popupCalendarVariable + ".initData.themePrefix",
+                    "jscalendar-" + popupTheme);
+
+            // specify the URL for the directory in which all the .gif images
+            // can be found
+            String imageLocation = HtmlRendererUtils.getImageLocation(uiComponent);
+            if (imageLocation == null)
+            {
+                String uri = ar.getResourceUri(facesContext, HtmlCalendarRenderer.class, popupTheme
+                        + "/");
+                setStringVariable(script, popupCalendarVariable + ".initData.imgDir",
+                        JavascriptUtils.encodeString(uri));
+            }
+            else
+            {
+                setStringVariable(script, popupCalendarVariable + ".initData.imgDir",
+                        (JavascriptUtils.encodeString(AddResourceFactory.getInstance(facesContext)
+                                .getResourceUri(facesContext, imageLocation + "/"))));
+            }
+        }
+        else
+        {
+            String imageLocation = HtmlRendererUtils.getImageLocation(uiComponent);
+            if (imageLocation == null)
+            {
+                String uri = ar.getResourceUri(facesContext, HtmlCalendarRenderer.class, "images/");
+                setStringVariable(script, popupCalendarVariable + ".initData.imgDir",
+                        JavascriptUtils.encodeString(uri));
+            }
+            else
+            {
+                setStringVariable(script, popupCalendarVariable + ".initData.imgDir",
+                        (JavascriptUtils.encodeString(AddResourceFactory.getInstance(facesContext)
+                                .getResourceUri(facesContext, imageLocation + "/"))));
+            }
+        }
+        defineStringArray(script, popupCalendarVariable + ".initData.monthName", mapMonths(symbols));
+        defineStringArray(script, popupCalendarVariable + ".initData.dayName", weekDays);
+        setIntegerVariable(script, popupCalendarVariable + ".initData.startAt", realFirstDayOfWeek);
+
+        defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.weekdays",
+                mapWeekdaysStartingWithSunday(symbols));
+        defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.shortWeekdays",
+                mapShortWeekdaysStartingWithSunday(symbols));
+        defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.shortMonths",
+                mapShortMonths(symbols));
+        defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.months",
+                mapMonths(symbols));
+        defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.eras", symbols
+                .getEras());
+        defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.ampms", symbols
+                .getAmPmStrings());
+
+        if (uiComponent instanceof HtmlInputCalendar)
+        {
+
+            HtmlInputCalendar inputCalendar = (HtmlInputCalendar) uiComponent;
+
+            if (inputCalendar.getPopupGotoString() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.gotoString",
+                        inputCalendar.getPopupGotoString());
+            if (inputCalendar.getPopupTodayString() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.todayString",
+                        inputCalendar.getPopupTodayString());
+            if (inputCalendar.getPopupTodayDateFormat() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.todayDateFormat",
+                        inputCalendar.getPopupTodayDateFormat());
+            else if (inputCalendar.getPopupDateFormat() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.todayDateFormat",
+                        inputCalendar.getPopupDateFormat());
+            if (inputCalendar.getPopupWeekString() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.weekString",
+                        inputCalendar.getPopupWeekString());
+            if (inputCalendar.getPopupScrollLeftMessage() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.scrollLeftMessage",
+                        inputCalendar.getPopupScrollLeftMessage());
+            if (inputCalendar.getPopupScrollRightMessage() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.scrollRightMessage",
+                        inputCalendar.getPopupScrollRightMessage());
+            if (inputCalendar.getPopupSelectMonthMessage() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.selectMonthMessage",
+                        inputCalendar.getPopupSelectMonthMessage());
+            if (inputCalendar.getPopupSelectYearMessage() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.selectYearMessage",
+                        inputCalendar.getPopupSelectYearMessage());
+            if (inputCalendar.getPopupSelectDateMessage() != null)
+                setStringVariable(script, popupCalendarVariable + ".initData.selectDateMessage",
+                        inputCalendar.getPopupSelectDateMessage());
+            setBooleanVariable(script, popupCalendarVariable + ".initData.popupLeft", inputCalendar
+                    .isPopupLeft());
+
+        }
+
+        return script.toString();
+    }
+
+    private static void setBooleanVariable(StringBuffer script, String name, boolean value)
+    {
+        script.append(name);
+        script.append(" = ");
+        script.append(value);
+        script.append(";\n");
+    }
+
+    private static void setIntegerVariable(StringBuffer script, String name, int value)
+    {
+        script.append(name);
+        script.append(" = ");
+        script.append(value);
+        script.append(";\n");
+    }
+
+    private static void setStringVariable(StringBuffer script, String name, String value)
+    {
+        script.append(name);
+        script.append(" = \"");
+        script.append(StringEscapeUtils.escapeJavaScript(value));
+        script.append("\";\n");
+    }
+
+    private static void defineStringArray(StringBuffer script, String arrayName, String[] array)
+    {
+        script.append(arrayName);
+        script.append(" = new Array(");
+
+        for(int i=0;i<array.length;i++)
+        {
+            if(i!=0)
+                script.append(",");
+
+            script.append("\"");
+            script.append(StringEscapeUtils.escapeJavaScript(array[i]));
+            script.append("\"");
+        }
+
+        script.append(");\n");
+    }
+
+    public static void getScriptBtn(ResponseWriter writer, FacesContext facesContext, UIComponent uiComponent,
+                                      String dateFormat, String popupButtonString, FunctionCallProvider prov)
+        throws IOException
+    {
+        boolean renderButtonAsImage = false;
+        String popupButtonStyle = null;
+        String popupButtonStyleClass = null;
+
+        if(uiComponent instanceof HtmlInputCalendar)
+        {
+            HtmlInputCalendar calendar = (HtmlInputCalendar)uiComponent;
+            renderButtonAsImage = calendar.isRenderPopupButtonAsImage();
+            popupButtonStyle = calendar.getPopupButtonStyle();
+            popupButtonStyleClass = calendar.getPopupButtonStyleClass();
+        }
+
+        if (!renderButtonAsImage) {
+            // render the button
+            writer.startElement(HTML.INPUT_ELEM, uiComponent);
+            writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_BUTTON, null);
+
+            writer.writeAttribute(HTML.ONCLICK_ATTR,
+                                  prov.getFunctionCall(facesContext,uiComponent,dateFormat),
+                                  null);
+
+            if(popupButtonString==null)
+                popupButtonString="...";
+            writer.writeAttribute(HTML.VALUE_ATTR, StringEscapeUtils.escapeJavaScript(popupButtonString), null);
+
+            if(popupButtonStyle != null)
+            {
+                writer.writeAttribute(HTML.STYLE_ATTR, popupButtonStyle, null);
+            }
+
+            if(popupButtonStyleClass != null)
+            {
+                writer.writeAttribute(HTML.CLASS_ATTR, popupButtonStyleClass, null);
+            }
+            
+            writer.endElement(HTML.INPUT_ELEM);
+        } else {
+            // render the image
+            writer.startElement(HTML.IMG_ELEM, uiComponent);
+            AddResource addResource = AddResourceFactory.getInstance(facesContext);
+
+            String imgUrl = (String) uiComponent.getAttributes().get("popupButtonImageUrl");
+
+            if(imgUrl!=null)
+            {
+                writer.writeAttribute(HTML.SRC_ATTR, addResource.getResourceUri(facesContext, imgUrl), null);
+            }
+            else
+            {
+                writer.writeAttribute(HTML.SRC_ATTR, addResource.getResourceUri(facesContext, HtmlCalendarRenderer.class, "images/calendar.gif"), null);
+            }
+
+            if(popupButtonStyle != null)
+            {
+                writer.writeAttribute(HTML.STYLE_ATTR, popupButtonStyle, null);
+            }
+            else
+            {
+                writer.writeAttribute(HTML.STYLE_ATTR, "vertical-align:bottom;", null);
+            }
+
+            if(popupButtonStyleClass != null)
+            {
+                writer.writeAttribute(HTML.CLASS_ATTR, popupButtonStyleClass, null);
+            }
+
+            writer.writeAttribute(HTML.ONCLICK_ATTR, prov.getFunctionCall(facesContext, uiComponent, dateFormat),
+                                  null);
+
+            writer.endElement(HTML.IMG_ELEM);
+        }
+    }
+
+
+    private void writeMonthYearHeader(FacesContext facesContext, ResponseWriter writer, UIInput inputComponent, Calendar timeKeeper,
+                                      int currentDay, String[] weekdays,
+                                      String[] months)
+            throws IOException
+    {
+        Calendar cal = shiftMonth(facesContext, timeKeeper, currentDay, -1);
+
+        writeCell(facesContext, writer, inputComponent, "<", cal.getTime(), null);
+
+        writer.startElement(HTML.TD_ELEM, inputComponent);
+        writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(weekdays.length - 2), null);
+        writer.writeText(months[timeKeeper.get(Calendar.MONTH)] + " " + timeKeeper.get(Calendar.YEAR), null);
+        writer.endElement(HTML.TD_ELEM);
+
+        cal = shiftMonth(facesContext, timeKeeper, currentDay, 1);
+
+        writeCell(facesContext, writer, inputComponent, ">", cal.getTime(), null);
+    }
+
+    private Calendar shiftMonth(FacesContext facesContext,
+                                Calendar timeKeeper, int currentDay, int shift)
+    {
+        Calendar cal = copyCalendar(facesContext, timeKeeper);
+
+        cal.set(Calendar.DAY_OF_MONTH, 1);
+        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + shift);
+
+        if(currentDay > cal.getActualMaximum(Calendar.DAY_OF_MONTH))
+            currentDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+
+        cal.set(Calendar.DAY_OF_MONTH, currentDay);
+        return cal;
+    }
+
+    private Calendar copyCalendar(FacesContext facesContext, Calendar timeKeeper)
+    {
+        Calendar cal = Calendar.getInstance(facesContext.getViewRoot().getLocale());
+        cal.setTime(timeKeeper.getTime());
+        return cal;
+    }
+
+    private void writeWeekDayNameHeader(int weekStartsAtDayIndex, String[] weekdays, FacesContext facesContext, ResponseWriter writer, UIInput inputComponent)
+            throws IOException
+    {
+        for (int i = weekStartsAtDayIndex; i < weekdays.length; i++)
+            writeCell(facesContext,
+                      writer, inputComponent, weekdays[i], null, null);
+
+        for (int i = 0; i < weekStartsAtDayIndex; i++)
+            writeCell(facesContext, writer,
+                      inputComponent, weekdays[i], null, null);
+    }
+
+    private void writeDays(FacesContext facesContext, ResponseWriter writer,
+                           HtmlInputCalendar inputComponent, Calendar timeKeeper, int currentDay, int weekStartsAtDayIndex,
+                           int weekDayOfFirstDayOfMonth, int lastDayInMonth, String[] weekdays)
+            throws IOException
+    {
+        Calendar cal;
+
+        int space = (weekStartsAtDayIndex < weekDayOfFirstDayOfMonth) ? (weekDayOfFirstDayOfMonth - weekStartsAtDayIndex)
+                    : (weekdays.length - weekStartsAtDayIndex + weekDayOfFirstDayOfMonth);
+
+        if (space == weekdays.length)
+            space = 0;
+
+        int columnIndexCounter = 0;
+
+        for (int i = 0; i < space; i++)
+        {
+            if (columnIndexCounter == 0)
+            {
+                writer.startElement(HTML.TR_ELEM, inputComponent);
+            }
+
+            writeCell(facesContext, writer, inputComponent, "",
+                      null, inputComponent.getDayCellClass());
+            columnIndexCounter++;
+        }
+
+        for (int i = 0; i < lastDayInMonth; i++)
+        {
+            if (columnIndexCounter == 0)
+            {
+                writer.startElement(HTML.TR_ELEM, inputComponent);
+            }
+
+            cal = copyCalendar(facesContext, timeKeeper);
+            cal.set(Calendar.DAY_OF_MONTH, i + 1);
+
+            String cellStyle = inputComponent.getDayCellClass();
+
+            if((currentDay - 1) == i)
+                cellStyle = inputComponent.getCurrentDayCellClass();
+
+            writeCell(facesContext, writer,
+                      inputComponent, String.valueOf(i + 1), cal.getTime(),
+                      cellStyle);
+
+            columnIndexCounter++;
+
+            if (columnIndexCounter == weekdays.length)
+            {
+                writer.endElement(HTML.TR_ELEM);
+                HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+                columnIndexCounter = 0;
+            }
+        }
+
+        if (columnIndexCounter != 0)
+        {
+            for (int i = columnIndexCounter; i < weekdays.length; i++)
+            {
+                writeCell(facesContext, writer,
+                          inputComponent, "", null, inputComponent.getDayCellClass());
+            }
+
+            writer.endElement(HTML.TR_ELEM);
+            HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+        }
+    }
+
+    /**
+     * Generate components and output for a single "day" cell within the calendar display.
+     */
+    private void writeCell(FacesContext facesContext,
+                           ResponseWriter writer, UIInput component, String content,
+                           Date valueForLink, String styleClass)
+            throws IOException
+    {
+        writer.startElement(HTML.TD_ELEM, component);
+
+        if (styleClass != null)
+            writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
+
+        if (valueForLink == null)
+            writer.writeText(content, JSFAttr.VALUE_ATTR);
+        else
+        {
+            writeLink(content, component, facesContext, valueForLink);
+        }
+
+        writer.endElement(HTML.TD_ELEM);
+    }
+
+    /**
+     * Create child components to represent a link to a specific date value, and render them.
+     * <p>
+     * For a disabled calendar, this just creates a Text component, attaches it as a child
+     * of the calendar and renders it. The value of the component is the string returned by
+     * valueForLink.getTime().
+     * <p>
+     * For a non-disabled calendar, create an HtmlCommandLink child that wraps the text
+     * returned by valueForLink.getTime(), and add it to the component.
+     */
+    private void writeLink(String content,
+                           UIInput component,
+                           FacesContext facesContext,
+                           Date valueForLink)
+            throws IOException
+    {
+        Converter converter = getConverter(component);
+        Application application = facesContext.getApplication();
+
+        HtmlOutputText text
+                = (HtmlOutputText)application.createComponent(HtmlOutputText.COMPONENT_TYPE);
+        text.setValue(content);
+        text.setId(component.getId() + "_" + valueForLink.getTime() + "_text");
+        text.setTransient(true);
+
+        HtmlInputCalendar calendar = (HtmlInputCalendar)component;
+        if (isDisabled(facesContext, component) || calendar.isReadonly())
+        {
+            component.getChildren().add(text);
+
+            RendererUtils.renderChild(facesContext, text);
+            return;
+        }
+
+        HtmlCommandLink link
+                = (HtmlCommandLink)application.createComponent(HtmlCommandLink.COMPONENT_TYPE);
+        link.setId(component.getId() + "_" + valueForLink.getTime() + "_link");
+        link.setTransient(true);
+        link.setImmediate(component.isImmediate());
+
+        UIParameter parameter
+                = (UIParameter)application.createComponent(UIParameter.COMPONENT_TYPE);
+        parameter.setId(component.getId() + "_" + valueForLink.getTime() + "_param");
+        parameter.setTransient(true);
+        parameter.setName(component.getClientId(facesContext));
+        parameter.setValue(converter.getAsString(facesContext, component, valueForLink));
+
+        RendererUtils.addOrReplaceChild(component,link);
+        link.getChildren().add(parameter);
+        link.getChildren().add(text);
+
+        RendererUtils.renderChild(facesContext, link);
+    }
+
+    private Converter getConverter(UIInput component)
+    {
+        Converter converter = component.getConverter();
+
+        if (converter == null)
+        {
+            converter = new CalendarDateTimeConverter();
+        }
+        return converter;
+    }
+
+    private int mapCalendarDayToCommonDay(int day)
+    {
+        switch (day)
+        {
+            case Calendar.TUESDAY:
+                return 1;
+            case Calendar.WEDNESDAY:
+                return 2;
+            case Calendar.THURSDAY:
+                return 3;
+            case Calendar.FRIDAY:
+                return 4;
+            case Calendar.SATURDAY:
+                return 5;
+            case Calendar.SUNDAY:
+                return 6;
+            default:
+                return 0;
+        }
+    }
+
+    private static String[] mapShortWeekdays(DateFormatSymbols symbols)
+    {
+        String[] weekdays = new String[7];
+
+        String[] localeWeekdays = symbols.getShortWeekdays();
+
+        weekdays[0] = localeWeekdays[Calendar.MONDAY];
+        weekdays[1] = localeWeekdays[Calendar.TUESDAY];
+        weekdays[2] = localeWeekdays[Calendar.WEDNESDAY];
+        weekdays[3] = localeWeekdays[Calendar.THURSDAY];
+        weekdays[4] = localeWeekdays[Calendar.FRIDAY];
+        weekdays[5] = localeWeekdays[Calendar.SATURDAY];
+        weekdays[6] = localeWeekdays[Calendar.SUNDAY];
+
+        return weekdays;
+    }
+
+    private static String[] mapShortWeekdaysStartingWithSunday(DateFormatSymbols symbols)
+    {
+        String[] weekdays = new String[7];
+
+        String[] localeWeekdays = symbols.getShortWeekdays();
+
+        weekdays[0] = localeWeekdays[Calendar.SUNDAY];
+        weekdays[1] = localeWeekdays[Calendar.MONDAY];
+        weekdays[2] = localeWeekdays[Calendar.TUESDAY];
+        weekdays[3] = localeWeekdays[Calendar.WEDNESDAY];
+        weekdays[4] = localeWeekdays[Calendar.THURSDAY];
+        weekdays[5] = localeWeekdays[Calendar.FRIDAY];
+        weekdays[6] = localeWeekdays[Calendar.SATURDAY];
+
+        return weekdays;
+    }
+
+    
+    private static String[] mapShortWeekdaysStartingWithSaturday(DateFormatSymbols symbols) 
+    {
+        String[] weekdays = new String[7];
+
+        String[] localeWeekdays = symbols.getShortWeekdays();
+
+        weekdays[0] = localeWeekdays[Calendar.SATURDAY];
+        weekdays[1] = localeWeekdays[Calendar.SUNDAY];
+        weekdays[2] = localeWeekdays[Calendar.MONDAY];
+        weekdays[3] = localeWeekdays[Calendar.TUESDAY];
+        weekdays[4] = localeWeekdays[Calendar.WEDNESDAY];
+        weekdays[5] = localeWeekdays[Calendar.THURSDAY];
+        weekdays[6] = localeWeekdays[Calendar.FRIDAY];
+
+        return weekdays;
+    }    
+    
+    private static String[] mapWeekdaysStartingWithSunday(DateFormatSymbols symbols)
+    {
+        String[] weekdays = new String[7];
+
+        String[] localeWeekdays = symbols.getWeekdays();
+
+        weekdays[0] = localeWeekdays[Calendar.SUNDAY];
+        weekdays[1] = localeWeekdays[Calendar.MONDAY];
+        weekdays[2] = localeWeekdays[Calendar.TUESDAY];
+        weekdays[3] = localeWeekdays[Calendar.WEDNESDAY];
+        weekdays[4] = localeWeekdays[Calendar.THURSDAY];
+        weekdays[5] = localeWeekdays[Calendar.FRIDAY];
+        weekdays[6] = localeWeekdays[Calendar.SATURDAY];
+
+        return weekdays;
+    }
+
+    public static String[] mapMonths(DateFormatSymbols symbols)
+    {
+        String[] months = new String[12];
+
+        String[] localeMonths = symbols.getMonths();
+
+        months[0] = localeMonths[Calendar.JANUARY];
+        months[1] = localeMonths[Calendar.FEBRUARY];
+        months[2] = localeMonths[Calendar.MARCH];
+        months[3] = localeMonths[Calendar.APRIL];
+        months[4] = localeMonths[Calendar.MAY];
+        months[5] = localeMonths[Calendar.JUNE];
+        months[6] = localeMonths[Calendar.JULY];
+        months[7] = localeMonths[Calendar.AUGUST];
+        months[8] = localeMonths[Calendar.SEPTEMBER];
+        months[9] = localeMonths[Calendar.OCTOBER];
+        months[10] = localeMonths[Calendar.NOVEMBER];
+        months[11] = localeMonths[Calendar.DECEMBER];
+
+        return months;
+    }
+
+    public static String[] mapShortMonths(DateFormatSymbols symbols)
+    {
+        String[] months = new String[12];
+
+        String[] localeMonths = symbols.getShortMonths();
+
+        months[0] = localeMonths[Calendar.JANUARY];
+        months[1] = localeMonths[Calendar.FEBRUARY];
+        months[2] = localeMonths[Calendar.MARCH];
+        months[3] = localeMonths[Calendar.APRIL];
+        months[4] = localeMonths[Calendar.MAY];
+        months[5] = localeMonths[Calendar.JUNE];
+        months[6] = localeMonths[Calendar.JULY];
+        months[7] = localeMonths[Calendar.AUGUST];
+        months[8] = localeMonths[Calendar.SEPTEMBER];
+        months[9] = localeMonths[Calendar.OCTOBER];
+        months[10] = localeMonths[Calendar.NOVEMBER];
+        months[11] = localeMonths[Calendar.DECEMBER];
+
+        return months;
+    }
+
+
+    public void decode(FacesContext facesContext, UIComponent component)
+    {
+        if(HtmlRendererUtils.isDisabledOrReadOnly(component))
+        {
+            // nothing to do here
+            return;
+        }
+
+        RendererUtils.checkParamValidity(facesContext, component, HtmlInputCalendar.class);
+
+        String helperString = getHelperString(component);
+
+        if (!(component instanceof EditableValueHolder)) {
+            throw new IllegalArgumentException("Component "
+                                               + component.getClientId(facesContext)
+                                               + " is not an EditableValueHolder");
+        }
+        Map paramMap = facesContext.getExternalContext()
+                .getRequestParameterMap();
+        String clientId = component.getClientId(facesContext);
+
+        if(paramMap.containsKey(clientId))
+        {
+            String value = (String) paramMap.get(clientId);
+
+            if(!value.equalsIgnoreCase(helperString))
+            {
+                ((EditableValueHolder) component).setSubmittedValue(value);
+            }
+            else
+            {
+                // The field was initially filled with the "helper string", and has
+                // not been altered by the user so treat this as if null had been
+                // passed by the user.
+                //
+                // TODO: does this mean the target date is set to todays date?
+                // And how does this affect the "required" property?
+                ((EditableValueHolder) component).setSubmittedValue("");
+            }
+        }
+        else
+        {
+            log.warn(HtmlRendererUtils.NON_SUBMITTED_VALUE_WARNING +
+                " Component : "+
+                RendererUtils.getPathToComponent(component));
+        }
+
+    }
+    
+    protected static boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
+    {
+        if (!UserRoleUtils.isEnabledOnUserRole(uiComponent))
+        {
+            return true;
+        }
+        else
+        {
+            if (uiComponent instanceof HtmlInputCalendar)
+            {
+                return ((HtmlInputCalendar)uiComponent).isDisabled();
+            }
+            else
+            {
+                return org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils.getBooleanAttribute(uiComponent, HTML.DISABLED_ATTR, false);
+            }
+        }
+    }
+
+    public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue) throws ConverterException
+    {
+        RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputCalendar.class);
+
+        UIInput uiInput = (UIInput) uiComponent;
+
+        Converter converter = uiInput.getConverter();
+
+        if(converter==null)
+        {
+            converter = new CalendarDateTimeConverter();
+        }
+
+        if (submittedValue != null && !(submittedValue instanceof String))
+        {
+            throw new IllegalArgumentException("Submitted value of type String expected");
+        }
+
+        return converter.getAsObject(facesContext, uiComponent, (String) submittedValue);
+    }
+
+    public interface DateConverter extends Converter
+    {
+        public Date getAsDate(FacesContext facesContext, UIComponent uiComponent);
+    }
+
+    private static String getHelperString(UIComponent uiComponent)
+    {
+        return uiComponent instanceof HtmlInputCalendar?((HtmlInputCalendar) uiComponent).getHelpText():null;
+    }
+
+    public static class CalendarDateTimeConverter implements DateConverter
+    {
+        private static final String CONVERSION_MESSAGE_ID = "org.apache.myfaces.calendar.CONVERSION";
+
+        public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s)
+        {
+            if(s==null || s.trim().length()==0 || s.equals(getHelperString(uiComponent)))
+                return null;
+
+            if(uiComponent instanceof HtmlInputCalendar && ((HtmlInputCalendar) uiComponent).isRenderAsPopup())
+            {
+                HtmlInputCalendar calendar = (HtmlInputCalendar) uiComponent;
+                String popupDateFormat = calendar.getPopupDateFormat();
+                String formatStr = createJSPopupFormat(facesContext, popupDateFormat);
+                Locale locale = facesContext.getViewRoot().getLocale();
+                Calendar timeKeeper = Calendar.getInstance(locale);
+                int firstDayOfWeek = timeKeeper.getFirstDayOfWeek() - 1;
+                org.apache.myfaces.dateformat.DateFormatSymbols symbols = new org.apache.myfaces.dateformat.DateFormatSymbols(locale);
+                SimpleDateFormatter dateFormat = new SimpleDateFormatter(formatStr, symbols, firstDayOfWeek);
+                
+                Date date = dateFormat.parse(s); 
+                if (date != null) {
+                    return date;
+                }
+                FacesMessage msg = MessageUtils.getMessage(FacesMessage.SEVERITY_ERROR,CONVERSION_MESSAGE_ID,new Object[]{
+                        uiComponent.getId(),s});
+                throw new ConverterException(msg);
+            }
+            else
+            {
+                DateFormat dateFormat = createStandardDateFormat(facesContext);
+                dateFormat.setLenient(false);
+                try
+                {
+                    Date date = dateFormat.parse(s); 
+                    return date;
+                }
+                catch (ParseException e)
+                {
+                    FacesMessage msg = MessageUtils.getMessage(FacesMessage.SEVERITY_ERROR,CONVERSION_MESSAGE_ID,new Object[]{
+                            uiComponent.getId(),s});
+                    throw new ConverterException(msg,e);
+                }
+            }
+        }
+
+        public Date getAsDate(FacesContext facesContext, UIComponent uiComponent)
+        {
+            return RendererUtils.getDateValue(uiComponent);
+        }
+
+        public static String createJSPopupFormat(FacesContext facesContext, String popupDateFormat)
+        {
+
+            if(popupDateFormat == null)
+            {
+                SimpleDateFormat defaultDateFormat = createStandardDateFormat(facesContext);
+                popupDateFormat = defaultDateFormat.toPattern();
+            }
+
+            return popupDateFormat;
+        }
+
+        public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o)
+        {
+            Date date = (Date) o;
+
+            if(date==null)
+                return getHelperString(uiComponent);
+
+            if(uiComponent instanceof HtmlInputCalendar && ((HtmlInputCalendar) uiComponent).isRenderAsPopup())
+            {
+                HtmlInputCalendar calendar = (HtmlInputCalendar) uiComponent;
+                String popupDateFormat = calendar.getPopupDateFormat();
+                String formatStr = createJSPopupFormat(facesContext, popupDateFormat);
+                Locale locale = facesContext.getViewRoot().getLocale();
+                Calendar timeKeeper = Calendar.getInstance(locale);
+                int firstDayOfWeek = timeKeeper.getFirstDayOfWeek() - 1;
+                org.apache.myfaces.dateformat.DateFormatSymbols symbols = new org.apache.myfaces.dateformat.DateFormatSymbols(locale);
+
+                SimpleDateFormatter dateFormat = new SimpleDateFormatter(formatStr, symbols, firstDayOfWeek);
+                return dateFormat.format(date);
+            }
+            else
+            {
+                DateFormat dateFormat = createStandardDateFormat(facesContext);
+                dateFormat.setLenient(false);
+                return dateFormat.format(date);
+            }
+        }
+
+        private static SimpleDateFormat createStandardDateFormat(FacesContext facesContext)
+        {
+            DateFormat dateFormat;
+            dateFormat = DateFormat.getDateInstance(DateFormat.SHORT,
+                                                    facesContext.getViewRoot().getLocale());
+
+            if(dateFormat instanceof SimpleDateFormat)
+                return (SimpleDateFormat) dateFormat;
+            else
+                return new SimpleDateFormat("dd.MM.yyyy", facesContext.getViewRoot().getLocale());
+        }
+    }
+}

Modified: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputHtml/InputHtml.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputHtml/InputHtml.java?rev=928556&r1=928555&r2=928556&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputHtml/InputHtml.java (original)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputHtml/InputHtml.java Mon Mar 29 01:18:21 2010
@@ -18,14 +18,12 @@
  */
 package org.apache.myfaces.custom.inputHtml;
 
+import javax.faces.context.FacesContext;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.component.html.ext.HtmlInputText;
 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
-import org.apache.myfaces.shared_tomahawk.util._ComponentUtils;
-
-import javax.faces.context.FacesContext;
-import javax.faces.el.ValueBinding;
 
 /**
  * HTML Editor using the kupu library.
@@ -55,79 +53,10 @@ public class InputHtml extends HtmlInput
 
     private static final Log log = LogFactory.getLog(HtmlInputText.class);
 
-    private String _fallback;
-    private String _type;
-
-    private Boolean _allowEditSource;
-    private Boolean _allowExternalLinks;
-    private Boolean _addKupuLogo;
-
-    private Boolean _showAllToolBoxes;
-    private Boolean _showPropertiesToolBox;
-    private Boolean _showLinksToolBox;
-    private Boolean _showImagesToolBox;
-    private Boolean _showTablesToolBox;
-    private Boolean _showCleanupExpressionsToolBox;
-    private Boolean _showDebugToolBox;
-
     public InputHtml() {
         setRendererType(DEFAULT_RENDERER_TYPE);
     }
 
-    public Object saveState(FacesContext context) {
-        Object values[] = new Object[4];
-        values[0] = super.saveState(context);
-
-        String[] types = new String[2];
-        types[0] = _fallback;
-        types[1] = _type;
-
-        values[1] = types;
-
-        Boolean toolBarButtons[] = new Boolean[3];
-        toolBarButtons[0] = _allowEditSource;
-        toolBarButtons[1] = _allowExternalLinks;
-        toolBarButtons[2] = _addKupuLogo;
-
-        values[2] = toolBarButtons;
-
-        Boolean toolBoxes[] = new Boolean[7];
-        toolBoxes[0] = _showAllToolBoxes;
-        toolBoxes[1] = _showPropertiesToolBox;
-        toolBoxes[2] = _showLinksToolBox;
-        toolBoxes[3] = _showImagesToolBox;
-        toolBoxes[4] = _showTablesToolBox;
-        toolBoxes[5] = _showCleanupExpressionsToolBox;
-        toolBoxes[6] = _showDebugToolBox;
-
-        values[3] = toolBoxes;
-
-        return values;
-    }
-
-    public void restoreState(FacesContext context, Object state) {
-        Object values[] = (Object[]) state;
-        super.restoreState(context, values[0]);
-
-        String[] types = (String[]) values[1];
-        _fallback = types[0];
-        _type = types[1];
-
-        Boolean[] toolBarButtons = (Boolean[]) values[2];
-        _allowEditSource = toolBarButtons[0];
-        _allowExternalLinks = toolBarButtons[1];
-        _addKupuLogo = toolBarButtons[2];
-
-        Boolean[] toolBoxes = (Boolean[]) values[3];
-        _showAllToolBoxes = toolBoxes[0];
-        _showPropertiesToolBox = toolBoxes[1];
-        _showLinksToolBox = toolBoxes[2];
-        _showImagesToolBox = toolBoxes[3];
-        _showTablesToolBox = toolBoxes[4];
-        _showCleanupExpressionsToolBox = toolBoxes[5];
-        _showDebugToolBox = toolBoxes[6];
-    }
-
     /**
      * Use a text area instead of the javascript HTML editor. 
      * 
@@ -136,13 +65,10 @@ public class InputHtml extends HtmlInput
      * @JSFProperty
      */
     public String getFallback(){
-        if (_fallback != null)
-            return _fallback;
-        ValueBinding vb = getValueBinding("fallback");
-        return vb != null ? vb.getValue(getFacesContext()).toString() : "false";
+        return (String) getStateHelper().eval(PropertyKeys.fallback, "false");
     }
     public void setFallback(String _fallback){
-        this._fallback = _fallback;
+        getStateHelper().put(PropertyKeys.fallback, _fallback);
     }
 
     /**
@@ -153,13 +79,10 @@ public class InputHtml extends HtmlInput
      * @JSFProperty
      */
     public String getType(){
-        if (_type != null)
-            return _type;
-        ValueBinding vb = getValueBinding("type");
-        return vb != null ? _ComponentUtils.getStringValue(getFacesContext(), vb) : "fragment";
+        return (String) getStateHelper().eval(PropertyKeys.type, "fragment");
     }
     public void setType(String _type){
-        this._type = _type;
+        getStateHelper().put(PropertyKeys.type, _type);
     }
     public boolean isTypeDocument(){
         return getType().equals("document");
@@ -171,13 +94,10 @@ public class InputHtml extends HtmlInput
      * @JSFProperty
      */
     public boolean isAllowEditSource(){
-           if (_allowEditSource != null)
-               return _allowEditSource.booleanValue();
-           ValueBinding vb = getValueBinding("allowEditSource");
-           return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : true;
+        return (Boolean) getStateHelper().eval(PropertyKeys.allowEditSource, Boolean.TRUE);
     }
     public void setAllowEditSource(boolean allowEditSource){
-        this._allowEditSource = Boolean.valueOf(allowEditSource);
+        getStateHelper().put(PropertyKeys.allowEditSource, allowEditSource);
     }
 
     /**
@@ -186,13 +106,10 @@ public class InputHtml extends HtmlInput
      * @JSFProperty
      */
     public boolean isAllowExternalLinks(){
-        if (_allowExternalLinks != null)
-            return _allowExternalLinks.booleanValue();
-        ValueBinding vb = getValueBinding("allowExternalLinks");
-        return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : true;
+        return (Boolean) getStateHelper().eval(PropertyKeys.allowExternalLinks, Boolean.TRUE);
     }
     public void setAllowExternalLinks(boolean allowExternalLinks){
-        this._allowExternalLinks = Boolean.valueOf(allowExternalLinks);
+        getStateHelper().put(PropertyKeys.allowExternalLinks, allowExternalLinks);
     }
 
     /**
@@ -201,13 +118,10 @@ public class InputHtml extends HtmlInput
      * @JSFProperty
      */
     public boolean isAddKupuLogo(){
-           if (_addKupuLogo != null)
-               return _addKupuLogo.booleanValue();
-           ValueBinding vb = getValueBinding("addKupuLogo");
-           return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : true;
+        return (Boolean) getStateHelper().eval(PropertyKeys.addKupuLogo, Boolean.TRUE);
     }
     public void setAddKupuLogo(boolean addKupuLogo){
-        this._addKupuLogo = Boolean.valueOf(addKupuLogo);
+        getStateHelper().put(PropertyKeys.addKupuLogo, addKupuLogo);
     }
 
     /**
@@ -216,13 +130,10 @@ public class InputHtml extends HtmlInput
      * @JSFProperty
      */
     public boolean isShowAllToolBoxes(){
-           if (_showAllToolBoxes != null)
-               return _showAllToolBoxes.booleanValue();
-        ValueBinding vb = getValueBinding("showAllToolBoxes");
-        return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : false;
+        return (Boolean) getStateHelper().eval(PropertyKeys.showAllToolBoxes, Boolean.FALSE);
     }
     public void setShowAllToolBoxes(boolean showAllToolBoxes){
-        this._showAllToolBoxes = Boolean.valueOf(showAllToolBoxes);
+        getStateHelper().put(PropertyKeys.showAllToolBoxes, showAllToolBoxes);
     }
 
     /**
@@ -234,14 +145,11 @@ public class InputHtml extends HtmlInput
         if( isShowAllToolBoxes() )
             return true;
 
-           if (_showPropertiesToolBox != null)
-               return _showPropertiesToolBox.booleanValue();
-        ValueBinding vb = getValueBinding("showPropertiesToolBox");
-        return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : false;
+        return (Boolean) getStateHelper().eval(PropertyKeys.showPropertiesToolBox, Boolean.FALSE);
     }
 
     public void setShowPropertiesToolBox(boolean showPropertiesToolBox){
-        this._showPropertiesToolBox = Boolean.valueOf(showPropertiesToolBox);
+        getStateHelper().put(PropertyKeys.showPropertiesToolBox, showPropertiesToolBox);
     }
 
     /**
@@ -253,14 +161,11 @@ public class InputHtml extends HtmlInput
         if( isShowAllToolBoxes() )
             return true;
 
-           if (_showLinksToolBox != null)
-               return _showLinksToolBox.booleanValue();
-        ValueBinding vb = getValueBinding("showLinksToolBox");
-        return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : false;
+        return (Boolean) getStateHelper().eval(PropertyKeys.showLinksToolBox, Boolean.FALSE);
     }
     
     public void setShowLinksToolBox(boolean showLinksToolBox){
-        this._showLinksToolBox = Boolean.valueOf(showLinksToolBox);
+        getStateHelper().put(PropertyKeys.showLinksToolBox, showLinksToolBox);
     }
 
     /**
@@ -272,13 +177,10 @@ public class InputHtml extends HtmlInput
         if( isShowAllToolBoxes() )
             return true;
 
-           if (_showImagesToolBox != null)
-               return _showImagesToolBox.booleanValue();
-        ValueBinding vb = getValueBinding("showImagesToolBox");
-        return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : false;
+        return (Boolean) getStateHelper().eval(PropertyKeys.showImagesToolBox, Boolean.FALSE);
     }
     public void setShowImagesToolBox(boolean showImagesToolBox){
-        this._showImagesToolBox = Boolean.valueOf(showImagesToolBox);
+        getStateHelper().put(PropertyKeys.showImagesToolBox, showImagesToolBox);
     }
 
     /**
@@ -290,13 +192,10 @@ public class InputHtml extends HtmlInput
         if( isShowAllToolBoxes() )
             return true;
 
-           if (_showTablesToolBox != null)
-               return _showTablesToolBox.booleanValue();
-        ValueBinding vb = getValueBinding("showTablesToolBox");
-        return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : false;
+        return (Boolean) getStateHelper().eval(PropertyKeys.showTablesToolBox, Boolean.FALSE);
     }
     public void setShowTablesToolBox(boolean showTablesToolBox){
-        this._showTablesToolBox = Boolean.valueOf(showTablesToolBox);
+        getStateHelper().put(PropertyKeys.showTablesToolBox, showTablesToolBox);
     }
 
     /**
@@ -308,13 +207,10 @@ public class InputHtml extends HtmlInput
         if( isShowAllToolBoxes() )
             return true;
 
-           if (_showCleanupExpressionsToolBox != null)
-               return _showCleanupExpressionsToolBox.booleanValue();
-        ValueBinding vb = getValueBinding("showCleanupExpressionsToolBox");
-        return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : false;
+        return (Boolean) getStateHelper().eval(PropertyKeys.showCleanupExpressionsToolBox, Boolean.FALSE);
     }
     public void setShowCleanupExpressionsToolBox(boolean showCleanupExpressionsToolBox){
-        this._showCleanupExpressionsToolBox = Boolean.valueOf(showCleanupExpressionsToolBox);
+        getStateHelper().put(PropertyKeys.showCleanupExpressionsToolBox, showCleanupExpressionsToolBox);
     }
 
     /**
@@ -326,13 +222,10 @@ public class InputHtml extends HtmlInput
         if( isShowAllToolBoxes() )
             return true;
 
-           if (_showDebugToolBox != null)
-               return _showDebugToolBox.booleanValue();
-        ValueBinding vb = getValueBinding("showDebugToolBox");
-        return vb != null ? ((Boolean)vb.getValue(getFacesContext())).booleanValue() : false;
+        return (Boolean) getStateHelper().eval(PropertyKeys.showDebugToolBox, Boolean.FALSE);
     }
-    public void setShowDebugToolBox(boolean showTablesToolBox){
-        this._showDebugToolBox = Boolean.valueOf(showTablesToolBox);
+    public void setShowDebugToolBox(boolean showTablesToolBox){        
+        getStateHelper().put(PropertyKeys.showDebugToolBox, showTablesToolBox);
     }
 
     public boolean isShowAnyToolBox(){
@@ -429,4 +322,21 @@ public class InputHtml extends HtmlInput
 
         return html.substring(bodyStartIndex, bodyEndIndex+1).trim();
     }
+    
+    protected enum PropertyKeys
+    {
+        fallback,
+        type,
+        allowEditSource,
+        allowExternalLinks,
+        addKupuLogo,
+        showAllToolBoxes,
+        showPropertiesToolBox,
+        showLinksToolBox,
+        showImagesToolBox,
+        showTablesToolBox,
+        showCleanupExpressionsToolBox,
+        showDebugToolBox,
+        
+    }
 }