001 package edu.nrao.sss.webapp.faces.component; 002 003 import javax.faces.component.UIComponent; 004 import javax.faces.component.UIInput; 005 import javax.faces.component.NamingContainer; 006 import javax.faces.context.FacesContext; 007 import javax.faces.context.ResponseWriter; 008 import javax.faces.el.ValueBinding; 009 010 import edu.nrao.sss.math.Polynomial; 011 import edu.nrao.sss.math.PolynomialTerm; 012 import edu.nrao.sss.util.StringUtil; 013 014 import java.io.IOException; 015 import java.util.Map; 016 import java.util.Iterator; 017 018 import org.apache.log4j.Logger; 019 020 public class PolynomialUIComponent extends UIInput implements NamingContainer 021 { 022 private Boolean enabled = null; 023 private static Logger log = Logger.getLogger(PolynomialUIComponent.class); 024 025 public void encodeBegin(FacesContext context) 026 throws IOException 027 { 028 Polynomial poly = (Polynomial)getValue(); 029 030 String styleClass = (String)getAttributes().get("styleClass"); 031 String style = (String)getAttributes().get("style"); 032 033 ResponseWriter writer = context.getResponseWriter(); 034 035 String id = getClientId(getFacesContext()); 036 String termIdPrefix = id + "term"; 037 038 writer.startElement("div", this); 039 writer.writeAttribute("id", id, null); 040 if (styleClass != null) 041 writer.writeAttribute("class", styleClass, null); 042 043 if (style != null) 044 writer.writeAttribute("style", style, null); 045 046 StringUtil su = StringUtil.getInstance(); 047 if (isEnabled()) 048 { 049 for (Iterator<PolynomialTerm> values = poly.getTerms().values().iterator(); values.hasNext();) 050 { 051 PolynomialTerm t = values.next(); 052 String tid = termIdPrefix + t.getExponent(); 053 054 writer.startElement("input", this); 055 writer.writeAttribute("type", "text", null); 056 writer.writeAttribute("size", "5", null); 057 writer.writeAttribute("id", tid, null); 058 writer.writeAttribute("name", tid, null); 059 writer.writeAttribute("value", su.formatNoScientificNotation(t.getCoefficient()), null); 060 writer.writeAttribute("onblur", "iceSubmitPartial(form, this, event); return false;", null); 061 writer.endElement("input"); 062 063 writer.write(" x"); 064 writer.startElement("sup", this); 065 writer.write(String.valueOf(t.getExponent())); 066 writer.endElement("sup"); 067 068 if (values.hasNext()) 069 writer.write(" + "); 070 } 071 } 072 073 else 074 { 075 for (Iterator<PolynomialTerm> values = poly.getTerms().values().iterator(); values.hasNext();) 076 { 077 PolynomialTerm t = values.next(); 078 String tid = termIdPrefix + t.getExponent(); 079 080 writer.startElement("span", this); 081 writer.writeAttribute("id", tid, null); 082 writer.write(su.formatNoScientificNotation(t.getCoefficient()) + "x"); 083 084 writer.startElement("sup", this); 085 writer.write(String.valueOf(t.getExponent())); 086 writer.endElement("sup"); 087 088 if (values.hasNext()) 089 writer.write(" + "); 090 091 writer.endElement("span"); 092 } 093 } 094 095 writer.endElement("div"); 096 097 //Start a div, then let our child UICommand render itself. 098 writer.startElement("div", this); 099 if (styleClass != null) 100 writer.writeAttribute("class", styleClass, null); 101 102 if (style != null) 103 writer.writeAttribute("style", style, null); 104 } 105 106 public void encodeEnd(FacesContext context) 107 throws IOException 108 { 109 ResponseWriter writer = context.getResponseWriter(); 110 if (isEnabled()) 111 { 112 String coeffId = getClientId(getFacesContext()) + "newTermCoef"; 113 String expId = getClientId(getFacesContext()) + "newTermExp"; 114 115 //Now we add an input field and selectOneMenu. 116 writer.startElement("input", this); 117 writer.writeAttribute("type", "text", null); 118 writer.writeAttribute("size", "5", null); 119 writer.writeAttribute("id", coeffId, null); 120 writer.writeAttribute("name", coeffId, null); 121 writer.writeAttribute("value", "0", null); 122 writer.endElement("input"); 123 124 writer.startElement("select", this); 125 writer.writeAttribute("name", expId, null); 126 127 writer.startElement("option", this); 128 writer.writeAttribute("value", "1", null); 129 writer.write("x"); 130 writer.endElement("option"); 131 132 writer.startElement("option", this); 133 writer.writeAttribute("value", "2", null); 134 135 writer.write("x"); 136 writer.startElement("sup", this); 137 writer.write("2"); 138 writer.endElement("sup"); 139 140 writer.endElement("option"); 141 142 writer.startElement("option", this); 143 writer.writeAttribute("value", "3", null); 144 145 writer.write("x"); 146 writer.startElement("sup", this); 147 writer.write("3"); 148 writer.endElement("sup"); 149 150 writer.endElement("option"); 151 152 writer.startElement("option", this); 153 writer.writeAttribute("value", "4", null); 154 155 writer.write("x"); 156 writer.startElement("sup", this); 157 writer.write("4"); 158 writer.endElement("sup"); 159 160 writer.endElement("option"); 161 162 writer.startElement("option", this); 163 writer.writeAttribute("value", "5", null); 164 165 writer.write("x"); 166 writer.startElement("sup", this); 167 writer.write("5"); 168 writer.endElement("sup"); 169 170 writer.endElement("option"); 171 172 writer.endElement("select"); 173 } 174 175 writer.endElement("div"); 176 } 177 178 public void decode(FacesContext context) 179 { 180 Map parms = context.getExternalContext().getRequestParameterMap(); 181 182 String termIdPrefix = getClientId(getFacesContext()) + "term"; 183 int prefixLength = termIdPrefix.length(); 184 185 StringBuilder poly = new StringBuilder(); 186 187 StringUtil su = StringUtil.getInstance(); 188 189 for (Iterator keys = parms.keySet().iterator(); keys.hasNext();) 190 { 191 String key = (String)keys.next(); 192 193 //Found a term entry, append the exponent and value 194 //(coefficient) to the submitted value. 195 if (key.startsWith(termIdPrefix)) 196 { 197 //Take from the end of the prefix to the end of the string to 198 //be the exponent. 199 String exp = key.substring(prefixLength); 200 String coefStr = ((String)parms.get(key)).trim(); 201 202 Double coef; 203 try { coef = Double.parseDouble(coefStr); } 204 catch(NumberFormatException nfe) { coef = null; } 205 206 if (coef != null && coef != 0) 207 poly.append(su.formatNoScientificNotation(coef) + "x^" + exp + " + "); 208 } 209 } 210 211 //remove the last " + " 212 if (poly.length() >= 3) 213 poly.setLength(poly.length() - 3); 214 215 log.debug("Polynomial w/o extra terms: " + poly); 216 if (getChildCount() == 1) 217 { 218 String buttonId = ((UIComponent)getChildren().get(0)).getClientId(context); 219 log.debug("\tchild buttonId: " + buttonId); 220 221 //If the add term button was hit.... 222 if (parms.get(buttonId) != null) 223 { 224 log.debug("\tAdding Extra term"); 225 //Now we have to check to see if they entered a new term. 226 String newCoefId = getClientId(getFacesContext()) + "newTermCoef"; 227 String newExpId = getClientId(getFacesContext()) + "newTermExp"; 228 229 String newCoefStr = (String)parms.get(newCoefId); 230 if (newCoefStr != null) 231 newCoefStr = newCoefStr.trim(); 232 233 String newExp = (String)parms.get(newExpId); 234 if (newExp != null) 235 newExp = newExp.trim(); 236 237 //if there's a valid non-zero value for the coeff, add it as a term. 238 Double newCoef; 239 try { newCoef = Double.parseDouble(newCoefStr); } 240 catch(NumberFormatException nfe) { newCoef = null; } 241 242 if (newCoef != null && newCoef != 0) 243 { 244 if (poly.length() > 0) 245 poly.append(" + "); 246 247 poly.append(su.formatNoScientificNotation(newCoef) + "x^" + newExp); 248 } 249 } 250 } 251 252 log.debug("Polynomial before the set submit: " + poly); 253 254 setValid(true); 255 setSubmittedValue(poly.toString()); 256 } 257 258 public Boolean isEnabled() 259 { 260 if (this.enabled != null) 261 return this.enabled; 262 263 ValueBinding vb = getValueBinding("enabled"); 264 if (vb != null) 265 { 266 Object val = vb.getValue(getFacesContext()); 267 268 if (val instanceof Boolean && val != null) 269 return (Boolean)val; 270 } 271 272 //else 273 return Boolean.TRUE; 274 } 275 276 public void setEnabled(Boolean e) 277 { 278 this.enabled = e; 279 } 280 281 /** 282 * Adds the enabled status of this component to the state being saved. 283 */ 284 public Object saveState(FacesContext context) 285 { 286 Object[] state = new Object[2]; 287 state[0] = super.saveState(context); 288 state[1] = this.enabled; 289 return state; 290 } 291 292 /** 293 * restores the enabled status of this component 294 */ 295 public void restoreState(FacesContext context, Object state) 296 { 297 Object[] mystate = (Object[])state; 298 super.restoreState(context, mystate[0]); 299 300 this.enabled = (Boolean)mystate[1]; 301 } 302 }