package er.extensions.components; import com.webobjects.appserver.WOActionResults; import com.webobjects.appserver.WOAssociation; import com.webobjects.appserver.WOComponent; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WOElement; import com.webobjects.appserver.WORequest; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSKeyValueCoding; import com.webobjects.foundation.NSMutableDictionary; import er.extensions.components._private.ERXHyperlink; /** * ERXDataHyperlink works like a WOHyperlink except that instead of turning * unknown bindings into tag attributes, it instead passes them to the page * specified in pageName. For instance, if you have a pageName = "PersonPage" * and person = "$currentPerson", when the link is clicked, the next page will * be a PersonPage with setPerson(currentPerson) passed into it. * * You can pass in as many bindings as you need, but there are some bindings * that are used by this element by itself and thus are not passed to the page: * The ones defined by WOHyperlink and additionally "id", "class", "onclick" and * "otherTagString", which are handled like bindings on a stock WOHyperlink. * * If the "pageName" binding is not set, ERXDataHyperlink will behave like a * regular WOHyperlink. * * @author mschrag * @author timo */ public class ERXDataHyperlink extends ERXHyperlink { private final static NSArray<String> BINDINGS_HANDLED_BY_SUPER_CLASS = new NSArray<>(new String[] {"id", "class", "onclick", "otherTagString"}); private NSMutableDictionary<String, WOAssociation> _bindingAssociations; @SuppressWarnings("unchecked") public ERXDataHyperlink(String s, NSDictionary associations, WOElement woelement) { // The WOHyperlink's constructor will remove all associations from // super._associations that directly affect WOHyperlink super(s, associations, woelement); if (_pageName != null) { _bindingAssociations = new NSMutableDictionary<>(); NSMutableDictionary<String, WOAssociation> superAssociations = super._associations; for (String key : superAssociations.allKeys()) { // leave anything listed in BINDINGS_HANDLED_BY_SUPERCLASS in // super._associations to be handled by the superclass. if (!BINDINGS_HANDLED_BY_SUPER_CLASS.containsObject(key)) { // Move all other associations to our own _bindingAssociations, // so they can later be used as bindings for the page specified // in pageName. _bindingAssociations.setObjectForKey(superAssociations.removeObjectForKey(key), key); } } } } @Override @SuppressWarnings("unchecked") public WOActionResults invokeAction(WORequest worequest, WOContext wocontext) { WOActionResults results = super.invokeAction(worequest, wocontext); if (results != null && _pageName != null) { WOComponent component = wocontext.component(); for (String bindingName : _bindingAssociations.allKeys()) { WOAssociation association = _bindingAssociations.objectForKey(bindingName); Object value = association.valueInComponent(component); NSKeyValueCoding.Utility.takeValueForKey(results, value, bindingName); } } return results; } }