Package de.iritgo.aktera.ui.listing

Source Code of de.iritgo.aktera.ui.listing.ListTools

/**
* 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.listing;


import de.iritgo.aktera.hibernate.StandardDao;
import de.iritgo.aktera.model.Command;
import de.iritgo.aktera.model.Input;
import de.iritgo.aktera.model.ModelException;
import de.iritgo.aktera.model.ModelRequest;
import de.iritgo.aktera.model.ModelResponse;
import de.iritgo.aktera.model.Output;
import de.iritgo.aktera.persist.PersistenceException;
import de.iritgo.aktera.persist.Persistent;
import de.iritgo.aktera.persist.PersistentMetaData;
import de.iritgo.aktera.spring.SpringTools;
import de.iritgo.aktera.tools.ModelTools;
import de.iritgo.aktera.ui.el.ExpressionLanguageContext;
import de.iritgo.aktera.ui.form.CommandInfo;
import de.iritgo.aktera.ui.form.PersistentDescriptor;
import de.iritgo.aktera.ui.form.QueryDescriptor;
import de.iritgo.aktera.ui.tools.UserTools;
import de.iritgo.simplelife.constants.SortOrder;
import de.iritgo.simplelife.math.NumberTools;
import de.iritgo.simplelife.string.StringTools;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.dbutils.DbUtils;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Properties;
import java.util.StringTokenizer;


/**
* Utility class that helps to create lists of persistent objects.
*/
public class ListTools
{
  /**
   * Create the listing response elements.
   *
   * @param request
   *            The model request.
   * @param response
   *            The model response.
   * @param listing
   *            The listing.
   * @param handler
   *            The listing handler.
   * @param filler
   *            The list filler.
   * @throws ModelException.
   */
  public static void createListing(ModelRequest request, ModelResponse response, ListingDescriptor listing,
          ListingHandler handler, ListContext context, ListFiller filler)
    throws ModelException, PersistenceException
  {
    if (filler == null && listing.getQuerySample() != null)
    {
      createListingWithSample(request, response, listing, handler, context);
    }
    else if (listing.getQuery() != null)
    {
      createListingWithQuery(request, response, listing, handler, context);
    }
    else if (filler == null && listing.getPersistents() != null && listing.getCondition() != null)
    {
      createListingWithCondition(request, response, listing, handler, context);
    }
    else
    {
      createListingWithFiller(request, response, listing, filler, context);
    }
  }

  /**
   * @param request
   * @param response
   * @param listing
   * @param handler
   * @param context
   * @throws ModelException
   */
  private static void createListingWithQuery(ModelRequest request, ModelResponse response, ListingDescriptor listing,
          ListingHandler handler, ListContext context) throws ModelException, PersistenceException
  {
    StandardDao standardDao = (StandardDao) SpringTools.getBean(StandardDao.ID);
    QueryDescriptor query = listing.getQuery();
    Properties queryParams = ExpressionLanguageContext.evalExpressionLanguageValue(context, request, query
            .getParams());
    int count = 0;

    if (query.getDaoName() != null)
    {
      try
      {
        java.util.List list = (java.util.List) MethodUtils.invokeExactMethod(SpringTools.getBean(query
                .getDaoName()), query.getDaoMethodName(), queryParams);

        count = list.size();
      }
      catch (NoSuchMethodException x)
      {
        throw new ModelException(x);
      }
      catch (IllegalAccessException x)
      {
        throw new ModelException(x);
      }
      catch (InvocationTargetException x)
      {
        throw new ModelException(x.getTargetException());
      }
    }
    else if (query.getCountName() != null)
    {
      count = (int) standardDao.countByNamedQuery(query.getCountName(), queryParams);
    }
    else if (query.getName() != null)
    {
      count = (int) standardDao.countByNamedFindQuery(query.getName(), queryParams);
    }
    else
    {
      if (query.getCountQuery() != null)
      {
        count = (int) standardDao.countByQuery(query.getCountQuery(), queryParams);
      }
      else
      {
        count = (int) standardDao.countByFindQuery(query.getQuery(), queryParams);
      }
    }

    int page = Math.max(listing.getPage(), 1);
    int maxPage = (Math.max(0, count - 1) / context.getResultsPerPage()) + 1;

    page = Math.min(page, maxPage);

    context.setPage(page);
    context.setFirstResult((page - 1) * context.getResultsPerPage());

    Output outList = createHeaderElements(request, response, listing, context);

    outList.setAttribute("pageCount", new Integer(maxPage));
    outList.setAttribute("page", String.valueOf(page));

    int firstResult = (page - 1) * context.getResultsPerPage();
    int maxResults = context.getResultsPerPage();
    java.util.List res = null;

    if (query.getDaoName() != null)
    {
      try
      {
        res = (java.util.List) MethodUtils.invokeExactMethod(SpringTools.getBean(query.getDaoName()), query
                .getDaoMethodName(), queryParams);
      }
      catch (NoSuchMethodException x)
      {
        throw new ModelException(x);
      }
      catch (IllegalAccessException x)
      {
        throw new ModelException(x);
      }
      catch (InvocationTargetException x)
      {
        throw new ModelException(x.getTargetException());
      }
    }
    else if (query.getName() != null)
    {
      res = standardDao.findByNamedQuery(query.getName(), queryParams, firstResult, maxResults, listing
              .getSortColumnName(), listing.getSortOrder());
    }
    else
    {
      res = standardDao.findByQuery(query.getQuery(), queryParams, firstResult, maxResults, listing
              .getSortColumnName(), listing.getSortOrder());
    }

    int rowNum = 1;

    for (Object row : res)
    {
      context.setIt(row);

      Output outItem = response.createOutput("item");

      outList.add(outItem);

      String idExpression = listing.getIdColumn();

      if (idExpression == null)
      {
        idExpression = "#{it.id}";
      }

      String id = ExpressionLanguageContext.evalExpressionLanguageValue(context, request, idExpression)
              .toString();

      try
      {
        outItem.setAttribute("id", id);
      }
      catch (Exception x)
      {
        throw new ModelException("Unable to retrieve id property in listing '" + listing.getId() + "' ("
                + x.getMessage() + ")");
      }

      outItem.setAttribute("odd", new Boolean(rowNum % 2 == 1));
      outItem.setAttribute("even", new Boolean(rowNum % 2 == 0));
      ++rowNum;

      int colNum = 0;

      for (ColumnDescriptor column : listing.getColumns())
      {
        Output outColumn = response.createOutput(String.valueOf(colNum++));
        outItem.add(outColumn);

        if ("custom".equals(column.getViewer()))
        {
          outColumn.setAttribute("viewer", "text");
          if (handler != null)
          {
            try
            {
              CellData cellData = handler.handleResult(request, response, listing, new BeanRowData(
                      listing, row), column);
              outColumn.setContent(cellData.getValue());
              outColumn.setAttribute("viewer", cellData.getViewer().toString());
              outColumn.setAttribute("bundle", cellData.getBundle());
            }
            catch (Exception x)
            {
              outColumn.setAttribute("viewer", "error");
              outColumn.setContent(x.getMessage());
            }
          }
          else
          {
            outColumn.setContent("");
          }
        }
        else
        {
          String valueExpression = column.getValue();
          if (valueExpression == null)
          {
            valueExpression = "#{it." + column.getName() + "}";
          }
          Object value = ExpressionLanguageContext.evalExpressionLanguageValue(context, request,
                  valueExpression);

          if ("combo".equals(column.getViewer()))
          {
            outColumn.setAttribute("viewer", column.getViewer());
            outColumn.setAttribute("bundle", column.getBundle());
            outColumn.setContent(! StringTools.isTrimEmpty(value) ? "opt" + value : "-");
          }
          else if ("message".equals(column.getViewer()))
          {
            outColumn.setAttribute("viewer", column.getViewer());
            outColumn.setAttribute("bundle", column.getBundle());

            String[] parts = value.toString().split("\\|");
            StringBuffer sb = new StringBuffer(parts[0]);

            for (int j = 1; j < parts.length; ++j)
            {
              if (parts[j].startsWith("#{") && parts[j].endsWith("}"))
              {
                sb.append("|"
                        + ExpressionLanguageContext.evalExpressionLanguageValue(context,
                                request, parts[j]));
              }
              else
              {
                sb.append("|" + parts[j]);
              }
            }

            outColumn.setContent(sb.toString());
          }
          else if (column.getViewer().startsWith("icon:"))
          {
            String viewer = column.getViewer();
            int slashPos = viewer.indexOf('|');
            String iconTrue = viewer.substring(5, slashPos > 0 ? slashPos : viewer.length());
            String iconFalse = slashPos > 0 ? viewer.substring(slashPos + 1, viewer.length()) : "blank";
            outColumn.setAttribute("viewer", "icon");
            outColumn.setContent(NumberTools.toBool(value, false) ? iconTrue : iconFalse);
          }
          else if (column.getViewer().startsWith("handler:"))
          {
            try
            {
              CellData cellData = (CellData) MethodUtils.invokeMethod(handler, column.getViewer()
                      .substring(8), value);
              outColumn.setContent(cellData.getValue());
              outColumn.setAttribute("viewer", cellData.getViewer() != null ? cellData.getViewer()
                      .toString() : "text");
              outColumn.setAttribute("bundle", cellData.getBundle() != null ? cellData.getBundle()
                      : listing.getBundle());
            }
            catch (InvocationTargetException x)
            {
              outColumn.setContent(x.getTargetException().toString());
            }
            catch (Exception x)
            {
              outColumn.setContent(x.toString());
            }
          }
          else if (column.getViewer().startsWith("js:"))
          {
            String[] params = column.getViewer().split(":");

            outColumn.setAttribute("viewer", "js");
            outColumn.setContent(params[1]);
            outColumn.setAttribute("name", column.getName());
            outColumn.setAttribute("id", id);
          }
          else if ("province".equals(column.getViewer()))
          {
            //          outColumn.setAttribute ("viewer", column.getViewer ());
            //          Object country = null;
            //          try
            //          {
            //            country = set.getObject (column.getAs () + "country");
            //          }
            //          catch (Exception ignored)
            //          {
            //          }
            //          Object value = set.getObject (column.getAs ());
            //          if (! StringTools.isTrimEmpty (value))
            //          {
            //            outColumn.setContent ((! StringTools.isTrimEmpty (country) ? country + "." : "") +
            //                    StringTools.trim (value));
            //          }
            //          else
            //          {
            //            outColumn.setContent ("");
            //          }
            outColumn.setContent("");
          }
          else
          {
            outColumn.setAttribute("viewer", column.getViewer());
            outColumn.setContent(! StringTools.isTrimEmpty(value) ? value : "");
          }
        }

        if (! column.isVisible())
        {
          outColumn.setAttribute("hide", "Y");
        }
      }

      CommandInfo viewCommand = listing.getCommand(ListingDescriptor.COMMAND_VIEW);

      if (viewCommand != null)
      {
        Command cmd = viewCommand.createCommand(request, response, context);

        cmd.setName("command");
        cmd.setParameter(listing.getKeyName(), id);
        cmd.setParameter("link", "Y");
        outItem.setAttribute("command", cmd);
      }
    }

    while (rowNum <= context.getResultsPerPage())
    {
      Output outItem = response.createOutput("item");

      outList.add(outItem);
      outItem.setAttribute("empty", Boolean.TRUE);
      ++rowNum;
    }

    createListingControls(request, response, listing, outList, 1, maxPage, page, context);
  }

  /**
   * Create the listing response elements.
   *
   * @param request
   *            The model request.
   * @param response
   *            The model response.
   * @param listing
   *            The listing.
   * @param handler
   *            The listing handler.
   * @param context
   *            TODO
   * @throws ModelException.
   */
  private static void createListingWithSample(ModelRequest request, ModelResponse response,
          ListingDescriptor listing, ListingHandler handler, ListContext context)
    throws ModelException, PersistenceException
  {
    Output outList = createHeaderElements(request, response, listing, context);

    int page = Math.max(listing.getPage(), 1);

    int maxPage = 1;

    if (! context.isDescribe())
    {
      int count = listing.getQuerySample().count();

      outList.setAttribute("count", new Integer(count));

      maxPage = (Math.max(0, count - 1) / context.getResultsPerPage()) + 1;
      page = Math.min(page, maxPage);

      context.setPage(page);
      context.setFirstResult((page - 1) * context.getResultsPerPage());

      outList.setAttribute("pageCount", new Integer(maxPage));
      outList.setAttribute("page", String.valueOf(page));

      listing.getQuerySample().setMaxRecords(context.getResultsPerPage());
      listing.getQuerySample().setOffsetRecord((page - 1) * context.getResultsPerPage());

      int num = 1;

      String sortColumn = listing.getSortColumnName();

      if (listing.getSortOrder() == SortOrder.DESCENDING)
      {
        sortColumn += " DESC";
      }

      Iterator result = listing.getQuerySample().query(sortColumn).iterator();

      while (result.hasNext())
      {
        Persistent persistent = (Persistent) result.next();

        Output outItem = response.createOutput("item");

        outList.add(outItem);

        outItem.setAttribute("id", persistent.getFieldString(listing.getIdField()));
        outItem.setAttribute("odd", new Boolean(num % 2 == 1));
        outItem.setAttribute("even", new Boolean(num % 2 == 0));

        handleResult(request, response, listing, outItem, persistent, context);

        ++num;
      }

      while (num < context.getResultsPerPage())
      {
        Output outItem = response.createOutput("item");

        outList.add(outItem);
        outItem.setAttribute("empty", Boolean.TRUE);
        ++num;
      }
    }

    createListingControls(request, response, listing, outList, 1, maxPage, page, context);
  }

  /**
   * Create the listing response elements.
   *
   * @param request
   *            The model request.
   * @param response
   *            The model response.
   * @param listing
   *            The listing.
   * @param handler
   *            The listing handler.
   * @param context
   *            TODO
   * @throws ModelException.
   */
  private static void createListingWithCondition(ModelRequest request, ModelResponse response,
          ListingDescriptor listing, ListingHandler handler, ListContext context)
    throws ModelException, PersistenceException
  {
    Output outList = createHeaderElements(request, response, listing, context);

    int count = 0;
    int page = Math.max(listing.getPage(), 1);
    int maxPage = 1;

    if (! context.isDescribe())
    {
      Connection connection = null;
      PreparedStatement stmt = null;
      ResultSet set = null;

      try
      {
        DataSourceComponent dataSource = (DataSourceComponent) request.getService(DataSourceComponent.ROLE,
                "keel-dbpool");

        connection = dataSource.getConnection();

        stmt = createPreparedStatement(listing, connection, createSqlSelectFields(listing) + " "
                + createSqlFrom(listing) + " " + createSqlWhere(request, listing));
        set = stmt.executeQuery();
        set.last();
        count = set.getRow();

        maxPage = (Math.max(0, count - 1) / context.getResultsPerPage()) + 1;
        page = Math.min(page, maxPage);

        context.setPage(page);
        context.setFirstResult((page - 1) * context.getResultsPerPage());

        outList.setAttribute("pageCount", new Integer(maxPage));
        outList.setAttribute("page", String.valueOf(page));

        set.beforeFirst();

        int num = 1;

        int offsetRecord = (page - 1) * context.getResultsPerPage();
        int recordCount = 0;
        int retrieveCount = 0;

        while (set.next())
        {
          recordCount++;
          retrieveCount++;

          if (retrieveCount < offsetRecord && offsetRecord > 0)
          {
            continue;
          }
          else if (retrieveCount == offsetRecord && offsetRecord > 0)
          {
            recordCount = 0;

            continue;
          }

          Output outItem = response.createOutput("item");

          outList.add(outItem);

          StringBuffer ids = null;

          if (listing.getNumIdColumns() == 1)
          {
            ids = new StringBuffer(set.getString("id") != null ? set.getString("id") : "0");
          }
          else
          {
            ids = new StringBuffer();

            int col = 1;

            for (Iterator i = listing.getIdColumns().iterator(); i.hasNext();)
            {
              ListingDescriptor.IdColumnInfo idInfo = (ListingDescriptor.IdColumnInfo) i.next();

              if (col > 1)
              {
                ids.append("|");
              }

              ids.append(idInfo.field + ":"
                      + (set.getString("id" + col) != null ? set.getString("id" + col) : "0"));
              ++col;
            }
          }

          outItem.setAttribute("id", ids.toString());
          outItem.setAttribute("odd", new Boolean(num % 2 == 1));
          outItem.setAttribute("even", new Boolean(num % 2 == 0));

          handleResult(request, response, listing, outItem, set, handler, context);

          ++num;

          if (recordCount == context.getResultsPerPage())
          {
            break;
          }
        }

        while (num <= context.getResultsPerPage())
        {
          Output outItem = response.createOutput("item");

          outList.add(outItem);
          outItem.setAttribute("empty", Boolean.TRUE);
          ++num;
        }
      }
      catch (SQLException x)
      {
        System.out.println("[ListTools] SQLError: " + x);
        throw new ModelException("[ListTools] SQLError " + x);
      }
      finally
      {
        DbUtils.closeQuietly(set);
        DbUtils.closeQuietly(stmt);
        DbUtils.closeQuietly(connection);
      }

      outList.setAttribute("count", new Integer(count));
    }

    createListingControls(request, response, listing, outList, 1, maxPage, page, context);
  }

  /**
   * @param request
   * @param response
   * @param listing
   * @param filler
   * @param context
   *            TODO
   * @throws ModelException
   */
  private static void createListingWithFiller(ModelRequest request, ModelResponse response,
          ListingDescriptor listing, ListFiller filler, ListContext context) throws ModelException
  {
    Output outList = createHeaderElements(request, response, listing, context);

    int page = Math.max(listing.getPage(), 1);
    int maxPage = 1;

    if (! context.isDescribe())
    {
      outList.setAttribute("count", new Integer(filler.getRowCount()));

      long totalCount = filler.getTotalRowCount();

      if (totalCount < 0)
      {
        totalCount = filler.getRowCount();
      }

      if (request.hasParameter(context.getListName() + "Page"))
      {
        page = Math.max(request.getParameterAsInt(context.getListName() + "Page", 1), 1);
      }

      maxPage = (int) ((Math.max(0, totalCount - 1) / context.getResultsPerPage()) + 1);
      page = Math.min(page, maxPage);

      context.setPage(page);
      context.setFirstResult((page - 1) * context.getResultsPerPage());

      outList.setAttribute("pageCount", new Integer(maxPage));
      outList.setAttribute("page", String.valueOf(page));

      int num = 1;
      int recordCount = 0;
      int retrieveCount = 0;
      int offsetRecord = (page - 1) * context.getResultsPerPage();

      while (filler.next())
      {
        recordCount++;

        if (filler.getTotalRowCount() < 0)
        {
          retrieveCount++;

          if (retrieveCount < offsetRecord && offsetRecord > 0)
          {
            continue;
          }
          else if (retrieveCount == offsetRecord && offsetRecord > 0)
          {
            recordCount = 0;

            continue;
          }
        }

        Output outItem = response.createOutput("item");

        outList.add(outItem);
        outItem.setAttribute("id", filler.getId());
        outItem.setAttribute("odd", new Boolean(num % 2 == 1));
        outItem.setAttribute("even", new Boolean(num % 2 == 0));

        int colNum = 0;

        for (Iterator j = listing.columnIterator(); j.hasNext();)
        {
          ColumnDescriptor column = (ColumnDescriptor) j.next();
          Output outColumn = response.createOutput(String.valueOf(colNum++));

          if (column.getViewer().startsWith("js:"))
          {
            String value = StringTools.trim(filler.getValue(column.getField()));
            outColumn.setContent(value);
            String[] params = column.getViewer().split(":");
            outColumn.setAttribute("viewer", "js");
            outColumn.setContent(params[1]);
            outColumn.setAttribute("name", column.getName());
            outColumn.setAttribute("id", filler.getId());
          }
          else if (column.getViewer().equals("message"))
          {
            String value = StringTools.trim(filler.getValue(column.getField()));
            outColumn.setAttribute("viewer", "message");
            int bundlePos = value.indexOf(":");
            if (bundlePos >= 0)
            {
              outColumn.setAttribute("bundle", value.substring(0, bundlePos));
            }
            else
            {
              outColumn.setAttribute("bundle", column.getBundle());
            }
            outColumn.setContent(value.substring(bundlePos + 1));
          }
          else
          {
            outColumn.setContent(filler.getValue(column.getField()));
            outColumn.setAttribute("viewer", column.getViewer());
          }

          if (! column.isVisible())
          {
            outColumn.setAttribute("hide", "Y");
          }

          outItem.add(outColumn);
        }

        CommandInfo viewCommand = listing.getCommand(ListingDescriptor.COMMAND_VIEW);

        if (viewCommand != null)
        {
          Command cmd = viewCommand.createCommand(request, response, context);

          cmd.setName("command");
          cmd.setParameter("id", filler.getId());
          cmd.setParameter("link", "Y");
          outItem.setAttribute("command", cmd);
        }

        ++num;

        if (recordCount == context.getResultsPerPage())
        {
          break;
        }
      }

      while (num <= context.getResultsPerPage())
      {
        Output outItem = response.createOutput("item");

        outList.add(outItem);
        outItem.setAttribute("empty", Boolean.TRUE);
        ++num;
      }
    }

    createListingControls(request, response, listing, outList, 1, maxPage, page, context);
  }

  /**
   * Handle one item of the query result.
   *
   * @param request
   *            The model request.
   * @param response
   *            The model response.
   * @param listing
   *            The listing.
   * @param outItem
   *            The generated output for the result item.
   * @param persistent
   *            The resulting persitent.
   */
  private static void handleResult(ModelRequest request, ModelResponse response, ListingDescriptor listing,
          Output outItem, Persistent persistent, ListContext context)
    throws PersistenceException, ModelException
  {
    int colNum = 0;

    for (Iterator i = listing.columnIterator(); i.hasNext();)
    {
      ColumnDescriptor column = (ColumnDescriptor) i.next();

      String fieldName = column.getName().substring(column.getName().lastIndexOf('.') + 1);

      Output outColumn = response.createOutput(String.valueOf(colNum++));

      outColumn.setContent(persistent.getField(fieldName));
      outColumn.setAttribute("viewer", column.getViewer());

      if (! column.isVisible())
      {
        outColumn.setAttribute("hide", "Y");
      }

      outItem.add(outColumn);
    }

    CommandInfo viewCommand = listing.getCommand(ListingDescriptor.COMMAND_VIEW);

    if (viewCommand != null)
    {
      Command cmd = viewCommand.createCommand(request, response, context);

      cmd.setName("command");
      cmd.setParameter(listing.getKeyName(), persistent.getFieldString(listing.getIdColumn()));
      cmd.setParameter("link", "Y");
      outItem.setAttribute("command", cmd);
    }
  }

  /**
   * Generate the SQL SELECT fields clause for a given listing.
   *
   * @param listing
   *            The listing for which to generate the statement
   * @return The SQL SELECT fields clause (SELECT a,b,c...)
   */
  private static String createSqlSelectFields(ListingDescriptor listing)
    throws ModelException, PersistenceException, SQLException
  {
    PersistentDescriptor persistents = listing.getPersistents();
    StringBuffer sql = new StringBuffer("SELECT ");
    PersistentMetaData idPersistentMeta = persistents.getMetaData(listing.getIdPersistent());

    if (idPersistentMeta == null)
    {
      throw new ModelException("ListTools: Unknown persistent specified for id column '" + listing.getIdColumn()
              + "'");
    }

    if (listing.getNumIdColumns() == 1)
    {
      sql.append(listing.getIdPersistent() + "." + idPersistentMeta.getDBFieldName(listing.getIdField())
              + " AS id");
    }
    else
    {
      int col = 1;

      for (Iterator i = listing.getIdColumns().iterator(); i.hasNext();)
      {
        ListingDescriptor.IdColumnInfo idInfo = (ListingDescriptor.IdColumnInfo) i.next();

        if (col > 1)
        {
          sql.append(", ");
        }

        sql
                .append(idInfo.persistent + "." + idPersistentMeta.getDBFieldName(idInfo.field)
                        + " AS id" + (col++));
      }
    }

    for (Iterator i = listing.columnIterator(); i.hasNext();)
    {
      ColumnDescriptor column = (ColumnDescriptor) i.next();

      if ("custom".equals(column.getViewer()) || column.getViewer().startsWith("js:"))
      {
        continue;
      }

      sql.append(", ");

      PersistentMetaData columnPersistentMeta = persistents.getMetaData(column.getPersistent());

      if (columnPersistentMeta == null)
      {
        throw new ModelException("ListTools: Unknown persistent specified for column '" + column.getName()
                + "'");
      }

      sql.append(column.getPersistent() + "." + columnPersistentMeta.getDBFieldName(column.getField()) + " AS "
              + column.getAs());
    }

    return sql.toString();
  }

  /**
   * Generate the SQL FROM clause for a given listing.
   *
   * @param listing
   *            The listing for which to generate the statement
   * @return The SQL FROM clause
   */
  private static String createSqlFrom(ListingDescriptor listing)
    throws ModelException, PersistenceException, SQLException
  {
    PersistentDescriptor persistents = listing.getPersistents();
    StringBuffer sql = new StringBuffer("");
    Iterator iKey = persistents.keyIterator();

    if (! iKey.hasNext())
    {
      throw new ModelException("No persistents defined for listing " + listing.getHeader());
    }

    String key = (String) iKey.next();
    PersistentMetaData persistentMeta = persistents.getMetaData(key);

    sql.append(" FROM " + persistentMeta.getTableName() + " AS " + key);

    for (; iKey.hasNext();)
    {
      key = (String) iKey.next();
      persistentMeta = persistents.getMetaData(key);
      sql.append(" LEFT JOIN " + persistentMeta.getTableName() + " AS " + key + " ON ");

      PersistentDescriptor.JoinInfo join = persistents.getJoin(key);

      if (join == null)
      {
        throw new ModelException("ListTools: No join info defined for persistent '" + key + "'");
      }

      PersistentMetaData persistentMetaJoin = persistents.getMetaData(join.getPersistent());

      sql.append(join.getPersistent() + "." + persistentMetaJoin.getDBFieldName(join.getKey()) + " = " + key
              + "." + persistentMeta.getDBFieldName(join.getMyKey()));

      if (join.getCondition() != null)
      {
        sql.append(" AND " + join.getCondition());
      }
    }

    return sql.toString();
  }

  /**
   * Generate the SQL WHERE clause for a given listing.
   *
   * @param request
   *            The model request
   * @param listing
   *            The listing for which to generate the statement
   * @return The SQL WHERE clause
   */
  private static String createSqlWhere(ModelRequest request, ListingDescriptor listing) throws PersistenceException
  {
    PersistentDescriptor persistents = listing.getPersistents();
    PersistentMetaData idPersistentMeta = persistents.getMetaData(listing.getIdPersistent());

    StringBuffer condition = new StringBuffer();

    if (! StringTools.isTrimEmpty(listing.getCondition()))
    {
      condition.append(" WHERE " + listing.getCondition());
    }

    if (listing.getSortColumns().size() > 0)
    {
      condition.append(" ORDER BY ");
    }

    for (Iterator i = listing.sortColumnIterator(); i.hasNext();)
    {
      ColumnDescriptor column = (ColumnDescriptor) i.next();

      condition.append(column.getName() + (column.getSort() == SortOrder.DESCENDING ? " DESC" : " ASC"));

      if (i.hasNext())
      {
        condition.append(", ");
      }
    }

    StringBuffer sqlCondition = new StringBuffer();

    for (StringTokenizer st = new StringTokenizer(condition.toString()); st.hasMoreTokens();)
    {
      String token = st.nextToken();
      int dotIndex = token.indexOf('.');

      if (dotIndex != - 1)
      {
        String persistent = token.substring(0, dotIndex);
        String field = token.substring(dotIndex + 1);
        PersistentMetaData meta = persistents.getMetaData(persistent);

        if (meta != null)
        {
          sqlCondition.append(" " + persistent + "." + meta.getDBFieldName(field) + " ");
        }
      }
      else if (token.startsWith("#") || (token.startsWith("'#") && token.endsWith("'")))
      {
        String paramName = null;
        String quote = token.startsWith("'") ? "'" : "";

        if (token.startsWith("'"))
        {
          paramName = token.substring(2, token.length() - 1);
        }
        else
        {
          paramName = token.substring(1);
        }

        String param = request.getParameterAsString(paramName);

        if (paramName.equals("id") && request.getParameter("prevId") != null)
        {
          param = request.getParameterAsString("prevId");
        }

        if (StringTools.isTrimEmpty(param))
        {
          param = "0";
        }

        sqlCondition.append(" " + quote + param + quote + " ");
      }
      else if (token.startsWith("$") || token.startsWith("~") || (token.startsWith("'$") && token.endsWith("'"))
              || (token.startsWith("'~") && token.endsWith("'")))
      {
        String var = null;
        String quote = token.startsWith("'") ? "'" : "";
        boolean like = token.startsWith("~") || token.startsWith("'~");

        if (token.startsWith("'"))
        {
          var = token.substring(2, token.length() - 1).toLowerCase();
        }
        else
        {
          var = token.substring(1).toLowerCase();
        }

        String value = null;

        if ("search".compareToIgnoreCase(var) == 0)
        {
          value = request.getParameterAsString(listing.getId(request) + "Search");
        }
        else if ("searchcategory".compareToIgnoreCase(var) == 0)
        {
          value = listing.getCategory();
        }
        else if ("userid".compareToIgnoreCase(var) == 0)
        {
          value = UserTools.getCurrentUserId(request).toString();
        }

        value = StringTools.trim(value);
        sqlCondition.append(" " + quote);

        if (like)
        {
          sqlCondition.append("%" + (StringTools.isEmpty(value) ? "" : value) + "%");
        }
        else
        {
          sqlCondition.append(StringTools.isEmpty(value) ? "0" : value);
        }

        sqlCondition.append(quote + " ");
      }
      else if ("like".compareToIgnoreCase(token) == 0)
      {
        sqlCondition.append(idPersistentMeta.getDatabaseType().getLikeStatement());
      }
      else
      {
        sqlCondition.append(" " + token + " ");
      }
    }

    return sqlCondition.toString();
  }

  /**
   * Create a prepared statement from the given SQL query.
   *
   * @param listing
   *            The listing for which to generate the statement
   * @param connection
   *            The JDBC connection
   * @param sql
   *            The SQL statement
   * @return The prepared statement
   * @throws SQLException
   *             In case of an SQL error
   */
  private static PreparedStatement createPreparedStatement(ListingDescriptor listing, Connection connection,
          String sql) throws PersistenceException, SQLException
  {
    PreparedStatement stmt = connection.prepareStatement(sql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE,
            ResultSet.CONCUR_READ_ONLY);

    if (listing.getCondition() != null && listing.getConditionParams() != null)
    {
      for (int i = 0; i < listing.getConditionParams().length; ++i)
      {
        stmt.setObject(i + 1, listing.getConditionParams()[i]);
      }
    }

    return stmt;
  }

  /**
   * Handle one item of the query result.
   *
   * @param request
   *            The model request.
   * @param response
   *            The model response.
   * @param listing
   *            The listing.
   * @param outItem
   *            The generated output for the result item.
   * @param set
   *            The result set.
   * @param handler
   *            The listing handler.
   */
  private static void handleResult(ModelRequest request, ModelResponse response, ListingDescriptor listing,
          Output outItem, ResultSet set, ListingHandler handler, ListContext context)
    throws PersistenceException, ModelException, SQLException
  {
    String ids = "";

    if (listing.getNumIdColumns() == 1)
    {
      ids = set.getString("id");
    }
    else
    {
      StringBuffer idsBuf = new StringBuffer();

      int col = 1;

      for (Iterator i = listing.getIdColumns().iterator(); i.hasNext();)
      {
        ListingDescriptor.IdColumnInfo idInfo = (ListingDescriptor.IdColumnInfo) i.next();

        if (col > 1)
        {
          idsBuf.append("|");
        }

        idsBuf.append(idInfo.field + ":"
                + (set.getString("id" + col) != null ? set.getString("id" + col) : "0"));
        ++col;
      }

      ids = idsBuf.toString();
    }

    int colNum = 0;

    for (Iterator i = listing.columnIterator(); i.hasNext();)
    {
      ColumnDescriptor column = (ColumnDescriptor) i.next();

      Output outColumn = response.createOutput(String.valueOf(colNum++));

      if ("custom".equals(column.getViewer()))
      {
        outColumn.setAttribute("viewer", "text");

        if (handler != null)
        {
          CellData cellData = handler.handleResult(request, response, listing, new SqlRowData(listing, set),
                  column);

          outColumn.setContent(cellData.getValue());
          outColumn.setAttribute("viewer", cellData.getViewer().toString());
          outColumn.setAttribute("bundle", cellData.getBundle());
        }
        else
        {
          outColumn.setContent("");
        }
      }
      else if ("combo".equals(column.getViewer()))
      {
        Object value = set.getObject(column.getAs());

        outColumn.setAttribute("viewer", column.getViewer());
        outColumn.setAttribute("bundle", column.getBundle());
        outColumn.setContent(! StringTools.isTrimEmpty(value) ? "opt" + value : "-");
      }
      else if ("message".equals(column.getViewer()))
      {
        outColumn.setAttribute("viewer", column.getViewer());

        Object value = set.getObject(column.getAs());

        outColumn.setAttribute("bundle", column.getBundle());

        String[] parts = value.toString().split("\\|");
        StringBuffer sb = new StringBuffer(parts[0]);

        for (int j = 1; j < parts.length; ++j)
        {
          if (parts[j].startsWith("?"))
          {
            sb.append("|" + set.getString(parts[j].substring(1).replace('.', '_')));
          }
          else
          {
            sb.append("|" + parts[j]);
          }
        }

        outColumn.setContent(sb.toString());
      }
      else if (column.getViewer().startsWith("icon:"))
      {
        Object value = set.getObject(column.getAs());
        String viewer = column.getViewer();
        int slashPos = viewer.indexOf('|');
        String iconTrue = viewer.substring(5, slashPos > 0 ? slashPos : viewer.length());
        String iconFalse = slashPos > 0 ? viewer.substring(slashPos + 1, viewer.length()) : "blank";
        outColumn.setAttribute("viewer", "icon");
        outColumn.setContent(NumberTools.toBool(value, false) ? iconTrue : iconFalse);
      }
      else if (column.getViewer().startsWith("handler:"))
      {
        Object value = set.getObject(column.getAs());

        outColumn.setAttribute("viewer", "text");

        try
        {
          Class cellHandler = Class.forName(column.getViewer().substring(8));
          String cellRes = cellHandler.getMethod("format", new Class[]
          {
            Object.class
          }).invoke(null, value).toString();

          outColumn.setContent(cellRes);
        }
        catch (InvocationTargetException x)
        {
          outColumn.setContent(x.getTargetException().toString());
        }
        catch (Exception x)
        {
          outColumn.setContent(x.toString());
        }
      }
      else if (column.getViewer().startsWith("js:"))
      {
        String[] params = column.getViewer().split(":");

        outColumn.setAttribute("viewer", "js");
        outColumn.setContent(params[1]);
        outColumn.setAttribute("name", column.getName());
        outColumn.setAttribute("id", ids);
      }
      else if ("province".equals(column.getViewer()))
      {
        outColumn.setAttribute("viewer", column.getViewer());

        Object country = null;

        try
        {
          country = set.getObject(column.getAs() + "country");
        }
        catch (Exception ignored)
        {
        }

        Object value = set.getObject(column.getAs());

        if (! StringTools.isTrimEmpty(value))
        {
          outColumn.setContent((! StringTools.isTrimEmpty(country) ? country + "." : "")
                  + StringTools.trim(value));
        }
        else
        {
          outColumn.setContent("");
        }
      }
      else
      {
        outColumn.setAttribute("viewer", column.getViewer());

        Object value = set.getObject(column.getAs());

        outColumn.setContent(! StringTools.isTrimEmpty(value) ? value : "");
      }

      if (! column.isVisible())
      {
        outColumn.setAttribute("hide", "Y");
      }

      outItem.add(outColumn);
    }

    CommandInfo viewCommand = listing.getCommand(ListingDescriptor.COMMAND_VIEW);

    if (viewCommand != null)
    {
      Command cmd = viewCommand.createCommand(request, response, context);

      cmd.setName("command");
      cmd.setParameter(listing.getKeyName(), ids);
      cmd.setParameter("link", "Y");
      outItem.setAttribute("command", cmd);
    }
  }

  /**
   * Create the page navigation controls.
   *
   * @param request
   *            The model request.
   * @param response
   *            The model response.
   * @param outList
   *            The list output element.
   * @param name
   *            The command name.
   * @throws ModelException.
   */
  private static void createListingControls(ModelRequest request, ModelResponse response, ListingDescriptor listing,
          Output outList, int minPage, int maxPage, int currentPage, ListContext context)
    throws ModelException
  {
    outList.setAttribute("keyName", listing.getKeyName());
    outList.setAttribute("headerTitle", listing.getHeader());
    outList.setAttribute("bundle", listing.getBundle());
    if (listing.getTitle() != null)
    {
      outList.setAttribute("title", listing.getTitle());
      outList.setAttribute("titleBundle", listing.getTitleBundle() != null ? listing.getTitleBundle() : listing
              .getBundle());
    }
    if (listing.getIcon() != null)
    {
      outList.setAttribute("icon", listing.getIcon());
    }
    if (listing.isEmbedded())
    {
      outList.setAttribute("embedded", "Y");
    }
    outList.setAttribute("commandStyle", listing.getCommandStyle());

    CommandInfo viewCommand = listing.getCommand(ListingDescriptor.COMMAND_VIEW);
    if (viewCommand != null && viewCommand.checkPermission(request))
    {
      Command cmd = viewCommand.createCommand(request, response, context);

      cmd.setName(outList.getName() + "CmdEdit");
      cmd.setLabel(viewCommand.getLabel() != null ? viewCommand.getLabel() : "edit");
      outList.setAttribute("cmdEdit", cmd);
    }

    CommandInfo cmdNew = listing.getCommand(ListingDescriptor.COMMAND_NEW);
    if (cmdNew != null && cmdNew.isVisible() && cmdNew.checkPermission(request))
    {
      Command cmd = cmdNew.createCommand(request, response, context);

      cmd.setName(outList.getName() + "CmdNew");
      outList.setAttribute("cmdNew", cmd);
    }

    String outListName = outList.getName();
    if (currentPage > 1)
    {
      Command cmdPageStart = createPageCommand(request, response, listing, "cmdPageStart", new String[]
      {
        "~listSort"
      });
      cmdPageStart.setParameter(outListName + "Page", String.valueOf(minPage));
      cmdPageStart.setLabel("$start");
      outList.setAttribute("cmdPageStart", cmdPageStart);

      Command cmdPageBack = createPageCommand(request, response, listing, "cmdPageBack", new String[]
      {
        "~listSort"
      });
      cmdPageBack.setParameter(outListName + "Page", String.valueOf(currentPage - 1));
      cmdPageBack.setLabel("$back");
      outList.setAttribute("cmdPageBack", cmdPageBack);

      Output outPrevPages = response.createOutput("prevPages");
      outList.setAttribute("prevPages", outPrevPages);
      int firstPrevPage = Math.max(minPage, currentPage - context.getNumPrevPages());
      for (int i = currentPage - 1; i >= firstPrevPage; --i)
      {
        Command cmdPage = createPageCommand(request, response, listing, "cmdPage", new String[]
        {
          "~listSort"
        });
        cmdPage.setParameter(outListName + "Page", String.valueOf(currentPage - i - 1 + firstPrevPage));
        cmdPage.setLabel(String.valueOf(currentPage - i - 1 + firstPrevPage));
        outPrevPages.add(cmdPage);
      }
    }

    if (currentPage < maxPage)
    {
      Command cmdPageEnd = createPageCommand(request, response, listing, "cmdPageEnd", new String[]
      {
        "~listSort"
      });
      cmdPageEnd.setParameter(outListName + "Page", String.valueOf(maxPage));
      cmdPageEnd.setLabel("$end");
      outList.setAttribute("cmdPageEnd", cmdPageEnd);

      Command cmdPageNext = createPageCommand(request, response, listing, "cmdPageNext", new String[]
      {
        "~listSort"
      });
      cmdPageNext.setParameter(outListName + "Page", String.valueOf(currentPage + 1));
      cmdPageNext.setLabel("$next");
      outList.setAttribute("cmdPageNext", cmdPageNext);

      Output outNextPages = response.createOutput("nextPages");
      outList.setAttribute("nextPages", outNextPages);
      int lastNextPage = Math.min(maxPage, currentPage + context.getNumNextPages());
      for (int i = currentPage + 1; i <= lastNextPage; ++i)
      {
        Command cmdPage = createPageCommand(request, response, listing, "page", new String[]
        {
          "~listSort"
        });
        cmdPage.setParameter(outListName + "Page", String.valueOf(i));
        cmdPage.setLabel(String.valueOf(i));
        outNextPages.add(cmdPage);
      }
    }

    if (listing.getListCommands() != null)
    {
      Output outCommands = response.createOutput("commands");
      outList.setAttribute("commands", outCommands);
      for (Iterator i = listing.getListCommands().iterator(); i.hasNext();)
      {
        CommandInfo descriptor = (CommandInfo) i.next();
        Command command = descriptor.createCommand(request, response, context);
        outCommands.add(command);
      }
    }

    if (listing.getItemCommands() != null)
    {
      Output outItemCommands = response.createOutput("itemCommands");
      CommandInfo viewCmd = listing.getCommand(ListingDescriptor.COMMAND_VIEW);
      if (viewCmd != null && viewCmd.checkPermission(request))
      {
        Command cmd = viewCmd.createCommand(request, response, context);
        outItemCommands.add(cmd);
      }
      outItemCommands.setAttribute("label", listing.getItemCommands().getLabel());
      outList.setAttribute("itemCommands", outItemCommands);
      for (Iterator i = listing.getItemCommands().iterator(); i.hasNext();)
      {
        CommandInfo descriptor = (CommandInfo) i.next();
        if (viewCmd == null || ! descriptor.getName().equals(viewCmd.getName()))
        {
          Command command = descriptor.createCommand(request, response, context);
          outItemCommands.add(command);
        }
      }

      Command cmdExecute;
      if (listing.getCommand(ListingDescriptor.COMMAND_EXECUTE) == null)
      {
        if (listing.isNg())
        {
          cmdExecute = response.createCommand(null);
          cmdExecute.setBean("de.iritgo.aktera.ui.ExecuteListItemCommand");
        }
        else
        {
          cmdExecute = response.createCommand("aktera.tools.execute-listitem-command");
        }
        cmdExecute.setName(outListName + "CmdExecute");
        cmdExecute.setLabel("execute");
      }
      else
      {
        cmdExecute = listing.getCommand(ListingDescriptor.COMMAND_EXECUTE).createCommand(request, response,
                "_lep", context);
      }

      outList.setAttribute("cmdExecute", cmdExecute);
      cmdExecute.setParameter("_lm", listing.getListModel() != null ? listing.getListModel() : ModelTools
              .getPreviousModel(request));
      for (Iterator i = request.getParameters().keySet().iterator(); i.hasNext();)
      {
        String key = (String) i.next();
        if ("model".equals(key) || "orig-model".equals(key) || key.startsWith("_lp"))
        {
          continue;
        }
        cmdExecute.setParameter("_lp" + key, request.getParameter(key));
      }

      for (Iterator i = listing.getItemCommands().iterator(); i.hasNext();)
      {
        CommandInfo descriptor = (CommandInfo) i.next();
        descriptor.setParameters(request, cmdExecute, "_lp", context);
      }
    }

    CommandInfo cmdSearch = listing.getCommand(ListingDescriptor.COMMAND_SEARCH);
    if (cmdSearch != null)
    {
      String searchInputName = outListName + "Search";
      Input input = response.createInput(searchInputName);
      input.setLabel("search");
      input.setDefaultValue(request.getParameterAsString(searchInputName));
      response.add(input);
      if (listing.getCategories() != null)
      {
        input = response.createInput(searchInputName + "Category");
        input.setDefaultValue(listing.getCategory());
        input.setValidValues(listing.getCategories());
        response.add(input);
      }
      Command cmd = cmdSearch.createCommand(request, response, context);
      cmd.setName(outListName + "CmdSearch");
      outList.setAttribute("cmdSearch", cmd);
    }

    CommandInfo cmdBack = listing.getCommand(ListingDescriptor.COMMAND_BACK);
    if (cmdBack != null)
    {
      Command cmd = cmdBack.createCommand(request, response, context);
      outList.setAttribute("cmdBack", cmd);
    }
  }

  /**
   * Create a page navigation command.
   *
   * @param request
   *            The model request.
   * @param response
   *            The model response.
   * @param listing
   *            The listing.
   * @param name
   *            The command name.
   * @return The new command.
   * @throws ModelException.
   */
  private static Command createPageCommand(ModelRequest request, ModelResponse response, ListingDescriptor listing,
          String name) throws ModelException
  {
    return createPageCommand(request, response, listing, name, null);
  }

  /**
   * Create a page navigation command.
   *
   * @param request
   *            The model request.
   * @param response
   *            The model response.
   * @param listing
   *            The listing.
   * @param name
   *            The command name.
   * @return The new command.
   * @throws ModelException.
   */
  private static Command createPageCommand(ModelRequest request, ModelResponse response, ListingDescriptor listing,
          String name, String[] ommitPrevParameters) throws ModelException
  {
    Command cmd = ModelTools.createPreviousModelCommand(request, response, listing.getListModel(),
            ommitPrevParameters);
    cmd.setName(name);
    cmd.getParameters().remove(listing.getId() + "Sort");
    return cmd;
  }

  /**
   * Create the table header response elements.
   *
   * @param req
   *            The model request.
   * @param res
   *            The model response.
   * @param listing
   *            The listing.
   * @param outList
   *            The list response element.
   * @return The listing output element.
   * @throws ModelException.
   */
  private static Output createHeaderElements(ModelRequest req, ModelResponse res, ListingDescriptor listing,
          ListContext context) throws ModelException
  {
    Output outList = res.createOutput(context.getListName());

    res.add(outList);

    if (listing.isSelectable())
    {
      outList.setAttribute("selectable", "Y");
    }
    outList.setAttribute("columnCount", new Integer(listing.getVisibleColumnCount()
            + (listing.getItemCommands() != null ? 1 : 0)));

    Output outHeader = res.createOutput("header");

    outList.setAttribute("header", outHeader);

    int colNum = 0;

    for (Iterator i = listing.columnIterator(); i.hasNext();)
    {
      ColumnDescriptor column = (ColumnDescriptor) i.next();

      Output outColumn = res.createOutput(String.valueOf(colNum++));

      outColumn.setContent(column.getAs());
      outColumn.setAttribute("label", column.getLabel());
      outColumn.setAttribute("bundle", column.getBundle() != null ? column.getBundle() : listing.getBundle());
      outColumn.setAttribute("width", new Integer(column.getWidth()));

      if (column.getSort() != SortOrder.NONE)
      {
        outColumn.setAttribute("sort", column.getSort() == SortOrder.ASCENDING ? "U" : "D");
      }

      if (! column.isVisible())
      {
        outColumn.setAttribute("hide", "Y");
      }

      if (column.isSortable() && ! "custom".equals(column.getViewer()) && ! column.getViewer().startsWith("js:"))
      {
        Command sortCommand = createPageCommand(req, res, listing, "sort" + colNum);

        sortCommand.setParameter(context.getListName() + "Sort", column.getName());
        outColumn.setAttribute("sortCommand", sortCommand);
      }

      outHeader.add(outColumn);
    }

    return outList;
  }
}
TOP

Related Classes of de.iritgo.aktera.ui.listing.ListTools

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.