/*
* The original code created by Software AG
* is part of Software AG Tamino X-Application and
* Copyright (c) 2001 Software AG, All Rights Reserved.
*
* Software AG highly appreciate the efforts and contributions of
* the Source Partners. For more information, please see
* http://www.softwareag.com/developer/x-application/guide.htm
*
* You can redistribute this software and/or modify it under the terms of
* the Software AG Source Add-On Software License
* http://www.softwareag.com/developer/x-application/license.htm
*/
package com.softwareag.xtools.xapplication.jsptaglib;
import java.io.IOException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyContent;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.Map;
import java.util.Comparator;
import java.util.Iterator;
import com.softwareag.xtools.xapplication.businessdocument.QueryContainer;
import com.softwareag.xtools.xapplication.businessdocument.QueryFilter;
import com.softwareag.xtools.xapplication.businessdocument.BusinessDocument;
import com.softwareag.xtools.xapplication.businessdocument.InvalidXPathException;
import com.softwareag.xtools.xapplication.businessdocument.BusinessDocumentStateException;
import com.softwareag.xtools.xapplication.store.StoreException;
import com.softwareag.xtools.xapplication.jsptaglib.util.HtmlStringParser;
/**
** Defines the superclass for display or edit tags. It can be instantiated by
** itself but supplies the body for processing the content in the body and
** implements the required JSP callback methods. All subclasses must implement
** processField which then works on the content of the display field.
**
** Superclass for fields. It is contains the common functions for display and
** edit fields
** @see com.softwareag.xtools.xapplication.jsptaglib.DisplayTag
** @see com.softwareag.xtools.xapplication.jsptaglib.EditTag
**
** @author Software AG Tamino X-Application Developers
** @version $Revision: 1.29 $
**/
public class FillSelectTag extends XBodyTag {
private String moduleId=null;
private String schema=null;
private String filter=null;
private String value=null;
private String text=null;
private String distinct=null;
private String sort=null;
private HashMap hm=null;
private TreeMap tm=null;
private Comparator comparator = new Comparator() {
public int compare(Object o1, Object o2) {
return (((String) hm.get(o1)).compareTo(hm.get(o2)));
}
};
/**
** sets the module value
**
** @param moduleId value of the module attribute
** @deprecated
**/
public void setModule(String moduleId) {
this.moduleId=moduleId;
}
/**
** sets the schema property
**
** @param schema String schema name
**/
public void setSchema(String schema) {
this.schema=schema;
}
/**
** sets the filter property
**
** @param filter String filter for fill select
**/
public void setFilter(String filter) {
this.filter=filter;
}
/**
** sets the value property
**
** @param value String xpath for value property
**/
public void setValue(String value) {
this.value=value;
}
/**
** sets the text property
**
** @param text String xpath for text property
**/
public void setText(String text) {
this.text=text;
}
/**
** set the distinct property
**
** @param distinct String value for distinct property
**/
public void setDistinct(String distinct) {
this.distinct=distinct;
}
/**
** set the sort property
**
** @param sort String value for sort property
**/
public void setSort(String sort) {
this.sort=sort;
}
/**
** Standard method of JSP tags that is called when the start tag is processed.
**
** @return return-code according to JSP spec
** @exception JspException standard exception
**/
public int doStartTagCore() throws JspException {
return EVAL_BODY_TAG;
}
/**
** Standard method of JSP tags that is called after the body is completly read.
**
** @return int return-code according to JSP spec
**
** @throws JspException standard exception
** @throws JspTagException standard exception
** @throws IOException to indicate IO problem
**/
public int doAfterBodyCore() throws JspTagException, JspException, IOException {
processField();
return SKIP_BODY;
}
/**
** Standard method of JSP tags that is called when the end tag is processed.
**
** @return int return-code according to JSP spec
**/
public int doEndTagCore() {
return EVAL_PAGE;
}
/**
** populates the selection box
**
** @throws JspException standard exception
** @throws JspTagException standard exception
** @throws IOException exception from Store
** @throws DatabaseAccessException exception from Store if database is not accessible
**/
public void processField() throws JspException, JspTagException, IOException, DatabaseAccessException {
QueryContainer qc=new QueryContainer(schema);
if (filter!=null) {
qc.add(new QueryFilter(filter));
}
ModuleInstance activeModule=findActiveInstance();
if (activeModule==null) {
throw new JspTagException("Evaluating Field Tag: module Id does not exist");
}
synchronized (activeModule) {
// creates a new temporary query
activeModule.setQuery("$$tempSelect",qc);
// creates a cursor
ModuleCursor cursor=activeModule.getCursor("$$tempSelect");
BodyContent body=getBodyContent();
HtmlStringParser htmlParser=null;
if (body.getString().length()==0) {
// if there is no body create a select tag
htmlParser=new HtmlStringParser(activeModule,"");
}
else {
// takes the body and parses it
htmlParser=new HtmlStringParser(activeModule,body.getString());
}
//HashMap hm=null;
// if distinct is required, create a hashmap
boolean bDistinct=false;
if (distinct!=null && distinct.equalsIgnoreCase("true")) {
bDistinct=true;
//hm=new HashMap();
}
// if sort is required, create a treemap.
// As is also a map, if we do Sort we also do Distinct(!!)
boolean bSort=false;
if (sort!=null && sort.equalsIgnoreCase("true")) {
bSort=true;
tm=new TreeMap(comparator);
}
if ((bDistinct) || (bSort)) {
hm=new HashMap();
}
try {
// iterates through the result set
while (cursor!=null && cursor.hasNext()) {
try{
cursor.next();
} catch (StoreException e) {
e.printStackTrace();
throw new JspException("error obtaing content for FillSelect: " + e.getMessage());
}
BusinessDocument doc=activeModule.getDocument("$$tempSelect");
// retrieves the value and the text field
String temp1;
try {
temp1 = doc.getRoot().getDescendant(value).getValue();
} catch (InvalidXPathException e) {
e.printStackTrace();
throw new JspException("invalid path in attribute 'value': '" + value + "' ");
}
String temp2;
try {
temp2=doc.getRoot().getDescendant(text).getValue();
} catch (InvalidXPathException e) {
e.printStackTrace();
throw new JspException("invalid path in attribute 'text': '" + text + "' ");
}
// if distinct is true, store them in the hashmap
if ((bDistinct==false) && (bSort==false))
htmlParser.addOption(temp1,temp2);
else
// otherwise put them into the select tag
hm.put(temp1,temp2);
}
if (bSort==true) {
tm.putAll(hm);
Iterator iterator=tm.keySet().iterator();
while (iterator.hasNext()) {
String temp1=(String)iterator.next();
String temp2=(String)hm.get(temp1);
htmlParser.addOption(temp1,temp2);
}
} else {
// if the loop is over and distinct is true, take the values from the hashmap
// and store them in the select tag
if (bDistinct==true) {
Iterator iterator=hm.keySet().iterator();
while (iterator.hasNext()) {
String temp1=(String)iterator.next();
String temp2=(String)hm.get(temp1);
htmlParser.addOption(temp1,temp2);
}
}
}
}
catch (BusinessDocumentStateException e) {
e.printStackTrace();
}
// writes the body with the new select tag
bodyContent.getEnclosingWriter().write(htmlParser.toHtml());
// clears the body content
bodyContent.clearBody();
// removes the temp cursor
activeModule.removeCursor("$$tempSelect");
}
}
}