For any related objects you have to play around with the creation order a bit and not call ec.saveChanges() in the end() method. Here's an example inserter rule for a related object:
package ca.cscw;
import ca.cscw.model.Author;
import ca.cscw.model.Document;
import er.extensions.ERXEC;
public class AuthorECInserterRule extends org.apache.commons.digester.Rule {
public AuthorECInserterRule( ) {
}
public void begin(String namespace, String name, org.xml.sax.Attributes attrs) {
// gets a reference to the top object on the stack, we need this to pass the same editingContext from rule to rule
Document doc = (Document) digester.peek();
// then create your author
Author author = new Author();
// push new author to the top of the stack
digester.push(author);
// get the ec
ERXEC ec = (ERXEC)mc.editingContext();
// insert new author
ec.insertObject(author);
}
public void end(String namespace, String name) {
// remove author from the stack (doc moves to the top once again)
Author author = (Author) digester.pop();
}
}
Here is the use of my example rules:
DocumentECInserterRule documentECMInserterRule = new DocumentECInserterRule();
digester.addRule("Document", documentECMInserterRule);
// add an attribute property
digester.addSetProperties("Document", "Status", "status" );
AuthorECInserterRule authorECInserterRule = new AuthorECInserterRule();
digester.addRule("Document/AuthorList/Author", authorECInserterRule);
// add a couple example properties
digester.addCallMethod("Document/AuthorList/Author/LastName", "setLastName", 0 );
digester.addCallMethod("Document/AuthorList/Author/FirstName", "setFirstName", 0 );
// call 'addToAuthors' method when the next 'Document/AuthorList/Author' pattern is seen
// this adds the author that is already in the ec from the InserterRule
digester.addSetNext("MedlineCitationSet/MedlineCitation/Article/AuthorList/Author", "addToAuthors" );
The rule firing order is first in, last out. So my custom (ignoring the property setting rules) rules will fire in this order:
documentECMInserterRule.begin() //creates the document and inserts it into a new EditingContext
authorECInserterRule.begin() // create author, get reference to the document's EditingContext, insert author
authorECInserterRule.end() // pops the author off the stack and adds it to the relationship using the default addSetNext rule
documentECMInserterRule.end() // save all changes to the EditingContext
Take care,
David
On 21-Apr-08, at 5:47 PM, Chuck Hill wrote:
On Apr 21, 2008, at 5:28 PM, David Holt wrote:
Hi all,
I have successfully parsed an XML file with the Apache Digester (thanks to Chuck's suggestion) and created EOs using the default rules.
I end up with an array of EOs each of which has several to-many relationships to other created EOs. The xml seems to all be "digested" at once when the file is parsed and I am not sure where to intervene to add an EO to the editing context. Can anyone help me with this?
Offhand, I don't know. I looked at our code using Digester (code which I was not at all involved in, my story, and I am sticking to it), we imported them into intermediate (non-EO) classes and then fetched / created EOs (as appropriate for update / create). We then copied the needed values from the intermediate classes. I think that was necessary as the XML represented EOs getting inserted into an existing, complex graph of objects. Your case is probably simpler, but I don't have a simple solution at hand.
Chuck
--
Practical WebObjects - for developers who want to increase their overall knowledge of WebObjects or who are trying to solve specific problems.