Re: D2WQuery and Rules Question
Travis Cripps <[email protected]>
| Newsgroups | gmane.comp.web.webobjects.devel |
|---|---|
| Message-ID | <[email protected]> |
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
On Feb 6, 2006, at 10:21 AM, [email protected]
wrote:
> Message: 7
> Date: Mon, 6 Feb 2006 09:43:43 -0600
> From: James Cicenia <[email protected]>
> Subject: D2WQuery and Rules Question
> To: WebObjects Dev Apple <[email protected]>
> Message-ID: <[email protected]>
> 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
_______________________________________________
WebObjects-dev mailing list
[email protected]
http://www.omnigroup.com/mailman/listinfo/webobjects-dev