Hi all,
This is actually pretty straight forward to do. I don't know if this
is the best way to accomplish saving XML objects as EOs, but it works
and will hopefully help someone else!
The key is that Apache Digester provides the ability to create and
call custom rules that have begin(), body() and end() methods when
they hit an XML tag pattern. Use a custom rule instead of the stock
ObjectCreateRule to create an EO and add it to an EditingContext
BEFORE you start changing property values on the EO with the stock
digester rules.
I'm using WOnder so i am using ERXEC for the editing context and when
I add the related object with the rule (addToAuthors) I am taking
advantage of the WOnder feature that automatically updates my inverse
relationship. If you're not using WOnder you'll have to figure out
where to addObjectToBothSidesOfRelationship ...
Anyway ....
Here's my example Custom Rule for the main Document object:
public class DocumentECInserterRule extends
org.apache.commons.digester.Rule {
private ERXEC ec = (ERXEC) ERXEC.newEditingContext();
private Document doc = new Document();
public void begin(String namespace, String name,
org.xml.sax.Attributes attrs) {
digester.push(doc);
ec.insertObject(doc);
}
public void end(String namespace, String name) {
System.out.println("---- Saving out the EO ----");
ec.saveChanges();
}
}
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.
http://www.global-village.net/products/practical_webobjects
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [EMAIL PROTECTED]