package com.cfinkel.reports.wrappers; import com.cfinkel.reports.exceptions.BadReportSyntaxException; import com.cfinkel.reports.generatedbeans.*; import com.cfinkel.reports.util.Util; import org.apache.log4j.Logger; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.io.Serializable; /** * $Author: charles $ * $Revision: 8904 $ * $Date: 2006-05-01 18:02:06 -0400 (Mon, 01 May 2006) $ * * Created by IntelliJ IDEA. * User: charles * Date: Mar 25, 2006 * Time: 5:40:14 PM * To change this template use File | Settings | File Templates. */ public abstract class Input implements Serializable { private static final Logger log = Logger.getLogger(Input.class); private boolean hasValidation; public Report getReport() { return report; } public abstract ControlElement getControlElement(); private Report report; // abstract methods: public abstract Map<String,String> getValues() throws Exception; public abstract String getDefaultVal(); public abstract String getDescription(); public abstract Control getControl(); public abstract Datatype getDatatype(); private InputElement inputElement; public int getDepth() { return depth; } private int depth = 0; public InputElement get() { return inputElement; } static final DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("MM/dd/yyyy"); static final DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("hh:mm a"); static final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("MM/dd/yyyy hh:mm a"); public Input (InputElement inputElement, Report report, int depth) throws BadReportSyntaxException { this.report = report; this.depth = depth; // todo: change this: check for validation this.hasValidation = false; // put this input into report: if (report.getAllInputs().get(inputElement.getName()) != null) throw new BadReportSyntaxException("There are more than one input named '" + inputElement.getName() + "'"); report.getAllInputs().put(inputElement.getName(),this); this.inputElement = inputElement; this.dependents = new LinkedHashMap<String,Input>(); this.report = report; for(DependentInputElement dependentInputElement : inputElement.getDependentInput()) { if (report.getAllInputs().get(dependentInputElement.getName()) != null) throw new BadReportSyntaxException("There are more than one dependentInput named '" + dependentInputElement.getName() + "'"); Input dependentInput; // if first "when" element is *, it has dynamic values if (dependentInputElement.getWhen().get(0).getParentValue().equals("*")) { dependentInput = new DependentInputWithDynamicValues(dependentInputElement,report,this,this.depth+1); } else { dependentInput = new DependentInputWithStaticValues(dependentInputElement,report,this,this.depth+1); } dependents.put(dependentInputElement.getName(),dependentInput); } } Map<String,Input> dependents; public boolean isHasDependents() { return ((dependents != null) && dependents.size() > 0); } public Map<String,Input> getDependents() { return dependents; } /** * * @return javascript for getting selected value of input. * different for radio buttons (annoying) */ public String getInputValueJavascript() { StringBuilder sb = new StringBuilder(); if (this.getControl().equals(Control.RADIO)) { sb.append("getSelectedRadioValue(document.getElementsByName('"); sb.append(this.get().getName()); sb.append("'))"); // getSelectedRadioValue } else { sb.append("document.getElementById('"); sb.append(this.get().getName()); sb.append("').value"); } return sb.toString(); } public String getName() { return inputElement.getName(); } /** * adds call to AJAX javascript update thang and validation checker * @return html for AJAX javascript update thang */ public String getOnChangeHTML() { StringBuilder sb = new StringBuilder(); if (!this.isHasDependents() && !this.isHasValidation()) return ""; if (this.getControl().equals(Control.RADIO)) { sb.append("onclick=\""); } else { sb.append("onchange=\""); } if (this.isHasDependents()) { sb.append(this.getName()); sb.append("_changed();"); } if (this.isHasValidation()) { sb.append(" check_"); sb.append(this.getName()); sb.append("();"); } sb.append("\""); return sb.toString(); } static final SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy"); static final SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm a"); static final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm a"); /** * formats the input value for proper insertion into the query * @param s * @return formatted String input */ public Object format(String s) throws ParseException { Object object; try { switch (this.getDatatype()) { case DATE: object = new Timestamp(dateFormat.parse(s).getTime()); break; case DATETIME: object = new Timestamp(dateTimeFormat.parse(s).getTime()); break; case TIME: object = new Timestamp(timeFormat.parse(s).getTime()); break; case STRING: object = s; break; case FLOAT: object = Float.valueOf(s); break; case INTEGER: object = Integer.valueOf(s); break; default: object = s; break; } } catch (ParseException e) { throw e; } catch (NumberFormatException e) { // todo: fix: should not be creating a parseexception right now throw new ParseException(e.toString(),0); } return object; } protected static String getDefaultValue(String defaultString, Datatype dataType) { if (defaultString == null) return ""; if (Util.equalsAny(dataType,Datatype.FLOAT,Datatype.INTEGER, Datatype.STRING)) { return defaultString; } String defaultVal = defaultString; if (defaultVal.equalsIgnoreCase("now") || defaultVal.equalsIgnoreCase("today")) { Calendar calendar = new GregorianCalendar(); if (defaultVal.equalsIgnoreCase("today")) { calendar.set(Calendar.HOUR_OF_DAY,0); calendar.set(Calendar.MINUTE,0); } Date date = calendar.getTime(); switch (dataType) { case DATE: defaultVal = dateFormat.format(date); break; case DATETIME: defaultVal = dateTimeFormat.format(date); break; case TIME: defaultVal = timeFormat.format(date); break; default: break; } } else if (defaultVal.startsWith("m")) { DateTime dateTime = new DateTime(); Integer minutes = Integer.parseInt(defaultVal.substring(1,defaultVal.length())); dateTime = dateTime.minusMinutes(minutes); defaultVal = dateTimeFormatter.print(dateTime); } else if (defaultVal.startsWith("d")) { DateTime dateTime = new DateTime(); Integer days = Integer.parseInt(defaultVal.substring(1,defaultVal.length())); dateTime = dateTime.minusDays(days); defaultVal = dateTimeFormatter.print(dateTime); } return defaultVal; } /** * gets values from attribute 'values' * @param valuesString * @return values from attribute 'values' */ public static HashMap<String,String> getValuesFromAttribute(String valuesString) { HashMap<String,String> tempMap = new LinkedHashMap<String,String>(); if (!Util.anyAreNullOrBlank(valuesString)) { // parse values as pairs: StringTokenizer st = new StringTokenizer(valuesString,"(),"); while (st.hasMoreTokens()) { String key = st.nextToken(); String value = st.nextToken(); tempMap.put(key,value); } } return tempMap; } /** * gets control attribute based on control element * kind of a kludge * @param controlElement * @return * @throws BadReportSyntaxException */ protected static Control getControlAttributeFromControlElement(ControlElement controlElement) throws BadReportSyntaxException { if(controlElement.getListbox() != null) { return Control.LISTBOX; } else if (controlElement.getTextarea() != null) { return Control.TEXTAREA; } else if (controlElement.getRadio() != null) { return Control.RADIO; } else { String message = "No proper control for this input. This should never happen."; log.error(message); throw new BadReportSyntaxException(message); } } /** * @return has validation? */ public boolean isHasValidation() { return hasValidation; } }