diff --git a/Frameworks/Ajax/Ajax/Sources/er/ajax/ERXAjaxDynamicElement.java b/Frameworks/Ajax/Ajax/Sources/er/ajax/ERXAjaxDynamicElement.java new file mode 100644 index 00000000000..fa33991fb63 --- /dev/null +++ b/Frameworks/Ajax/Ajax/Sources/er/ajax/ERXAjaxDynamicElement.java @@ -0,0 +1,146 @@ +package er.ajax; + +import com.webobjects.appserver.WOActionResults; +import com.webobjects.appserver.WOAssociation; +import com.webobjects.appserver.WOContext; +import com.webobjects.appserver.WOElement; +import com.webobjects.appserver.WORequest; +import com.webobjects.appserver.WOResponse; +import com.webobjects.foundation.NSDictionary; +import com.webobjects.foundation.NSMutableArray; + +import er.extensions.appserver.ajax.ERXAjaxApplication; +import er.extensions.components.ERXDynamicElement; + +/** + * ERXAjaxDynamicElement provides a common base class for dynamic Ajax elements. + * + * @author jw + */ +public abstract class ERXAjaxDynamicElement extends ERXDynamicElement implements IAjaxElement { + + public ERXAjaxDynamicElement(String name, NSDictionary associations, WOElement template) { + super(name, associations, template); + } + + public ERXAjaxDynamicElement(String name, NSDictionary associations, NSMutableArray children) { + super(name, associations, children); + } + + /** + * Execute the request, if it's coming from our action, then invoke the ajax handler and put the key + * AJAX_REQUEST_KEY in the request userInfo dictionary (request.userInfo()). + * + * @param request the current request + * @param context context of the transaction + * @return the action results + */ + @Override + public WOActionResults invokeAction(WORequest request, WOContext context) { + WOActionResults result = null; + if (shouldHandleRequest(request, context)) { + result = handleRequest(request, context); + AjaxUtils.updateMutableUserInfoWithAjaxInfo(context); + if (ERXAjaxApplication.shouldIgnoreResults(request, context, result)) { + log.warn("An Ajax request attempted to return the page, which is almost certainly an error."); + result = null; + } + if (result == null && !ERXAjaxApplication.isAjaxReplacement(request)) { + result = AjaxUtils.createResponse(request, context); + } + } else if (hasChildrenElements()) { + result = super.invokeAction(request, context); + } + return result; + } + + /** + * Checks if the current request should be handled by this element. + * + * @param request the current request + * @param context context of the transaction + * @return true if we should handle the request + */ + protected boolean shouldHandleRequest(WORequest request, WOContext context) { + return AjaxUtils.shouldHandleRequest(request, context, id(context)); + } + + /** + * Overridden to call {@link #addRequiredWebResources(WOResponse, WOContext)}. + * + * @param response the current response + * @param context context of the transaction + */ + @Override + public void appendToResponse(WOResponse response, WOContext context) { + addRequiredWebResources(response, context); + } + + /** + * Override this method to append the needed scripts for this component. + * + * @param request the current request + * @param context context of the transaction + */ + protected abstract void addRequiredWebResources(WOResponse response, WOContext context); + + /** + * Override this method to return the response for an Ajax request. + * + * @param request the current request + * @param context context of the transaction + */ + public abstract WOActionResults handleRequest(WORequest request, WOContext context); + + /** + * Adds a script link tag with a correct resource URL in the HTML head tag if it isn't + * already present in the response. + * + * @param context context of the transaction + * @param response the current response + * @param framework name of the framework that contains the file + * @param fileName script file name + */ + protected void addScriptResourceInHead(WOContext context, WOResponse response, String framework, String fileName) { + AjaxUtils.addScriptResourceInHead(context, response, framework, fileName); + } + + /** + * Adds a script link tag with a correct resource URL in the HTML head tag if it isn't + * already present in the response. The script file will be searched within the + * Ajax framework. + * + * @param context context of the transaction + * @param response the current response + * @param fileName script file name + */ + protected void addScriptResourceInHead(WOContext context, WOResponse response, String fileName) { + AjaxUtils.addScriptResourceInHead(context, response, fileName); + } + + /** + * Adds a stylesheet link tag with a correct resource URL in the HTML head + * tag if it isn't already present in the response. + * + * @param context context of the transaction + * @param response the current response + * @param framework name of the framework that contains the file + * @param fileName CSS file name + */ + protected void addStylesheetResourceInHead(WOContext context, WOResponse response, String framework, String fileName) { + AjaxUtils.addStylesheetResourceInHead(context, response, framework, fileName); + } + + /** + * Adds a stylesheet link tag with a correct resource URL in the HTML head + * tag if it isn't already present in the response. The CSS file will be searched + * within the Ajax framework. + * + * @param context context of the transaction + * @param response the current response + * @param fileName CSS file name + */ + protected void addStylesheetResourceInHead(WOContext context, WOResponse response, String fileName) { + AjaxUtils.addStylesheetResourceInHead(context, response, fileName); + } +} diff --git a/Frameworks/Core/ERExtensions/Sources/er/extensions/components/ERXDynamicElement.java b/Frameworks/Core/ERExtensions/Sources/er/extensions/components/ERXDynamicElement.java new file mode 100644 index 00000000000..9f2dc243fce --- /dev/null +++ b/Frameworks/Core/ERExtensions/Sources/er/extensions/components/ERXDynamicElement.java @@ -0,0 +1,255 @@ +package er.extensions.components; + +import org.apache.log4j.Logger; + +import com.webobjects.appserver.WOAssociation; +import com.webobjects.appserver.WOComponent; +import com.webobjects.appserver.WOContext; +import com.webobjects.appserver.WOElement; +import com.webobjects.appserver.WOResponse; +import com.webobjects.appserver._private.WODynamicGroup; +import com.webobjects.foundation.NSArray; +import com.webobjects.foundation.NSDictionary; +import com.webobjects.foundation.NSMutableArray; + +import er.extensions.appserver.ERXWOContext; +import er.extensions.foundation.ERXValueUtilities; + +/** + * ERXDynamicElement provides a common base class for dynamic elements. + * + * @author jw + */ +public abstract class ERXDynamicElement extends WODynamicGroup { + protected Logger log = Logger.getLogger(getClass()); + private NSDictionary _associations; + + public ERXDynamicElement(String name, NSDictionary associations, WOElement template) { + super(name, associations, template); + _associations = associations; + } + + public ERXDynamicElement(String name, NSDictionary associations, NSMutableArray children) { + super(name, associations, children); + _associations = associations; + } + + /** + * Returns the element's association dictionary. + * + * @return the element's association dictionary + */ + public NSDictionary associations() { + return _associations; + } + + /** + * Return the value of the id binding if it exists or a safe identifier + * otherwise. + * + * @param context context of the transaction + * @return id string for this component + */ + public String id(WOContext context) { + String id = stringValueForBinding("id", context.component()); + if (id == null) { + id = ERXWOContext.safeIdentifierName(context, false); + } + return id; + } + + /** + * Returns the name of this element within the given context. This + * corresponds to the elementID. + * + * @param context context of the transaction + * @return elementID + */ + public String nameInContext(WOContext context) { + return context.elementID(); + } + + /** + * Checks if we are in secure mode by checking the secure binding or the + * context's secure mode as fallback. + * + * @param context context of the transaction + * @return true if in secure mode + */ + public boolean secureInContext(WOContext context) { + if (hasBinding("secure")) { + return booleanValueForBinding("secure", false, context.component()); + } + return context.secureMode(); + } + + /** + * Checks if there is an association for a binding with the given name. + * + * @param name binding name + * @return true if the association exists + */ + public boolean hasBinding(String name) { + return ERXComponentUtilities.hasBinding(name, associations()); + } + + /** + * Returns the association for a binding with the given name. If there is + * no such association null will be returned. + * + * @param name binding name + * @return association for given binding or null + */ + public WOAssociation bindingNamed(String name) { + return ERXComponentUtilities.bindingNamed(name, associations()); + } + + /** + * Checks if the association for a binding with the given name can assign + * values at runtime. + * + * @param name binding name + * @return true if binding is settable + */ + public boolean bindingIsSettable(String name) { + return ERXComponentUtilities.bindingIsSettable(name, associations()); + } + + /** + * Will try to set the given binding in the component to the passed value. + * + * @param value new value for the binding + * @param name binding name + * @param component component to set the value in + */ + public void setValueForBinding(Object value, String name, WOComponent component) { + ERXComponentUtilities.setValueForBinding(value, name, associations(), component); + } + + /** + * Retrieves the current value of the given binding from the component. If there + * is no such binding or its value evaluates to null the default + * value will be returned. + * + * @param name binding name + * @param defaultValue default value + * @param component component to get value from + * @return retrieved value or default value + */ + public Object valueForBinding(String name, Object defaultValue, WOComponent component) { + return ERXComponentUtilities.valueForBinding(name, defaultValue, associations(), component); + } + + /** + * Retrieves the current value of the given binding from the component. If there + * is no such binding null will be returned. + * + * @param name binding name + * @param component component to get value from + * @return retrieved value or null + */ + public Object valueForBinding(String name, WOComponent component) { + return ERXComponentUtilities.valueForBinding(name, associations(), component); + } + + /** + * Retrieves the current string value of the given binding from the component. If there + * is no such binding or its value evaluates to null the default + * value will be returned. + * + * @param name binding name + * @param defaultValue default value + * @param component component to get value from + * @return retrieved string value or default value + */ + public String stringValueForBinding(String name, String defaultValue, WOComponent component) { + return ERXComponentUtilities.stringValueForBinding(name, defaultValue, associations(), component); + } + + /** + * Retrieves the current string value of the given binding from the component. If there + * is no such binding null will be returned. + * + * @param name binding name + * @param component component to get value from + * @return retrieved string value or null + */ + public String stringValueForBinding(String name, WOComponent component) { + return ERXComponentUtilities.stringValueForBinding(name, associations(), component); + } + + /** + * Retrieves the current boolean value of the given binding from the component. If there + * is no such binding the default value will be returned. + * + * @param name binding name + * @param defaultValue default value + * @param component component to get value from + * @return retrieved boolean value or default value + */ + public boolean booleanValueForBinding(String name, boolean defaultValue, WOComponent component) { + return ERXComponentUtilities.booleanValueForBinding(name, defaultValue, associations(), component); + } + + /** + * Retrieves the current boolean value of the given binding from the component. If there + * is no such binding false will be returned. + * + * @param name binding name + * @param component component to get value from + * @return retrieved boolean value or false + */ + public boolean booleanValueForBinding(String name, WOComponent component) { + return ERXComponentUtilities.booleanValueForBinding(name, associations(), component); + } + + /** + * Retrieves the current int value of the given binding from the component. If there + * is no such binding the default value will be returned. + * + * @param name binding name + * @param defaultValue default value + * @param component component to get value from + * @return retrieved int value or default value + */ + public int integerValueForBinding(String name, int defaultValue, WOComponent component) { + return ERXComponentUtilities.integerValueForBinding(name, defaultValue, associations(), component); + } + + /** + * Resolves a given binding as an NSArray object. + * + * @param name binding name + * @param component component to get value from + * @return retrieved array value or null + */ + public NSArray arrayValueForBinding(String name, WOComponent component) { + return ERXComponentUtilities.arrayValueForBinding(name, associations(), component); + } + + /** + * Resolves a given binding as an NSArray object. + * + * @param name binding name + * @param defaultValue default value + * @param component component to get value from + * @return retrieved array value or default value + */ + public NSArray arrayValueForBinding(String name, NSArray defaultValue, WOComponent component) { + return ERXComponentUtilities.arrayValueForBinding(name, defaultValue, associations(), component); + } + + /** + * Appends the attribute to the response. If the value is null + * the appending is skipped. + * + * @param response the current response + * @param name the attribute name + * @param value the attribute value + */ + protected void appendTagAttributeToResponse(WOResponse response, String name, Object value) { + if (value != null) { + response._appendTagAttributeAndValue(name, value.toString(), true); + } + } +}