package er.extensions.components._private; import java.text.Format; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webobjects.appserver.WOAssociation; import com.webobjects.appserver.WOComponent; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WODynamicElement; import com.webobjects.appserver.WOElement; import com.webobjects.appserver.WOResponse; import com.webobjects.appserver._private.WODynamicElementCreationException; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSKeyValueCoding; import com.webobjects.foundation.NSTimeZone; import com.webobjects.foundation.NSTimestampFormatter; import er.extensions.appserver.ERXSession; import er.extensions.formatters.ERXNumberFormatter; import er.extensions.formatters.ERXTimestampFormatter; /** * Reimplementation of WOString that can resolve localized format strings. This * is very useful as most of the components in DirectToWeb use a "format"-String * binding - so to use localized patterns, you'd need to re-implement all these * components. * * @author ak */ public class ERXWOString extends WODynamicElement { private static final Logger log = LoggerFactory.getLogger(ERXWOString.class); protected WOAssociation _dateFormat; protected WOAssociation _numberFormat; protected WOAssociation _formatter; protected WOAssociation _value; protected WOAssociation _escapeHTML; protected WOAssociation _valueWhenEmpty; boolean _shouldFormat; public ERXWOString(String s, NSDictionary nsdictionary, WOElement woelement) { super(null, null, null); _value = (WOAssociation) nsdictionary.objectForKey("value"); if (_value == null) { throw new WODynamicElementCreationException("<" + getClass().getName() + "> ( no 'value' attribute specified."); } _valueWhenEmpty = (WOAssociation) nsdictionary.objectForKey("valueWhenEmpty"); _escapeHTML = (WOAssociation) nsdictionary.objectForKey("escapeHTML"); _dateFormat = (WOAssociation) nsdictionary.objectForKey("dateformat"); _numberFormat = (WOAssociation) nsdictionary.objectForKey("numberformat"); _formatter = (WOAssociation) nsdictionary.objectForKey("formatter"); if (_dateFormat != null || _numberFormat != null || _formatter != null) _shouldFormat = true; else _shouldFormat = false; if ((_dateFormat != null && _numberFormat != null) || (_formatter != null && _dateFormat != null) || (_formatter != null && _numberFormat != null)) { throw new WODynamicElementCreationException("<" + getClass().getName() + "> ( cannot have 'dateFormat' and 'numberFormat' or 'formatter' attributes at the same time."); } } @Override public void appendToResponse(WOResponse woresponse, WOContext wocontext) { WOComponent component = wocontext.component(); Object valueInComponent = null; if (_value != null) { valueInComponent = _value.valueInComponent(component); if (_shouldFormat) { Format format = null; boolean hasFormatter = false; if (_formatter != null) { format = (Format) _formatter.valueInComponent(component); } if (format == null) { if (_dateFormat != null) { String formatString = (String) _dateFormat.valueInComponent(component); if (formatString == null) { format = ERXTimestampFormatter.defaultDateFormatterForObject(formatString); } else { format = ERXTimestampFormatter.dateFormatterForPattern(formatString); } } else if (_numberFormat != null) { String formatString = (String) _numberFormat.valueInComponent(component); if (formatString == null) { format = ERXNumberFormatter.defaultNumberFormatterForObject(valueInComponent); } else { format = ERXNumberFormatter.numberFormatterForPattern(formatString); } } } else { hasFormatter = true; } if(valueInComponent == NSKeyValueCoding.NullValue) { valueInComponent = null; } if (format != null) { if (valueInComponent == null) { // do nothing; } else { if(ERXSession.autoAdjustTimeZone() && !hasFormatter && format instanceof NSTimestampFormatter && wocontext.hasSession() && ERXSession.class.isAssignableFrom(wocontext.session().getClass()) ) { synchronized(format) { ERXSession session = (ERXSession)wocontext.session(); NSTimeZone zone = NSTimeZone._nstimeZoneWithTimeZone(session.timeZone()); NSTimestampFormatter tsFormat = (NSTimestampFormatter)format; NSTimeZone parseZone = tsFormat.defaultParseTimeZone(); NSTimeZone formatZone = tsFormat.defaultFormatTimeZone(); tsFormat.setDefaultFormatTimeZone(zone); tsFormat.setDefaultParseTimeZone(zone); try { valueInComponent = format.format(valueInComponent); } catch (IllegalArgumentException ex) { log.info("Exception while formatting", ex); valueInComponent = null; } finally { tsFormat.setDefaultFormatTimeZone(formatZone); tsFormat.setDefaultParseTimeZone(parseZone); } } } else { try { valueInComponent = format.format(valueInComponent); } catch (IllegalArgumentException ex) { log.info("Exception while formatting", ex); valueInComponent = null; } } } } else { if (valueInComponent != null) { log.debug("no formatter found! {}", valueInComponent); } } } } else { log.warn("value binding is null !"); } String stringValue = null; if (valueInComponent != null) stringValue = valueInComponent.toString(); if ((stringValue == null || stringValue.length() == 0) && _valueWhenEmpty != null) { stringValue = (String) _valueWhenEmpty.valueInComponent(component); woresponse.appendContentString(stringValue); } else if (stringValue != null) { boolean escapeHTML = true; if (_escapeHTML != null) escapeHTML = _escapeHTML.booleanValueInComponent(component); if (escapeHTML) woresponse.appendContentHTMLString(stringValue); else woresponse.appendContentString(stringValue); } } }