Listing of Source cgi/DynamicTableCGI.java
package se.entra.phantom.server.http; 

import se.entra.phantom.server.*;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;
import org.w3c.dom.Element;

/**
 * HtmlDynamicTable
 */
public class DynamicTableCGI implements IncludeCgiPrintInterface
{
  ///
  /// Variables.
  ///

  /**
   * Listbox column data for current row.
   */
  private String colData[];

  /**
   * Application action string for hyperlinks.
   */
  private String appAction;

  /**
   * Current count,
   * can be used for Image reference separation per row.
   */
  private int currCount;

  /**
   * Current runtime file name, templates are loaded from runtime base directory.
   */
  private String runtimeFile;

  /**
   * Output stream.
   */
  private PrintWriter outStream;

  /**
   * HTTP Session.
   */
  private HttpSession httpSession;

  /**
   * HTTP Resource.
   */
  private HtmlResource htmlResource;

  /**
   * VirtualSessionManager. 
   */
  private VirtualSessionManager vsm;

  /**
   * listbox ID.
   */
  private String listBoxID;

  /**
   * List box.
   */
  protected VirtualCListBox vlist;

  /**
   * List box count.
   */
  protected int listCount;

  /**
   * Perform action is main method.
   */
  @Override
  public void performAction(HttpSession httpSession,HttpResource resource,Element element,PrintWriter out) throws IOException
    {
    this.outStream    = out;
    this.httpSession  = httpSession;
    if (resource instanceof HtmlResource)
      this.htmlResource = (HtmlResource)resource;
    this.vsm=httpSession.clientSession.getVirtualSessionManager();

    performAction(httpSession,element);
    }

  /**
   * Dynamic version of performAction.
   */ 
  public void performAction(HttpSession httpSession,Element element)
    {
    // Get listbox ID from parameter or global variable or use "LIST" as default.
    String listBoxID=element.getAttribute("listid");
    if (listBoxID == null || listBoxID.length() == 0)
      {
      listBoxID = vsm.globVarGet("HTMLDYNAMICTABLE_LISTID");
      if (listBoxID == null || listBoxID.length() == 0)
        listBoxID = "LIST";
      }

    // Check parameter template column (default=0).
    int templateColumn=0; // Default.
    try
      {
      templateColumn=Integer.parseInt(element.getAttribute("listboxcolumn"));
      }
    catch (Exception e){}

    // Initiate with listbox ID.
    if (!init(listBoxID))
      return;

    // Create template Vector.
    Hashtable<String,String> tList=new Hashtable<String,String>();

    // Loop through all listbox rows.
    for (int i=0; i<listCount; ++i)
      {
      // Get listbox cells and convert into HTML text.
      String cells[]=vlist.getLineCells(i);
      convCells(cells);

      // Name of global variable containing template is default first column in listbox.
      String templateVar=getColData(templateColumn);

      // First check parameter, then global variable.
      String templateFile=element.getAttribute(templateVar);
      if (templateFile == null || templateFile.length() == 0)
        templateFile = vsm.globVarGet(templateVar);

      // List column MUST contain template.
      if (templateFile == null || templateFile.length() == 0)
        {
        println("Template: "+templateVar+" on row "+i+" missing.");
        return;
        }

      // Check Hastable for template.
      String templContent=tList.get(templateVar);
      if (templContent == null)
        {
        // Template not found, create new template from file.
        templContent=getTemplateFromFile(templateFile);
        if (templContent != null)
          tList.put(templateVar,templContent);
        }

      // If any template content, create row from template and listbox.
      if (templContent != null)
        {
        String row=getRowFromTemplate(templContent,i);
        println(row);
        }
      }
    }

  /**
   * Initiate method.
   */ 
  protected boolean init(String listBoxID)
    {
    // Get current runtime file.
    VirtualRuntime runtime=httpSession.clientSession.getVirtualSessionManager().getCurrentRuntime();
    runtimeFile=runtime.fileName;

    // Get specified listbox.
    this.listBoxID = listBoxID;
    VirtualInterface vc=httpSession.getControl(listBoxID);
    if (!(vc instanceof VirtualCListBox))
      {
      println("ListBox "+listBoxID+" not found in panel");
      return false;
      }
    vlist=(VirtualCListBox)vc;

    // Get number of lines in listbox.
    listCount=vlist.getTotLines();

    // Get application action for hyperlinks.
    appAction=httpSession.getApplicationAction();

    return true;
    }

  /**
   * Print line (String+(cr)(lf)) to output stream.
   */
  public void println(String printString)
    {
    outStream.println(printString);
    }

  /**
   * Convert dynamic data (from panel) to internet characters (&amp; ,..).
   */
  public void convCells(String convCells[])
    {
    int numCells=convCells.length;
    colData = new String[numCells];
    for (int i=0; i<numCells; ++i)
      colData[i]=InternetCharacterConversion.stringConvertToHTMLString(convCells[i].trim());
    }

  /**
   * Get cell data for one listbox column.
   */
  protected String getColData(int col)
    {
    if (col<0 || col>colData.length)
      return "";

    return colData[col];
    }

  /**
   * Get HTML hyperlink start info.
   */
  private String getLink(String action,int rowNum)
    {
    String submit=HtmlSubmitString.create(HtmlSubmitString.TYPE_LISTSEL,listBoxID,rowNum,0,action);
    String link="<A href=\""+appAction+"+"+submit+"\"";
    return link;
    }

  /**
   * Get define value from template file.
   * ex: @*DEFINE;
   */
  protected String getDefine(String define,int rowNum)
    {
    // If starting with _ get data from listbox column.
    if (define.startsWith("_"))
      {
      int colNum=Integer.parseInt(define.substring(1))-1;
      return getColData(colNum);
      }

    // If starts with LINK_, get ACTION and create link.
    if (define.startsWith("LINK_"))
      return getLink(define.substring(5),rowNum);

    // If starts with @, it's a NetPhantom variable.
    if (define.startsWith("@"))
      return HtmlVariable.getTextData(httpSession,htmlResource,define);

    // Increase count and return.
    if (define.equalsIgnoreCase("NEXTCOUNT"))
      return Integer.toString(++currCount);

    // Get current count.
    if (define.equalsIgnoreCase("COUNT"))
      return Integer.toString(currCount);

    // Define not found.
    return "NOTFOUND:"+define;
    }

  /**
   * Parse template and replace definitions with dynamic data.
   */
  protected String getRowFromTemplate(String template,int rowNum)
    {
    // Create buffer for HTML row data.
    int len=template.length();
    StringBuilder rowData=new StringBuilder();

    // Loop through template.
    for (int j=0; j<len;)
      {
      // If define found, resolve it into new buffer.
      int pos=template.indexOf("@*",j);
      if (pos == -1)
        {
        rowData.append(template.substring(j));
        break;
        }
      else
        {
        // Check for double @
        if (pos == 0 || template.charAt(pos-1) != '@')
          {
          // Else copy template data to new buffer.
          rowData.append(template.substring(j,pos));
          j=pos+2;
          int endPos = template.indexOf(";",j);
          if (endPos != -1)
            {
            String define = template.substring(j,endPos);
            rowData.append(getDefine(define,rowNum));

            j=endPos+1;
            }
          }
        }
      }

    // Return buffer data.
    return rowData.toString();
    }

  /**
   * Get HTML template file data.
   */ 
  protected String getTemplateFromFile(String fileName)
    {
    try
      {
      fileName=PhantomFile.getFileNameFromAnother(fileName,runtimeFile);
      String data=new String(PhantomFile.loadFile(fileName));
      return data;
      }
    catch (Exception e) {}
    return "Can't read template file: "+fileName;
    }
}