Package de.iritgo.aktera.ui.form

Source Code of de.iritgo.aktera.ui.form.FormTools

/**
* This file is part of the Iritgo/Aktera Framework.
*
* Copyright (C) 2005-2011 Iritgo Technologies.
* Copyright (C) 2003-2005 BueroByte GbR.
*
* Iritgo 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 de.iritgo.aktera.ui.form;


import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.sql.Date;
import java.text.*;
import java.util.*;
import java.util.regex.*;
import org.apache.avalon.framework.logger.Logger;
import org.apache.commons.beanutils.*;
import de.iritgo.aktera.configuration.SystemConfigManager;
import de.iritgo.aktera.configuration.preferences.Preferences;
import de.iritgo.aktera.hibernate.StandardDao;
import de.iritgo.aktera.model.*;
import de.iritgo.aktera.persist.*;
import de.iritgo.aktera.spring.SpringTools;
import de.iritgo.aktera.tools.ModelTools;
import de.iritgo.aktera.ui.UIRequest;
import de.iritgo.aktera.ui.el.ExpressionLanguageContext;
import de.iritgo.aktera.ui.ng.ModelRequestWrapper;
import de.iritgo.aktera.ui.tools.UserTools;
import de.iritgo.simplelife.math.NumberTools;
import de.iritgo.simplelife.string.StringTools;


/**
* Utility class that helps to create input elements for persistent objects.
*/
public class FormTools
{
  /** Regular expression for validating numbers. */
  private static Pattern reNumber;

  /** Regular expression for validating integers. */
  private static Pattern reInteger;

  /** Regular expression for validating digits. */
  private static Pattern reDigits;

  /** Regular expression for validating real numbers. */
  private static Pattern reRealNumber;

  /** Regular expression for validating ip addresses. */
  private static Pattern reIpAddress;

  /** Regular expression for validating host names. */
  private static Pattern reHostname;

  /** Regular expression for validating no whitespace text. */
  private static Pattern reNoWhiteSpace;

  /**
   * Regular expression for validating no whitespace and special character
   * text.
   */
  private static Pattern reIdentifier;

  /** Regular expression for validating email addresses. */
  private static Pattern reEmail;

  /** DateFormat used to format time property values. */
  private static DateFormat formatPropertyTime = new SimpleDateFormat("HH:mm:00");

  static
  {
    try
    {
      reNumber = Pattern.compile("[0-9]*");
      reInteger = Pattern.compile("([-+])?[0-9]*");
      reDigits = Pattern.compile("[0-9]*");
      reIpAddress = Pattern
              .compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
      // reIpAddress =
      // Pattern.compile("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(/\\d\\d)?");
      reHostname = Pattern.compile("^(([\\w][\\w\\-\\.]*)\\.)?([\\w][\\w\\-]+)(\\.([\\w][\\w\\.]*))?$");
      reNoWhiteSpace = Pattern.compile("[^ ]+");
      reIdentifier = Pattern.compile("\\w+");
      reRealNumber = Pattern.compile("[0-9]+(\\.[0-9]+)?");
      reEmail = Pattern.compile("[\\w\\.-]+((@){1}?[\\w\\.-]+)?");
    }
    catch (PatternSyntaxException x)
    {
      System.out.println("FormTools: " + x);
    }
  }

  /**
   * Create the key under which the persistents are stored in the user
   * context.
   *
   * @param contextId The context id.
   * @param id The object id.
   * @return The context key.
   */
  public static String createContextKey(String contextId, Object id)
  {
    return "aktera.formular:" + contextId + ":" + id;
  }

  /**
   * Retrieve the request id of the formular persistents.
   *
   * @param req A model request.
   * @param keyName Alternate id name.
   * @return The persistent id.
   */
  public static Object getPersistentId(ModelRequest req, String formName, String keyName)
  {
    if (req.getParameter("new") == null)
    {
      String kname = "";

      if (keyName != null)
      {
        kname = keyName;
      }
      else if (req.getParameter("prevId") != null)
      {
        kname = "prevId";
      }
      else
      {
        kname = "id";
      }

      if (req.getParameter(kname) instanceof String[])
      {
        Object id = ((String[]) req.getParameter(kname))[0];

        return id != null ? id : new Integer(- 1);
      }
      else
      {
        Object id = req.getParameter(kname);

        return id != null ? id : new Integer(- 1);
      }
    }

    return new Integer(- 1);
  }

  /**
   * Retrieve a formular descriptor that is stored in the user context.
   *
   * @param req A model request.
   * @param formName The name of the formular.
   * @param id The persistents id.
   * @return The formular.
   */
  public static FormularDescriptor getFormularFromContext(ModelRequest req, String formName, Object id)
  {
    String formId = createContextKey(formName, id);
    FormularDescriptor formular = (FormularDescriptor) UserTools.getContextObject(req, formId);

    return formular;
  }

  /**
   * Retrieve a formular descriptor that is stored in the user context.
   *
   * @param req A model request.
   * @param formName The name of the formular.
   * @param id The persistents id.
   * @return The formular.
   */
  public static FormularDescriptor getFormularFromContext(UIRequest request, String formName, Object id)
  {
    String formId = createContextKey(formName, id);
    FormularDescriptor formular = (FormularDescriptor) UserTools.getContextObject(new ModelRequestWrapper(request),
            formId);

    return formular;
  }

  /**
   * Retrieve a formular descriptor that is stored in the user context.
   *
   * @param req A model request.
   * @param formName The name of the formular.
   * @param keyName Alternate id name.
   * @return The formular.
   */
  public static FormularDescriptor getFormularFromContext(ModelRequest req, String formName, String keyName)
  {
    String formId = createContextKey(formName, getPersistentId(req, formName, keyName));

    return (FormularDescriptor) UserTools.getContextObject(req, formId);
  }

  /**
   * Create all input and output elements for the given formular.
   *
   * @param req The model request.
   * @param res The model response.
   * @param formular The formular description.
   * @param persistents The persistent instances.
   */
  public static void createResponseElements(ModelRequest req, ModelResponse res, FormularDescriptor formular,
          PersistentDescriptor persistents, ExpressionLanguageContext context)
    throws ModelException, PersistenceException
  {
    createResponseElements(req, res, formular, persistents, null, formular.getReadOnly(), context);
  }

  /**
   * Create all input and output elements for the given formular.
   *
   * @param req The model request.
   * @param res The model response.
   * @param formular The formular description.
   * @param persistents The persistent instances.
   * @param commands The formular commands.
   */
  public static void createResponseElements(ModelRequest req, ModelResponse res, FormularDescriptor formular,
          PersistentDescriptor persistents, CommandDescriptor commands, ExpressionLanguageContext context)
    throws ModelException, PersistenceException
  {
    createResponseElements(req, res, formular, persistents, commands, formular.getReadOnly(), context);
  }

  /**
   * Create all input and output elements for the given formular.
   *
   * @param req The model request.
   * @param res The model response.
   * @param formular The formular description.
   * @param persistents The persistent instances.
   * @param commands The formular commands.
   * @param readOnly If true, all fields are created as read only fields.
   */
  public static void createResponseElements(ModelRequest req, ModelResponse res, FormularDescriptor formular,
          PersistentDescriptor persistents, CommandDescriptor commands, boolean readOnly,
          ExpressionLanguageContext context) throws ModelException, PersistenceException
  {
    Output labelWidth = res.createOutput("labelWidth");

    labelWidth.setContent(new Integer(formular.getLabelWidth()));
    res.add(labelWidth);

    if (formular.getTitle() != null)
    {
      Output title = res.createOutput("title");

      title.setContent(formular.getTitle());
      title.setAttribute("bundle", formular.getTitleBundle());
      res.add(title);
    }

    if (formular.getIcon() != null)
    {
      Output icon = res.createOutput("icon");

      icon.setContent(formular.getIcon());
      res.add(icon);
    }

    if (! formular.hasVisibleButtons())
    {
      Output out = res.createOutput("hideButtonBar", "Y");

      res.add(out);
    }

    String idName = formular.getIdField();

    if (idName != null)
    {
      if (idName.contains("."))
      {
        String idFieldName = idName.substring(idName.indexOf('.') + 1);
        String idPersistentName = idName.substring(0, Math.max(idName.indexOf('.'), 0));
        Object idPersistent = persistents.get(idPersistentName);
        Input inId = res.createInput("id");

        inId.setDefaultValue(getAttributeFromDataObject(idPersistent, idFieldName));
        res.add(inId);
      }
      else
      {
        Input inId = res.createInput("id");

        inId.setDefaultValue(persistents.getAttribute(idName));
        res.add(inId);
      }
    }

    Output groupList = res.createOutput("groups");

    if (readOnly)
    {
      groupList.setAttribute("readOnly", Boolean.TRUE);
    }

    res.add(groupList);

    int currentPage = Math.max(Math.min(formular.getPage(), formular.getPageCount() - 1), 0);

    Output outCurrentPage = res.createOutput("currentPage");
    outCurrentPage.setContent(currentPage);
    res.add(outCurrentPage);

    Output pageList = null;

    Iterator iGroups = formular.groupIterator();

    if (formular.hasPages())
    {
      pageList = res.createOutput("pages");
      res.add(pageList);

      int pageNum = 0;

      for (Iterator i = formular.pageIterator(); i.hasNext(); ++pageNum)
      {
        PageDescriptor page = (PageDescriptor) i.next();

        Command command = ModelTools.createPreviousModelCommand(req, res);

        command.setName(String.valueOf(pageNum));
        command.setLabel(page.getLabel());
        command.setParameter("page", String.valueOf(pageNum));
        command.setAttribute("page", String.valueOf(pageNum));
        command.setAttribute("bundle", page.getBundle());

        if (page.hasIcon())
        {
          command.setAttribute("icon", page.getIcon());

          command.setAttribute("inactiveIcon",
                  page.hasInactiveIcon() ? page.getInactiveIcon() : page.getIcon());
        }

        boolean active = pageNum == currentPage;

        if (active)
        {
          command.setAttribute("active", "Y");
        }

        if (pageNum == 0)
        {
          command.setAttribute("style", active ? "af" : "f");
        }
        else
        {
          if (i.hasNext())
          {
            command.setAttribute("style", active ? "am" : "m");
          }
          else
          {
            command.setAttribute("style", active ? "al" : "l");
          }
        }

        pageList.add(command);
      }

      iGroups = formular.getPage(currentPage).groupIterator();
    }

    int groupNum = 0;

    for (; iGroups.hasNext(); ++groupNum)
    {
      GroupDescriptor group = (GroupDescriptor) iGroups.next();

      if (! group.isVisible())
      {
        continue;
      }

      Output outGroup = res.createOutput(String.valueOf(groupNum), group.getLabel());

      if (StringTools.isNotTrimEmpty(group.getBundle()))
      {
        outGroup.setAttribute("bundle", group.getBundle());
      }
      else
      {
        outGroup.setAttribute("bundle", formular.getBundle());
      }

      if (readOnly)
      {
        outGroup.setAttribute("readOnly", Boolean.TRUE);
      }

      if (! group.isTitleVisible())
      {
        outGroup.setAttribute("hideTitle", Boolean.TRUE);
      }

      if (! StringTools.isTrimEmpty(group.getIcon()))
      {
        outGroup.setAttribute("icon", group.getIcon());
      }

      groupList.add(outGroup);

      int num = 1;

      for (Iterator<FieldDescriptor> j = group.fieldIterator(); j.hasNext();)
      {
        FieldDescriptor field = (FieldDescriptor) j.next();

        createResponseElementsForField(req, res, field, persistents, outGroup, readOnly, num++, context);
      }
    }

    if (req.getParameter("error") != null)
    {
      res.addOutput("focus", req.getParameterAsString("error"));
    }

    if (commands != null)
    {
      for (Iterator i = commands.iterator(); i.hasNext();)
      {
        CommandInfo descriptor = (CommandInfo) i.next();

        if ("save".equals(descriptor.getName()) && readOnly)
        {
          continue;
        }
        else if ("cancel".equals(descriptor.getName()))
        {
          Command command = descriptor.createCancelCommand(req, res, context);

          res.add(command);
        }
        else
        {
          Command command = descriptor.createCommand(req, res, context);

          res.add(command);
        }
      }
    }
  }

  /**
   * Create an input element for a formular field.
   *
   * An input has the following attributes:
   *
   * <table>
   * <tr>
   * <th>Name</th>
   * <th>Type</th>
   * <th>Description</th>
   * </tr>
   * <tr>
   * <td>editor</td>
   * <td>string</td>
   * <td>Id of the field editor.</td>
   * </tr>
   * <tr>
   * <td>size</td>
   * <td>integer</td>
   * <td>Display size of the editor.</td>
   * </tr>
   * <tr>
   * <td>readOnly</td>
   * <td>flag</td>
   * <td>If set, this is a read only field.</td>
   * </tr>
   * <tr>
   * <td>duty</td>
   * <td>flag</td>
   * <td>If set, this is a duty field.</td>
   * </tr>
   * </table>
   *
   * @param req The model request.
   * @param res The model response.
   * @param persistents The persistent instances.
   * @param field The formular field descriptor.
   * @param group An optional grouping output which can be null.
   * @param readOnly If true, all fields are created as read only fields.
   * @param num The current element number.
   */
  public static void createResponseElementsForField(ModelRequest req, ModelResponse res, FieldDescriptor field,
          PersistentDescriptor persistents, Output outGroup, boolean readOnly, int num,
          ExpressionLanguageContext context) throws ModelException, PersistenceException
  {
    ValidationResult result = new ValidationResult();

    String name = field.getName();

    String fieldName = name.substring(name.indexOf('.') + 1);
    String persistentName = name.substring(0, Math.max(name.indexOf('.'), 0));
    String inputName = name.replace('.', '_').replace('(', '_').replace(')', '_');

    Object persistent = null;

    try
    {
      persistent = persistents.get(persistentName);
    }
    catch (ModelException ignored)
    {
    }

    PersistentMetaData meta = null;

    if (persistent != null && persistent instanceof Persistent)
    {
      meta = ((Persistent) persistent).getMetaData();
    }

    if (field.isHideIfNull() && persistent != null && getAttributeFromDataObject(persistent, fieldName) == null)
    {
      return;
    }

    if (field.isOmitted())
    {
      return;
    }

    Input input = res.createInput(inputName + ("list".equals(field.getEditor()) ? "List" : ""));

    input.setLabel(field.getLabel() != null ? field.getLabel() : fieldName);

    input.setAttribute("bundle", field.getBundle());
    input.setAttribute("odd", new Boolean(num % 2 == 1));
    input.setAttribute("even", new Boolean(num % 2 == 0));

    if (field.isSelectable())
    {
      input.setAttribute("selectable", "Y");
    }

    if (field.getToolTip() != null)
    {
      input.setAttribute("toolTip", field.getToolTip());
    }

    input.setAttribute("size", new Integer(field.getSize()));

    if (field.getRows() != 0)
    {
      input.setAttribute("rows", new Integer(field.getRows()));
    }

    if ("date".equals(field.getEditor()))
    {
      input.setAttribute("editor", "datecombo");
    }
    else if ("time".equals(field.getEditor()))
    {
      input.setAttribute("editor", "timecombo");
    }
    else if ("timestamp".equals(field.getEditor()))
    {
      input.setAttribute("editor", "timestampcombo");
    }
    else if (field.getEditor().startsWith("regexp:"))
    {
      input.setAttribute("editor", "text");
    }
    else
    {
      input.setAttribute("editor", field.getEditor());
    }

    if (readOnly || field.isReadOnly() || (field.isBound() && meta != null && meta.isReadOnly(fieldName)))
    {
      input.setAttribute("readOnly", "Y");
    }

    input.setAttribute("disabled", field.isDisabled());

    if (field.isDuty() && ! field.isReadOnly() && ! field.isDisabled())
    {
      input.setAttribute("duty", "Y");
    }

    if (field.hasValidationClass() && ! field.isReadOnly())
    {
      input.setAttribute("duty", "Y");
    }

    if (field.isSubmit())
    {
      input.setAttribute("submit", "Y");
    }

    input.setAttribute("nullAllowed", field.isNullAllowed());
   
    if (field.isComment())
    {
      input.setAttribute("desc", "Y");

      Preferences preferences = UserTools.getUserPreferences(req);

      if (preferences == null || preferences.getPowerUser() == null
              || ! preferences.getPowerUser().booleanValue())
      {
        if (outGroup != null)
        {
          outGroup.add(input);
        }

        res.add(input);
      }

      return;
    }

    if (field.isNoLabel())
    {
      input.setAttribute("noLabel", "Y");
    }

    if ("date".equals(field.getEditor()))
    {
      Date date = null;

      if (field.isBound())
      {
        date = (Date) getAttributeFromDataObject(persistent, fieldName);
      }
      else
      {
        date = (Date) persistents.getAttribute(inputName);
      }

      input.setDefaultValue(date);

      Input inputDay = res.createInput(inputName + "Day");

      res.add(inputDay);

      Input inputMonth = res.createInput(inputName + "Month");

      res.add(inputMonth);

      Input inputYear = res.createInput(inputName + "Year");

      res.add(inputYear);

      Calendar calendar = new GregorianCalendar();

      if (date != null)
      {
        calendar.setTime(date);
        inputDay.setDefaultValue(new Integer(calendar.get(Calendar.DAY_OF_MONTH)));
        inputMonth.setDefaultValue(new Integer(calendar.get(Calendar.MONTH) + 1));
        inputYear.setDefaultValue(new Integer(calendar.get(Calendar.YEAR)));
      }
      else
      {
        inputDay.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Day"), - 1));
        inputMonth.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Month"), - 1));
        inputYear.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Year"), - 1));
      }
    }
    else if ("time".equals(field.getEditor()))
    {
      Time time = null;

      if (field.isBound())
      {
        time = (Time) getAttributeFromDataObject(persistent, fieldName);
      }
      else
      {
        time = (Time) persistents.getAttribute(inputName);
      }

      input.setDefaultValue(time);

      Input inputHour = res.createInput(inputName + "Hour");

      res.add(inputHour);

      Input inputMinute = res.createInput(inputName + "Minute");

      res.add(inputMinute);

      Calendar calendar = new GregorianCalendar();

      if (time != null)
      {
        calendar.setTime(time);
        inputHour.setDefaultValue(new Integer(calendar.get(Calendar.HOUR_OF_DAY)));
        inputMinute.setDefaultValue(new Integer(calendar.get(Calendar.MINUTE)));
      }
      else
      {
        inputHour.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Hour"), - 1));
        inputMinute.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Minute"),
                - 1));
      }
    }
    else if ("timestamp".equals(field.getEditor()))
    {
      Timestamp timestamp = null;

      if (field.isBound())
      {
        timestamp = (Timestamp) getAttributeFromDataObject(persistent, fieldName);
      }
      else
      {
        timestamp = (Timestamp) persistents.getAttribute(fieldName);
      }

      input.setDefaultValue(timestamp);

      Input inputDay = res.createInput(inputName + "Day");

      res.add(inputDay);

      Input inputMonth = res.createInput(inputName + "Month");

      res.add(inputMonth);

      Input inputYear = res.createInput(inputName + "Year");

      res.add(inputYear);

      Input inputHour = res.createInput(inputName + "Hour");

      res.add(inputHour);

      Input inputMinute = res.createInput(inputName + "Minute");

      res.add(inputMinute);

      Calendar calendar = new GregorianCalendar();

      if (timestamp != null)
      {
        calendar.setTime(timestamp);
        inputDay.setDefaultValue(new Integer(calendar.get(Calendar.DAY_OF_MONTH)));
        inputMonth.setDefaultValue(new Integer(calendar.get(Calendar.MONTH) + 1));
        inputYear.setDefaultValue(new Integer(calendar.get(Calendar.YEAR)));
        inputHour.setDefaultValue(new Integer(calendar.get(Calendar.HOUR_OF_DAY)));
        inputMinute.setDefaultValue(new Integer(calendar.get(Calendar.MINUTE)));
      }
      else
      {
        inputDay.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Day"), - 1));
        inputMonth.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Month"), - 1));
        inputYear.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Year"), - 1));
        inputHour.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Hour"), - 1));
        inputMinute.setDefaultValue(NumberTools.toIntInstance(persistents.getAttribute(inputName + "Minute"),
                - 1));
      }
    }
    else if ("money".equals(field.getEditor()))
    {
      Input inputValue = res.createInput(inputName + "Value");

      res.add(inputValue);

      if (field.isBound())
      {
        if (getAttributeFromDataObject(persistent, fieldName) != null)
        {
          inputValue.setDefaultValue(getAttributeFromDataObject(persistent, fieldName));
        }
        else
        {
          inputValue.setDefaultValue(getAttributeDefaultValueFromDataObject(persistent, fieldName));
        }
      }

      Input inputCurrency = res.createInput(inputName + "Currency");

      res.add(inputCurrency);

      String currencyFieldName = fieldName + "Currency";

      if (field.isBound())
      {
        if (getAttributeFromDataObject(persistent, currencyFieldName) != null)
        {
          inputCurrency.setDefaultValue(getAttributeFromDataObject(persistent, currencyFieldName));
        }
        else
        {
          inputCurrency.setDefaultValue(getAttributeDefaultValueFromDataObject(persistent, fieldName));
        }
      }
    }
    else if ("combo".equals(field.getEditor()))
    {
      if (field.isBound())
      {
        if (getAttributeFromDataObject(persistent, fieldName) != null)
        {
          Object value = getAttributeFromDataObject(persistent, fieldName);
          if (! value.getClass().isEnum() && ! (value instanceof String) && ! (value instanceof Integer))
          {
            value = getAttributeFromDataObject(persistent, fieldName + ".id");
          }
          input.setDefaultValue(value);
        }
        else
        {
          input.setDefaultValue(getAttributeDefaultValueFromDataObject(persistent, fieldName));
        }

        try
        {
          input.setValidValues(getAttributeValidValuesFromDataObject(persistent, fieldName));
        }
        catch (PersistenceException x)
        {
          Map validValues = (Map) persistents.getAttribute(inputName + "ValidValues");

          if (validValues != null)
          {
            input.setValidValues((Map) persistents.getAttribute(inputName + "ValidValues"));
          }
          else
          {
            TreeMap dummyValues = new TreeMap();
            dummyValues.put("", "---");
            input.setValidValues(dummyValues);
            addError(res, ValidationResult.ERROR_NO_VALID_VALUES, inputName, result, 0);
          }
        }
      }
      else
      {
        input.setDefaultValue(persistents.getAttribute(inputName));

        Map validValues = (Map) persistents.getAttribute(inputName + "ValidValues");

        if (validValues != null)
        {
          input.setValidValues(validValues);
        }
        else
        {
          TreeMap dummyValues = new TreeMap();

          dummyValues.put("", "---");
          input.setValidValues(dummyValues);
          addError(res, ValidationResult.ERROR_NO_VALID_VALUES, inputName, result, 0);
        }
      }
    }
    else if ("list".equals(field.getEditor()))
    {
      input.setAttribute("listId", inputName);
    }
    else if ("none".equals(field.getEditor()))
    {
      input.setDefaultValue("");
    }
    else if ("check".equals(field.getEditor()))
    {
      if (field.isBound())
      {
        if (getAttributeFromDataObject(persistent, fieldName) != null)
        {
          input.setDefaultValue(NumberTools.toBool(getAttributeFromDataObject(persistent, fieldName), false));
        }
        else
        {
          input.setDefaultValue(getAttributeDefaultValueFromDataObject(persistent, fieldName));
        }
      }
      else
      {
        input.setDefaultValue(NumberTools.toBool(persistents.getAttribute(inputName), false));
      }
    }
    else if (field.getEditor().startsWith("jsp:"))
    {
      input.setAttribute("jsp", field.getEditor().substring(4));
    }
    else
    {
      if (persistents.hasAttribute(inputName))
      {
        input.setDefaultValue(persistents.getAttribute(inputName));
      }
      else
      {
        if (req.getParameter(name) != null)
        {
          input.setDefaultValue(req.getParameterAsString(name));
        }
        else if (req.getParameter(fieldName) != null)
        {
          input.setDefaultValue(req.getParameterAsString(fieldName));
        }
        else if (field.isBound())
        {
          if (getAttributeFromDataObject(persistent, fieldName) != null)
          {
            input.setDefaultValue(getAttributeFromDataObject(persistent, fieldName));
          }
          else
          {
            input.setDefaultValue(getAttributeDefaultValueFromDataObject(persistent, fieldName));
          }
        }
        else
        {
          if (persistents.hasAttribute(fieldName))
          {
            input.setDefaultValue(persistents.getAttribute(fieldName));
          }
          else
          {
            input.setDefaultValue(persistents.getAttribute(inputName));
          }
        }
      }
    }

    if (outGroup != null)
    {
      outGroup.add(input);
    }

    if (field.getCommands().commandCount() > 0)
    {
      Output commands = res.createOutput("commands");
      input.setAttribute("commands", commands);
      for (Iterator i = field.getCommands().iterator(); i.hasNext();)
      {
        CommandInfo descriptor = (CommandInfo) i.next();
        Command command = descriptor.createCommand(req, res, context);
        commands.add(command);
      }
    }

    res.add(input);

    if (res.get("focus") == null && ! field.isHidden() && ! field.isReadOnly())
    {
      res.addOutput("focus", inputName);
    }
  }

  /**
   * Validate the complete formular input against the formular and persistent
   * constraints. This method generates global and field specific error
   * objects in the model response.
   *
   * @param req The model request.
   * @param res The model response.
   * @param formular The formular description.
   * @param persistents The persistent instances.
   * @return A validation result.
   * @throws ModelException
   */
  public static ValidationResult validateInput(ModelRequest req, ModelResponse res, FormularDescriptor formular,
          PersistentDescriptor persistents) throws ModelException
  {
    ValidationResult result = new ValidationResult();

    if (formular.hasPages())
    {
      int currentPageNum = Math.max(Math.min(formular.getPage(), formular.getPageCount() - 1), 0);

      int pageNum = 0;

      for (Iterator iPages = formular.pageIterator(); iPages.hasNext();)
      {
        PageDescriptor page = (PageDescriptor) iPages.next();

        validateInput(req, res, formular, persistents, page.groupIterator(), result, pageNum);

        ++pageNum;
      }
    }
    else
    {
      validateInput(req, res, formular, persistents, formular.groupIterator(), result, 0);
    }

    return result;
  }

  /**
   * Validate the complete formular input against the formular and persistent
   * constraints. This method generates global and field specific error
   * objects in the model response.
   *
   * @param req The model request.
   * @param res The model response.
   * @param formular The formular description.
   * @param persistents The persistent instances.
   * @param result The validation result.
   * @param pageNum The current page number.
   * @throws ModelException
   */
  public static void validateInput(ModelRequest req, ModelResponse res, FormularDescriptor formular,
          PersistentDescriptor persistents, Iterator iGroups, ValidationResult result, int pageNum)
    throws ModelException
  {
    for (; iGroups.hasNext();)
    {
      GroupDescriptor group = (GroupDescriptor) iGroups.next();

      if (! group.isVisible())
      {
        continue;
      }

      for (Iterator<FieldDescriptor> j = group.fieldIterator(); j.hasNext();)
      {
        FieldDescriptor field = (FieldDescriptor) j.next();
       
        if (field.isReadOnly() || field.isOmitted() || field.isDisabled())
        {
          continue;
        }

        String name = field.getName();
        String fieldName = name.substring(name.indexOf('.') + 1);
        String inputName = name.replace('.', '_').replace('(', '_').replace(')', '_');

        if ("text".equals(field.getEditor()) || "password".equals(field.getEditor())
                || "number".equals(field.getEditor()) || "integer".equals(field.getEditor())
                || "digits".equals(field.getEditor()) || "realnumber".equals(field.getEditor())
                || "ipaddress".equals(field.getEditor()) || "nospacetext".equals(field.getEditor())
                || "identifier".equals(field.getEditor()) || "country".equals(field.getEditor())
                || "combo".equals(field.getEditor()) || "email".equals(field.getEditor())
                || "macaddress".equals(field.getEditor()) || "day".equals(field.getEditor())
                || "month".equals(field.getEditor()) || "year".equals(field.getEditor())
                || "hostname".equals(field.getEditor()) || field.getEditor().startsWith("regexp"))
        {
          if (field.isDuty() && ! field.isDisabled() && StringTools.isTrimEmpty(persistents.getAttribute(inputName)))
          {
            addError(res, ValidationResult.ERROR_MISSING_DUTY_FIELD, inputName, result, pageNum);
          }
          else
          {
            if (field.hasValidationClass())
            {
              if (field.getValidationClass().checkValidation(req, persistents, field,
                      (String) persistents.getAttribute(inputName)))
              {
                addError(res, ValidationResult.ERROR_VALIDATION_CLASS, inputName, result, field
                        .getValidationClass().getErrorTextId(), pageNum);
              }
            }

            if (! StringTools.isTrimEmpty(persistents.getAttribute(inputName)))
            {
              if ("number".equals(field.getEditor())
                      && ! reNumber.matcher(StringTools.trim(persistents.getAttribute(inputName)))
                              .matches())
              {
                addError(res, ValidationResult.ERROR_NOT_A_NUMBER, inputName, result, pageNum);
              }
              else if ("integer".equals(field.getEditor())
                      && ! reInteger.matcher(
                              StringTools.trim(persistents.getAttribute(inputName)))
                              .matches())
              {
                addError(res, ValidationResult.ERROR_NOT_AN_INTEGER, inputName, result, pageNum);
              }
              else if ("digits".equals(field.getEditor())
                      && ! reDigits.matcher(StringTools.trim(persistents.getAttribute(inputName)))
                              .matches())
              {
                addError(res, ValidationResult.ERROR_ONLY_DIGITS_ALLOWED, inputName, result, pageNum);
              }
              else if ("realnumber".equals(field.getEditor())
                      && ! reRealNumber.matcher(
                              StringTools.trim(persistents.getAttribute(inputName)))
                              .matches())
              {
                addError(res, ValidationResult.ERROR_NOT_A_REAL_NUMBER, inputName, result, pageNum);
              }
              else if ("ipaddress".equals(field.getEditor())
                      && ! reIpAddress.matcher(
                              StringTools.trim(persistents.getAttribute(inputName)))
                              .matches())
              {
                addError(res, ValidationResult.ERROR_NOT_A_IP_ADDRESS, inputName, result, pageNum);
              }
              else if ("hostname".equals(field.getEditor())
                      && ! reHostname.matcher(
                              StringTools.trim(persistents.getAttribute(inputName)))
                              .matches())
              {
                addError(res, ValidationResult.ERROR_NOT_A_HOSTNAME, inputName, result, pageNum);
              }
              else if ("nospacetext".equals(field.getEditor())
                      && ! reNoWhiteSpace.matcher(
                              StringTools.trim(persistents.getAttribute(inputName)))
                              .matches())
              {
                addError(res, ValidationResult.ERROR_WHITESPACE_NOT_ALLOWED, inputName, result, pageNum);
              }
              else if ("identifier".equals(field.getEditor())
                      && ! reIdentifier.matcher(
                              StringTools.trim(persistents.getAttribute(inputName)))
                              .matches())
              {
                addError(res, ValidationResult.ERROR_WHITESPACE_OR_SPECIAL_NOT_ALLOWED, inputName,
                        result, pageNum);
              }
              else if ("email".equals(field.getEditor())
                      && ! reEmail.matcher(StringTools.trim(persistents.getAttribute(inputName)))
                              .matches())
              {
                addError(res, ValidationResult.ERROR_NOT_AN_EMAIL, inputName, result, pageNum);
              }
              else if (("password".equals(field.getEditor()))
                      && (((String) persistents.getAttribute(inputName)).indexOf(" ") > - 1))
              {
                addError(res, ValidationResult.ERROR_WHITESPACE_OR_SPECIAL_NOT_ALLOWED, inputName,
                        result, pageNum);
              }
              else if (("macaddress".equals(field.getEditor())))
              {
                try
                {
                  StringTools.normalizeMACAddress((String) persistents.getAttribute(inputName));
                }
                catch (IllegalArgumentException ignored)
                {
                  addError(res, ValidationResult.ERROR_NOT_A_MACADDRESS, inputName, result, pageNum);
                }
              }
              else if (field.getEditor().startsWith("regexp:"))
              {
                try
                {
                  Pattern re = Pattern.compile(field.getEditor().substring(7));

                  if (! re.matcher((String) persistents.getAttribute(inputName)).matches())
                  {
                    addError(res, ValidationResult.ERROR_REGEXP, inputName, result, pageNum);
                  }
                }
                catch (PatternSyntaxException x)
                {
                  throw new ModelException("FormTools: Regexp editor unable to compile pattern: " + x);
                }
              }
            }
          }
        }
        else if ("date".equals(field.getEditor()))
        {
          int day = NumberTools.toInt(persistents.getAttribute(inputName + "Day"), - 1);
          int month = NumberTools.toInt(persistents.getAttribute(inputName + "Month"), - 1);
          int year = NumberTools.toInt(persistents.getAttribute(inputName + "Year"), - 1);

          if (field.isDuty() && ! field.isDisabled() && day == - 1 && month == - 1 && year == - 1)
          {
            addError(res, ValidationResult.ERROR_MISSING_DUTY_FIELD, inputName, result, pageNum);
          }

          if ((day != - 1 || month != - 1 || year != - 1) && (day == - 1 || month == - 1 || year == - 1))
          {
            addError(res, ValidationResult.ERROR_MISSING_DATE_FIELD, inputName, result, pageNum);
          }
        }
        else if ("time".equals(field.getEditor()))
        {
          int minute = NumberTools.toInt(persistents.getAttribute(inputName + "Minute"), - 1);
          int hour = NumberTools.toInt(persistents.getAttribute(inputName + "Hour"), - 1);

          if (field.isDuty() && ! field.isDisabled() && minute == - 1 && hour == - 1)
          {
            addError(res, ValidationResult.ERROR_MISSING_DUTY_FIELD, inputName, result, pageNum);
          }

          if ((minute != - 1 || hour != - 1) && (minute == - 1 || hour == - 1))
          {
            addError(res, ValidationResult.ERROR_MISSING_TIME_FIELD, inputName, result, pageNum);
          }
        }
        else if ("money".equals(field.getEditor()))
        {
          if (field.isDuty() && ! field.isDisabled() && StringTools.isTrimEmpty(persistents.getAttribute(inputName)))
          {
            addError(res, ValidationResult.ERROR_MISSING_DUTY_FIELD, inputName, result, pageNum);
          }
        }
      }
    }
  }

  /**
   * Helper method for the validateInput method.
   *
   * This method sets a global error, but only if this is the first time, that
   * a specific error occurred. In any case a field error is generated.
   *
   * @param res The model response.
   * @param errorType The error type.
   * @param inputName The name of the input field.
   * @param result The validation result.
   * @param pageNum The index of the page that contains the field.
   * @throws ModelException
   */
  public static void addError(ModelResponse res, int errorType, String inputName, ValidationResult result, int pageNum)
    throws ModelException
  {
    addError(res, errorType, inputName, result, "", pageNum);
  }

  /**
   * Helper method for the validateInput method.
   *
   * This method sets a global error, but only if this is the first time, that
   * a specific error occurred. In any case a field error is generated.
   *
   * @param res The model response.
   * @param errorType The error type.
   * @param inputName The name of the input field.
   * @param result The validation result.
   * @param string The errorTextId
   * @param pageNum The index of the page that contains the field.
   * @throws ModelException
   */
  public static void addError(ModelResponse res, int errorType, String inputName, ValidationResult result,
          String errorTextId, int pageNum) throws ModelException
  {
    String name = inputName.replace('.', '_').replace('(', '_').replace(')', '_');

    result.addError(name, errorType, pageNum, errorTextId);
  }

  /**
   * Add an error to a model response and validation result.
   *
   * @param res The model response.
   * @param result The validation result.
   * @param field The error field.
   * @param message The error message.
   */
  public static void addError(ModelResponse res, ValidationResult result, String field, String message)
  {
    String name = field.replace('.', '_');

    result.addError(name, ValidationResult.ERROR_GENERAL, 0, message);
  }

  /**
   * Add an info message to a model response and validation result.
   *
   * @param res The model response.
   * @param result The validation result.
   * @param message The info message.
   */
  public static void addInfo(ModelResponse res, ValidationResult result, String message)
  {
    result.addInfo(message);
  }

  /**
   * Transfer the complete formular input into the persistent objects.
   *
   * @param req The model request.
   * @param res The model response.
   * @param formular The formular description.
   * @param persistents The persistent instances.
   * @return True If the stored input has modified the persistents.
   * @throws ModelException
   */
  public static boolean storeInput(ModelRequest req, ModelResponse res, FormularDescriptor formular,
          PersistentDescriptor persistents, Logger logger) throws ModelException, PersistenceException
  {
    boolean modified = false;

    Calendar calendar = new GregorianCalendar();

    int page = Math.max(Math.min(formular.getPage(), formular.getPageCount() - 1), 0);

    Iterator iGroups = formular.hasPages() ? formular.getPage(page).groupIterator() : formular.groupIterator();

    for (; iGroups.hasNext();)
    {
      GroupDescriptor group = (GroupDescriptor) iGroups.next();

      if (! group.isVisible())
      {
        continue;
      }

      for (Iterator<FieldDescriptor> j = group.fieldIterator(); j.hasNext();)
      {
        FieldDescriptor field = (FieldDescriptor) j.next();

        if (field.isReadOnly() || field.isDisabled() || field.isOmitted() || field.isComment() || field.getEditor().startsWith("jsp"))
        {
          continue;
        }

        String name = field.getName();
        String fieldName = name.substring(name.indexOf('.') + 1);
        String persistentName = name.substring(0, Math.max(name.indexOf('.'), 0));
        String inputName = name.replace('.', '_').replace('(', '_').replace(')', '_');

        Object persistent = null;
        PersistentMetaData meta = null;

        if (field.isSelectable() && req.getParameter(inputName + "_Selected") != null)
        {
          persistents.setAttributeSelected(inputName, true);
        }

        if (field.isBound())
        {
          persistent = persistents.get(persistentName);

          if (persistent instanceof Persistent)
          {
            meta = ((Persistent) persistent).getMetaData();
          }
        }

        if ("money".equals(field.getEditor()))
        {
          if (! StringTools.isTrimEmpty(req.getParameter(inputName)))
          {
            setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName,
                    NumberTools.toDoubleInstance(req.getParameter(inputName), 0.0));
            persistents.putAttribute(inputName, req.getParameterAsString(inputName));
          }
          else
          {
            setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName, null);
            persistents.removeAttribute(inputName);
          }

          setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName
                  + "Currency", req.getParameterAsString(inputName + "Currency"));
          persistents.putAttribute(inputName + "Currency", req.getParameterAsString(inputName + "Currency"));
        }
        else if ("date".equals(field.getEditor()))
        {
          int day = NumberTools.toInt(req.getParameter(inputName + "Day"), - 1);
          int month = NumberTools.toInt(req.getParameter(inputName + "Month"), - 1);
          int year = NumberTools.toInt(req.getParameter(inputName + "Year"), - 1);

          persistents.putAttribute(inputName + "Day", new Integer(day));
          persistents.putAttribute(inputName + "Month", new Integer(month));
          persistents.putAttribute(inputName + "Year", new Integer(year));

          if (day != - 1 && month != - 1 && year != - 1)
          {
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.set(Calendar.DAY_OF_MONTH, day);
            calendar.set(Calendar.MONTH, month - 1);
            calendar.set(Calendar.YEAR, year);

            setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName,
                    new Date(calendar.getTime().getTime()));
            persistents.putAttribute(inputName, new Date(calendar.getTime().getTime()));
          }
          else
          {
            setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName, null);
            persistents.removeAttribute(inputName);
          }
        }
        else if ("time".equals(field.getEditor()))
        {
          int hour = NumberTools.toInt(req.getParameter(inputName + "Hour"), - 1);
          int minute = NumberTools.toInt(req.getParameter(inputName + "Minute"), - 1);

          persistents.putAttribute(inputName + "Hour", new Integer(hour));
          persistents.putAttribute(inputName + "Minute", new Integer(minute));

          if (minute != - 1 && hour != - 1)
          {
            Time time = Time.valueOf(hour + ":" + minute + ":0");

            setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName, time);
            persistents.putAttribute(inputName, time);
          }
          else
          {
            setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName, null);
            persistents.removeAttribute(inputName);
          }
        }
        else if ("timestamp".equals(field.getEditor()))
        {
          int day = NumberTools.toInt(req.getParameter(inputName + "Day"), - 1);
          int month = NumberTools.toInt(req.getParameter(inputName + "Month"), - 1);
          int year = NumberTools.toInt(req.getParameter(inputName + "Year"), - 1);
          int hour = NumberTools.toInt(req.getParameter(inputName + "Hour"), - 1);
          int minute = NumberTools.toInt(req.getParameter(inputName + "Minute"), - 1);

          persistents.putAttribute(inputName + "Day", new Integer(day));
          persistents.putAttribute(inputName + "Month", new Integer(month));
          persistents.putAttribute(inputName + "Year", new Integer(year));
          persistents.putAttribute(inputName + "Hour", new Integer(hour));
          persistents.putAttribute(inputName + "Minute", new Integer(minute));

          if (day != - 1 && month != - 1 && year != - 1 && minute != - 1 && hour != - 1)
          {
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.set(Calendar.DAY_OF_MONTH, day);
            calendar.set(Calendar.MONTH, month - 1);
            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MINUTE, minute);
            calendar.set(Calendar.HOUR_OF_DAY, hour);

            setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName,
                    new Timestamp(calendar.getTime().getTime()));
            persistents.putAttribute(inputName, new Timestamp(calendar.getTime().getTime()));
          }
          else
          {
            setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName, null);
            persistents.removeAttribute(inputName);
          }
        }
        else if ("check".equals(field.getEditor()))
        {
          boolean oldValue = persistents.hasAttribute(inputName) ? ((Boolean) persistents
                  .getAttribute(inputName)).booleanValue() : false;

          modified |= (NumberTools.toBool(req.getParameter(inputName), false) != oldValue);

          setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName,
                  NumberTools.toBoolInstance(req.getParameter(inputName), false));
          persistents.putAttribute(inputName, NumberTools.toBoolInstance(req.getParameter(inputName), false));
        }
        else if ("number".equals(field.getEditor()) && ! StringTools.isTrimEmpty(req.getParameter(inputName)))
        {
          setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName,
                  NumberTools.toIntInstance(req.getParameter(inputName), 0));
          persistents.putAttribute(inputName, req.getParameterAsString(inputName));
        }
        else if ("macaddress".equals(field.getEditor())
                && ! StringTools.isTrimEmpty(req.getParameter(inputName)))
        {
          String macAddress = req.getParameterAsString(inputName);

          try
          {
            macAddress = StringTools.normalizeMACAddress(macAddress);
          }
          catch (IllegalArgumentException ignored)
          {
          }

          setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName, macAddress);
          persistents.putAttribute(inputName, req.getParameterAsString(inputName));
        }
        else if ("list".equals(field.getEditor()))
        {
        }
        else if ("dipswitch".equals(field.getEditor()))
        {
          String oldVal = (String) persistents.getAttribute(inputName);
          StringBuffer val = new StringBuffer();

          if (oldVal != null)
          {
            for (int i = 0; i < oldVal.length(); ++i)
            {
              val.append(req.getParameter(inputName + i) != null ? "1" : "0");
            }
          }

          setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName,
                  val.toString());
          persistents.putAttribute(inputName, val.toString());
        }
        else if ("weekdaycheck".equals(field.getEditor()))
        {
          StringBuffer val = new StringBuffer();

          for (int i = 0; i < 7; ++i)
          {
            val.append(req.getParameter(inputName + i) != null ? (i + ",") : "");
          }

          setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName,
                  val.toString());
          persistents.putAttribute(inputName, val.toString());
        }
        else if ("seconds".equals(field.getEditor()) || "minutes".equals(field.getEditor())
                || "hours".equals(field.getEditor()) || "days".equals(field.getEditor())
                || "months".equals(field.getEditor()) || "weekdays".equals(field.getEditor()))
        {
          Object vs = req.getParameter(inputName);
          String[] values = null;

          if (vs instanceof String[])
          {
            values = (String[]) vs;
          }
          else
          {
            values = vs != null ? new String[]
            {
              vs.toString()
            } : new String[0];
          }

          StringBuilder commaValues = new StringBuilder();

          if (values != null)
          {
            for (String value : values)
            {
              StringTools.appendWithDelimiter(commaValues, value, ",");
            }
          }

          String newValue = commaValues.toString();

          if (persistents.hasAttribute(inputName))
          {
            modified |= ! newValue.equals(persistents.getAttribute(inputName));
          }
          else
          {
            modified |= ! newValue.equals(getAttributeFromDataObject(persistent, fieldName));
          }

          setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName, newValue);
          persistents.putAttribute(inputName, newValue);
        }
        else
        {
          String value = req.getParameterAsString(inputName);

          if (! "textarea".equals(field.getEditor()))
          {
            value = StringTools.trim(value);
          }

          if (value != null && meta != null && meta.getLength(fieldName) > 0)
          {
            value = value.substring(0, Math.min(meta.getLength(fieldName), value.length()));
          }

          if (persistents.hasAttribute(inputName))
          {
            modified |= ! value.equals(persistents.getAttribute(inputName));
          }

          setAttributeOnDataObjectSafe(logger, persistents, persistent, persistentName, fieldName, value);
          persistents.putAttribute(inputName, value);
        }
      }
    }

    return modified;
  }

  /**
   * This method sets the input values by reading the data of a property
   * table. The persistents of this table must contain the fields 'category',
   * 'name', 'type', 'validValues' and 'value'.
   *
   * @param req The model request.
   * @param formular The formular description.
   * @param persistents The persistent descriptor in which to store the input
   *            values.
   * @param persistentId The id of the persistent objects of the property
   *            table.
   */
  public static void createInputValuesFromPropertyTable(ModelRequest req, FormularDescriptor formular,
          PersistentDescriptor persistents, String persistentId) throws ModelException, PersistenceException
  {
    createInputValuesFromPropertyTable(req, formular, persistents, persistentId, null);
  }

  /**
   * This method sets the input values by reading the data of a property
   * table. The persistents of this table must contain the fields 'category',
   * 'name', 'type', 'validValues' and 'value'.
   *
   * @param req The model request.
   * @param formular The formular description.
   * @param persistents The persistent descriptor in which to store the input
   *            values.
   * @param persistentId The id of the persistent objects of the property
   *            table.
   * @param category Only create input values for fields that match this
   *            category.
   */
  public static void createInputValuesFromPropertyTable(ModelRequest req, FormularDescriptor formular,
          PersistentDescriptor persistents, String persistentId, String category)
    throws ModelException, PersistenceException
  {
    createInputValuesFromPropertyTable(req, formular, persistents, persistentId, category,
            UserTools.getCurrentUserId(req));
  }

  /**
   * This method sets the input values by reading the data of a property
   * table. The persistents of this table must contain the fields 'category',
   * 'name', 'type', 'validValues' and 'value'.
   *
   * @param req The model request.
   * @param formular The formular description.
   * @param persistents The persistent descriptor in which to store the input
   *            values.
   * @param persistentId The id of the persistent objects of the property
   *            table.
   * @param category Only create input values for fields that match this
   *            category.
   */
  public static void createInputValuesFromPropertyTable(ModelRequest req, FormularDescriptor formular,
          PersistentDescriptor persistents, String persistentId, String category, Integer userId)
    throws ModelException, PersistenceException
  {
    PersistentFactory persistentManager = (PersistentFactory) req.getService(PersistentFactory.ROLE,
            req.getDomain());

    Persistent sample = persistentManager.create(persistentId);

    if (sample.getMetaData().hasField("userId"))
    {
      sample.setField("userId", userId);
    }

    if (! StringTools.isTrimEmpty(category))
    {
      sample.setField("category", category);
    }

    for (Iterator i = sample.query().iterator(); i.hasNext();)
    {
      Persistent persistent = (Persistent) i.next();

      String fieldName = persistent.getFieldString("category") + "." + persistent.getFieldString("name");

      if (! formular.containsField(fieldName))
      {
        continue;
      }

      String key = persistent.getFieldString("category") + "_" + persistent.getFieldString("name");

      switch (persistent.getFieldString("type").charAt(0))
      {
        case 'S':
          persistents.putAttribute(key, persistent.getFieldString("value"));

          break;

        case 'B':
          persistents.putAttribute(key, NumberTools.toBoolInstance(persistent.getFieldString("value")));

          break;

        case 'I':
          persistents.putAttribute(key, NumberTools.toIntInstance(persistent.getFieldString("value")));

          break;

        case 'C':
        {
          StringTokenizer st = new StringTokenizer(persistent.getFieldString("validValues"), "|");
          TreeMap validValues = new TreeMap();

          while (st.hasMoreTokens())
          {
            String aValidValue = st.nextToken();

            validValues.put(aValidValue, "$" + aValidValue);
          }

          persistents.putAttribute(key, persistent.getFieldString("value"));
          persistents.putAttribute(key + "ValidValues", validValues);

          break;
        }

        case 'T':
          persistents.putAttribute(key, Time.valueOf(persistent.getFieldString("value")));

          break;
      }
    }
  }

  /**
   * This method stores the input values into a property table. The
   * persistents of this table must contain the fields 'category', 'name',
   * 'type', 'validValues' and 'value'.
   *
   * @param req The model request.
   * @param formular The formular description.
   * @param persistents The persistent descriptor in which to store the input
   *            values.
   * @param persistentId The id of the persistent objects of the property
   *            table.
   * @return True if any of the values have changed.
   */
  public static boolean storeInputValuesToPropertyTable(ModelRequest req, FormularDescriptor formular,
          PersistentDescriptor persistents, String persistentId) throws ModelException, PersistenceException
  {
    return storeInputValuesToPropertyTable(req, formular, persistents, persistentId, null);
  }

  /**
   * This method stores the input values into a property table. The
   * persistents of this table must contain the fields 'category', 'name',
   * 'type', 'validValues' and 'value'.
   *
   * @param req The model request.
   * @param formular The formular description.
   * @param persistents The persistent descriptor in which to store the input
   *            values.
   * @param persistentId The id of the persistent objects of the property
   *            table.
   * @param category Only store input values for fields that match this
   *            category.
   * @return True if any of the values have changed.
   */
  public static boolean storeInputValuesToPropertyTable(ModelRequest req, FormularDescriptor formular,
          PersistentDescriptor persistents, String persistentId, String category)
    throws ModelException, PersistenceException
  {
    return storeInputValuesToPropertyTable(req, formular, persistents, persistentId, category,
            UserTools.getCurrentUserId(req));
  }

  /**
   * This method stores the input values into a property table. The
   * persistents of this table must contain the fields 'category', 'name',
   * 'type', 'validValues' and 'value'.
   *
   * @param req The model request.
   * @param formular The formular description.
   * @param persistents The persistent descriptor in which to store the input
   *            values.
   * @param persistentId The id of the persistent objects of the property
   *            table.
   * @param category Only store input values for fields that match this
   *            category.
   * @return True if any of the values have changed.
   */
  public static boolean storeInputValuesToPropertyTable(ModelRequest req, FormularDescriptor formular,
          PersistentDescriptor persistents, String persistentId, String category, Integer userId)
    throws ModelException, PersistenceException
  {
    boolean modified = false;

    PersistentFactory persistentManager = (PersistentFactory) req.getService(PersistentFactory.ROLE,
            req.getDomain());

    Persistent sample = persistentManager.create(persistentId);

    if (sample.getMetaData().hasField("userId"))
    {
      sample.setField("userId", userId);
    }

    if (! StringTools.isTrimEmpty(category))
    {
      sample.setField("category", category);
    }

    for (Iterator i = sample.query().iterator(); i.hasNext();)
    {
      Persistent persistent = (Persistent) i.next();

      String fieldName = persistent.getFieldString("category") + "." + persistent.getFieldString("name");

      if (! formular.containsField(fieldName))
      {
        continue;
      }

      String key = persistent.getFieldString("category") + "_" + persistent.getFieldString("name");

      modified |= ! StringTools.trim(persistent.getField("value")).equals(
              StringTools.trim(persistents.getAttribute(key)));

      switch (persistent.getFieldString("type").charAt(0))
      {
        case 'S':
          persistent.setField("value", StringTools.trim(persistents.getAttribute(key)));

          break;

        case 'B':
          persistent.setField("value", NumberTools.toBoolInstance(persistents.getAttribute(key)));

          break;

        case 'I':
          persistent.setField("value", NumberTools.toIntInstance(persistents.getAttribute(key)));

          break;

        case 'C':
          persistent.setField("value", persistents.getAttribute(key));

          break;

        case 'T':

          try
          {
            persistent.setField("value", formatPropertyTime.format(persistents.getAttribute(key)));
          }
          catch (Exception x)
          {
            persistent.setField("value", "00:00:00");
          }

          break;
      }

      persistent.update();

      SystemConfigManager systemConfigManager = (SystemConfigManager) req.getSpringBean(SystemConfigManager.ID);

      systemConfigManager.invalidate(persistent.getFieldString("category"), persistent.getFieldString("name"));
    }

    return modified;
  }

  /**
   */
  public static void loadPersistents(FormularDescriptor formular, PersistentDescriptor persistents)
    throws ModelException, PersistenceException
  {
    if (formular.hasPages())
    {
      int currentPageNum = Math.max(Math.min(formular.getPage(), formular.getPageCount() - 1), 0);

      int pageNum = 0;

      for (Iterator iPages = formular.pageIterator(); iPages.hasNext();)
      {
        PageDescriptor page = (PageDescriptor) iPages.next();

        loadPersistents(formular, persistents, page.groupIterator());

        ++pageNum;
      }
    }
    else
    {
      loadPersistents(formular, persistents, formular.groupIterator());
    }
  }

  /**
   */
  public static void loadPersistents(FormularDescriptor formular, PersistentDescriptor persistents, Iterator iGroups)
    throws ModelException, PersistenceException
  {
    for (; iGroups.hasNext();)
    {
      GroupDescriptor group = (GroupDescriptor) iGroups.next();

      if (! group.isVisible())
      {
        continue;
      }

      for (Iterator<FieldDescriptor> j = group.fieldIterator(); j.hasNext();)
      {
        FieldDescriptor field = (FieldDescriptor) j.next();

        if (field.isReadOnly() || ! field.isBound() || field.isOmitted())
        {
          continue;
        }

        String name = field.getName();
        String fieldName = name.substring(name.indexOf('.') + 1);
        String persistentName = name.substring(0, Math.max(name.indexOf('.'), 0));
        String inputName = name.replace('.', '_').replace('(', '_').replace(')', '_');

        if (StringTools.isTrimEmpty(persistentName) && field.isBound())
        {
          throw new ModelException("No persistent specified for bound parameter '" + inputName + "'");
        }

        Object attributeValue = getAttributeFromDataObject(persistents.get(persistentName), fieldName);

        if ("text".equals(field.getEditor()) || "textarea".equals(field.getEditor())
                || "password".equals(field.getEditor()) || "number".equals(field.getEditor())
                || "integer".equals(field.getEditor()) || "digits".equals(field.getEditor())
                || "realnumber".equals(field.getEditor()) || "ipaddress".equals(field.getEditor())
                || "nospacetext".equals(field.getEditor()) || "identifier".equals(field.getEditor())
                || "country".equals(field.getEditor()) || "macaddress".equals(field.getEditor())
                || "combo".equals(field.getEditor()) || "email".equals(field.getEditor())
                || field.getEditor().startsWith("regexp"))
        {
          persistents.putAttribute(inputName, StringTools.trim(attributeValue));
        }
        else if ("check".equals(field.getEditor()))
        {
          persistents.putAttribute(inputName, NumberTools.toBoolInstance(attributeValue));
        }
      }
    }
  }

  /**
   * Retrieve an attribute either from a Persistent object or a general bean
   * object.
   *
   * @param o The object
   * @param name The attribute name
   * @return The attribute value
   * @throws PersistenceException If the attribute couldn't be retrieved
   */
  protected static Object getAttributeFromDataObject(Object o, String name) throws PersistenceException
  {
    if (o instanceof Persistent)
    {
      return ((Persistent) o).getField(name);
    }
    else
    {
      try
      {
        return PropertyUtils.getNestedProperty(o, name);
      }
      catch (IllegalAccessException x)
      {
      }
      catch (InvocationTargetException x)
      {
      }
      catch (NoSuchMethodException x)
      {
      }
    }

    throw new PersistenceException("Object of type " + o.getClass() + " doesn't contain attribute '" + name + "'");
  }

  /**
   * Set an attribute either on a Persistent object or a general bean object.
   *
   * @param o The object
   * @param value The attribute vale
   * @throws PersistenceException If the attribute couldn't be retrieved
   */
  private static void setAttributeOnDataObject(Logger logger, Object o, String name, Object value)
    throws PersistenceException
  {
    if (o == null)
    {
      return;
    }

    if (o instanceof Persistent)
    {
      ((Persistent) o).setField(name, value);

      return;
    }
    else
    {
      try
      {
        PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(o, name);

        if (descriptor != null && Enum.class.isAssignableFrom(descriptor.getPropertyType()))
        {
          value = MethodUtils.invokeExactStaticMethod(descriptor.getPropertyType(), "valueOf", value);
        }
        else if (descriptor != null
                && descriptor.getPropertyType().getAnnotation(javax.persistence.Entity.class) != null)
        {
          StandardDao standardDAO = (StandardDao) SpringTools.getBean(StandardDao.ID);
          value = standardDAO.get(descriptor.getPropertyType().getName(), NumberTools.toInt(value, - 1));
        }

        PropertyUtils.setNestedProperty(o, name, value);

        return;
      }
      catch (IllegalAccessException x)
      {
        logger.error("Unable to set property " + name + " in object " + o, x);
      }
      catch (InvocationTargetException x)
      {
        logger.error("Unable to set property " + name + " in object " + o, x);
      }
      catch (NoSuchMethodException x)
      {
        logger.error("Unable to set property " + name + " in object " + o, x);
      }
    }

    throw new PersistenceException("Object of type " + o.getClass() + " doesn't contain attribute '" + name + "'");
  }

  /**
   * Set an attribute either on a Persistent object, a general bean object or
   * as a persistent attribute.
   *
   * @param persistents
   * @param persistent
   * @param persistentName
   * @param fieldName
   * @param value
   * @throws PersistenceException
   */
  private static void setAttributeOnDataObject(Logger logger, PersistentDescriptor persistents, Object persistent,
          String persistentName, String fieldName, Object value) throws PersistenceException
  {
    try
    {
      setAttributeOnDataObject(logger, persistent, fieldName, value);
    }
    catch (PersistenceException x)
    {
      if (persistent instanceof Persistent)
      {
        persistents.putAttribute((Persistent) persistent, persistentName, fieldName, value.toString());
      }
    }
  }

  /**
   * Set an attribute either on a Persistent object, a general bean object or
   * as a persistent attribute. Ignore any exceptions.
   *
   * @param persistents
   * @param persistent
   * @param persistentName
   * @param fieldName
   * @param value
   * @throws PersistenceException
   */
  private static void setAttributeOnDataObjectSafe(Logger logger, PersistentDescriptor persistents,
          Object persistent, String persistentName, String fieldName, Object value)
  {
    try
    {
      setAttributeOnDataObject(logger, persistents, persistent, persistentName, fieldName, value);
    }
    catch (PersistenceException ignored)
    {
    }
    catch (IllegalArgumentException ignored)
    {
    }
  }

  /**
   * Retrieve an attribute's valid values either from a Persistent object or a
   * general bean object.
   *
   * @param o The object
   * @param name The attribute name
   * @return The attribute's valid values
   * @throws PersistenceException If the attribute couldn't be retrieved
   */
  protected static Map getAttributeValidValuesFromDataObject(Object o, String name) throws PersistenceException
  {
    if (o instanceof Persistent)
    {
      return ((Persistent) o).getValidValues(name);
    }
    else
    {
      // TODO: Try to get valid values from the entity bean
      throw new PersistenceException();
    }
  }

  /**
   * Retrieve the default value of an attribute either from a Persistent
   * object or a general bean object.
   *
   * @param o The object
   * @param name The attribute name
   * @return The attribute value
   * @throws PersistenceException If the attribute couldn't be retrieved
   */
  protected static Object getAttributeDefaultValueFromDataObject(Object o, String name) throws PersistenceException
  {
    if (o instanceof Persistent)
    {
      return ((Persistent) o).getMetaData().getDefaultValue(name);
    }
    else
    {
      try
      {
        return PropertyUtils.getNestedProperty(o, name + "DefaultValue");
      }
      catch (IllegalAccessException x)
      {
      }
      catch (InvocationTargetException x)
      {
      }
      catch (NoSuchMethodException x)
      {
      }
    }

    return null;
  }

  /**
   * @param req
   * @param res
   * @param formular
   * @param persistents
   * @param commands
   * @throws ModelException
   * @throws PersistenceException
   */
  public static void createResponseElements(ModelRequest req, ModelResponse res, FormularDescriptor formular,
          PersistentDescriptor persistents, CommandDescriptor commands)
    throws ModelException, PersistenceException
  {
    createResponseElements(req, res, formular, persistents, commands, new ExpressionLanguageContext(req));
  }
}
TOP

Related Classes of de.iritgo.aktera.ui.form.FormTools

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.