
Some parts of this message have been removed.
Learn more about Nabble's
security policy.
I tried some of what Martin suggested but possibly didn't get it right. Here's a shortened copy of my service. I call the getXML method passing my object to get the XML string that will be sent to the web service. Then I turn right around and call the autoService method, again passing my object to actually call the web service. The builder code is/should be exactly the same, which is why I was hoping to eliminate one copy of the that code, but maybe that's not quite possible because of what the HttpBuilder class is expecting. The send() method is actually a two parm method which can take a Closure as the second parm which represents the xml builder. So, ideally, I'd like the autoService call to share a builder with the getXML method (only 1 copy to maintain) and the newer version would just pass the XML as the second parm to the send method.
Hope this makes sense!
package com.jda.portfolio.service
import com.jda.portfolio.domain.Configuration
import com.jda.portfolio.domain.TransactionSpec
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.XML
import static groovyx.net.http.ContentType.TEXT
import static groovyx.net.http.Method.PUT
class AutoTransService {
boolean transactional = false
def String getXML(TransactionSpec txnSpec) {
def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)
builder.TransactionSpec (training:txnSpec.training) {
transClassName txnSpec.transClassName
locationNumber txnSpec.locationNumber
currencyCode txnSpec.currencyCode
AssociateSpec { associateNumber txnSpec.associateSpec.associateNumber }
terminalName txnSpec.terminalName
LineItemSpecs {
for (item in txnSpec.lineItemSpecs) {
LineItemSpec {
sku(item.sku)
quantity(item.quantity)
if (item.overrideReasonCode) overrideReasonCode(item.overrideReasonCode)
if (item.overridePrice) overridePrice(item.overridePrice)
if (item.pricePrecision) pricePrecision(item.pricePrecision)
}
}
}
}
writer.toString()
}
def autoService(TransactionSpec txnSpec, Configuration conf, String userid, String pswd) {
def ppos = new HTTPBuilder( conf.protocol+"//"+conf.server+":"+conf.port, TEXT )
try {
ppos.request( PUT ) {
uri.path = conf.context + conf.url
headers = [Accept:'application/xml', 'ppos-user':userid, 'ppos-pswd':pswd]
send( groovyx.net.http.ContentType.XML ) {
TransactionSpec (training:txnSpec.training) {
transClassName txnSpec.transClassName
locationNumber txnSpec.locationNumber
currencyCode txnSpec.currencyCode
AssociateSpec { associateNumber txnSpec.associateSpec.associateNumber }
terminalName txnSpec.terminalName
if (txnSpec.lineItemSpecs) {
LineItemSpecs {
LineItemSpec {
for (item in txnSpec.lineItemSpecs) {
sku(item.sku)
quantity(item.quantity)
if (item.overrideReasonCode) overrideReasonCode(item.overrideReasonCode)
if (item.overridePrice) overridePrice(item.overridePrice)
if (item.pricePrecision) pricePrecision(item.pricePrecision)
}
}
}
}
// success handler
response.success = { resp, reader ->
//pretty print format the response
def stringWriter = new StringWriter()
def node = new XmlParser().parseText(reader.text);
new XmlNodePrinter(new PrintWriter(stringWriter)).print(node)
return stringWriter.toString()
}
// failure handler
response.failure = { resp ->
return 'Response status='+resp.status
}
}
} catch(Exception e) {
log.error("Caught exception:", e)
return e.toString()
}
}
}
> Date: Tue, 3 Nov 2009 19:20:22 -0500
> From:
martin@...> To:
user@...> Subject: Re: [groovy-user] How to use MarkupBuilder
>
> I think you can do:
>
> def myClosure = {
> ... some build code here ...
> }
>
> builder.TransactionObject(myClosure)
>
> then pass that same closure to the other XML builder.
>
> If that doesn't work, we'd probably need more details on your situation
> to help you.
>
> Best,
> Martin
>
> Mike Miller wrote:
> > I have a question about Groovy and the MarkupBuilder. I have a Grails
> > application that generates some XML. I am trying to 'DRY' up my
> > code. I have one method that gets the XML String represented by one of
> > my objects and it looks like this:
> >
> >
> > def getXMLString(TxnObject obj) {
> >
> > def writer = new StringWriter()
> > def builder = new MarkupBuilder()
> > builder.TransactionObject {
> > ... some build code here ...
> > }
> > writer.toString()
> > }
> >
> > Then I am using the HttpBuilder to make a RESTful call to a web
> > service. Inside the HttpBuilder code, I have basically the same builder
> > code to build my XML. The HttpBuilder class expects a closure for the
> > xml builder.
> >
> > How do I define the closure and/or builder so that I am not repeating
> > the closure in two separate places?
> >
> >
> > i'm EMAILING FOR THE GREATER GOOD
> > Join me <http://im.live.com/Messenger/IM/Home/?source=EML_WLHM_GreaterGood>
> >
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>