James,
Hi. I'm sorry you've had such a frustrating experience with this particular D2W problem. I think I may have a workable solution for you.
The short answer is "Yes." You can certainly extend the D2W components. The long answer, comprised mostly of sample code follows below:
If I understand correctly, you want a way to save the query parameters, and then reload them at some later time. Keep in mind that you'd want to do something more functional than store the queries in the session, but this is just an example. ;)
You could extend the D2WQueryPage with your own custom WOComponent as follows:
import com.webobjects.foundation.*; import com.webobjects.appserver.*; import com.webobjects.eocontrol.*; import com.webobjects.eoaccess.*; import com.webobjects.directtoweb.*;
import java.util.Enumeration;
/** * An example subclass of the D2WQueryPage that allows us to intercept the values * the user supplied to the query. When we intercept the values, we "freeze" them * for later use. If the entity has been previously used in a query, we retrieve * the former query values, "thaw" them, and repopulate the query fields with the * saved values. * * To use this subclass for the query component for an entity, define a rule in * the D2WModel such that: * * (task='query') => pageName = "MyQueryPage" [100] * * Optionally restrict this by adding more conditions such as: * * ((task='query') and (entity.name = 'Foo')) * * This class could easily be extended to do something more useful with the query * parameters, such as serialize them to a database, or display a list of * previously saved queries, allowing the user to load the desired query. * * @author Travis Cripps */ public class MyQueryPage extends D2WQueryPage {
public MyQueryPage(WOContext context) { super(context); }
/** * Returns the WODisplayGroup used by this page. * * @return WODisplayGroup used by the page */ public WODisplayGroup displayGroup() { return displayGroup; }
/** * Overrides the superclass' implementation to give us a chance to save the * query parameters by calling the freezeQuery method. * * @return the result component */ public WOComponent queryAction() { NSLog.debug.appendln("DG queryMatch: " + displayGroup().queryMatch()); NSLog.debug.appendln("DG queryMatch: " + displayGroup().queryOperator()); NSLog.debug.appendln("DG qualifier: " + displayGroup().qualifierFromQueryValues());
// Save the query parameters. freezeQuery();
return super.queryAction(); }
/** * "Freezes" the query parameters for later use. */ private void freezeQuery() { NSMutableDictionary currentQuery = new NSMutableDictionary(); currentQuery.takeValueForKey(displayGroup().queryMatch(), "queryMatch"); currentQuery.takeValueForKey(displayGroup().queryOperator(), "queryOperator");
((Session)session()).savedQueriesByEntity().takeValueForKey(currentQuery, entity().name()); }
/** * Retrieves the "frozen" query parameters for the current entity, if any, * and "thaws" them, and re-injects the values into the WODisplayGroup used * by this component. */ private void thawQuery() { NSDictionary savedQuery = (NSDictionary)((Session)session()).savedQueriesByEntity().valueForKey(entity().name());
if (savedQuery != null) { NSDictionary queryMatch = (NSDictionary)savedQuery.valueForKey("queryMatch"); NSDictionary queryOperator = (NSDictionary)savedQuery.valueForKey("queryOperator");
// Reconstite the queryMatch keys from the saved query. NSArray matchKeys = queryMatch.allKeys(); Enumeration keysEnum = matchKeys.objectEnumerator(); while (keysEnum.hasMoreElements()) { String key = (String)keysEnum.nextElement(); String value = (String)queryMatch.valueForKey(key);
displayGroup().queryMatch().takeValueForKey(value, key); }
// Reconstite the queryOperator keys from the saved query. NSArray operatorKeys = queryOperator.allKeys(); keysEnum = operatorKeys.objectEnumerator(); while (keysEnum.hasMoreElements()) { String key = (String)keysEnum.nextElement(); String value = (String)queryOperator.valueForKey(key);
displayGroup().queryOperator().takeValueForKey(value, key); } } }
/** * Overrides the superclass' implementation to give us a chance to retrieve * our "frozen" query values for the current entity. */ public void appendToResponse(WOResponse response, WOContext context) {
// Reload any previously saved query parameters. thawQuery();
super.appendToResponse(response, context); }
}
And in your session, simply add:
private NSMutableDictionary savedQueriesByEntity = new NSMutableDictionary(); /** * Retrieves the dictionary used to provide storage for saved queries. */ public NSMutableDictionary savedQueriesByEntity() { return savedQueriesByEntity; }
Then, to use this component, create a rule in your D2WModel:
(task='query') => pageName = "MyQueryPage" [100]
That should do the trick. As you can see, you can get the query parameters from the displayGroup's queryMatch and queryOperator dictionaries. Once you have that info, the sky's the limit.
I hope this helps you. Best of luck with your project!
Travis
Message: 7 Date: Mon, 6 Feb 2006 09:43:43 -0600 From: James Cicenia <email@hidden> Subject: D2WQuery and Rules Question To: WebObjects Dev Apple <email@hidden> Message-ID: <email@hidden">email@hidden> Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed
OK -
How about this thought anyone.....
Can I create a custom component and use the D2W rules to populate the query input fields?
I need a solution or an approach to this problem desperately.
Thanks James Cicenia
|