How to use MarkupBuilder

View: New views
4 Messages — Rating Filter:   Alert me  

How to use MarkupBuilder

by mikemil :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
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

Re: How to use MarkupBuilder

by Martin C. Martin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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



RE: How to use MarkupBuilder

by mikemil :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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()
  }
 }
 
}






i'm EMAILING FOR THE GREATER GOOD
Join me


 

> 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
>
>

Re: How to use MarkupBuilder

by Tom Nichols :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Although I haven't looked in detail over your code, I remember a
similar situation where I wanted to abstract out some builder calls so
the method|closure could be used more than once.  I think in short,
the builder instance needs to be assigned as the closure's delegate.

On Wed, Nov 4, 2009 at 12:34 AM, Mike Miller <mikemil@...> wrote:

>
> 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()
>   }
>  }
>
> }
>
>
>
>
>
>
> EMAILING FOR THE GREATER GOOD
> Join me
>
>
> > 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
> >
> >

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email