RE: Barracuda Streaming

"Christian Cryder" <[email protected]>
Newsgroups gmane.comp.java.enhydra.barracuda.general
Message-ID <[email protected]>
Yep, it is. But its not documented anywhere I don't think.

Basically, there is a BlockIterateHandler that is designed for this task -
it will process and render the page in chunks. Now what this means is that
any components used to render individual portions of the page can't do
anything fancy (like scripting) that will require them to access other
portions of the DOM outside of their little segment.

Here's a sample template...

<div class="Dir::Block_Iterate.RepsList">
  ...
  any markup you want in here; may contain directives,
  regular directive iterators, etc
  ...
</div>

Then you implement your handler like this:

    class RenderRepsListHandler extends BlockIterateHandler {
        public abstract Class getTemplateClass() {
		return RepsListHTML.class; 	//just what you'd expect
        }
        public abstract BlockIterator getIterator(String key) {
            return new RepsIterator();  //this is what's different
        }
    }

Ok, so what happens is when Barracuda encounters the special Block_Iterate
directive in the markup, it asks for an iterator that answers to the name of
'RepsList'. You provide an instance of RepsListIterator(), which implements
Barracuda's BlockIterator class and looks something like this:

    class RepsIterator extends AbstractBlockIterator {
        RepList rl = null;
        RepMap rmPayee = null;
        int rssize = 0;
        int reccnt = -1;

        //when the RepsIterator is instantiated, load the RepsList
        public RepsIterator() {
            logger.debug("Instantiating RepsIterator "+this);
            ObjectRepository or = ObjectRepository.getLocalRepository();
            rl = (RepList) or.getState(COMMISSION_LIST);

            //figure out the total number of recs in the result set
            try {rssize = rl.size();}
            catch (SQLException e) {}
            logger.debug(rssize+" reps in list");
        }

        //this allows us to specify the models that will be used by the
BTemplate
        //that processes each item in the iterator. This gets called once,
after each
        //loadNext() invocation returns true
        public Object getTemplateModels() {
            logger.debug("getting RepsIterator template models "+this);
            List models = CommonModels.getCommonModels();
            try {
                models.add(new BatchModel());
                models.add(new QueryModel());
                models.add(new GreenbarModel());
                models.add(new RepsModel(rmPayee));
                RepList rlMerchants = (RepList) rmPayee.get(MERCH_LIST);
                if (rlMerchants!=null) models.add(new
MerchantsModel(rmPayee, rlMerchants));
                List stmtList = (List) rmPayee.get(STMT_LIST);
                if (stmtList!=null) models.add(new StmtModel(stmtList));
            } catch (SQLException e) {
                localLogger.warn("Unexpected SQLException: "+e);
                e.printStackTrace();
            }
            logger.debug("got em");
            return models;
        }


        //do we have any more items in the list
        public boolean hasNext() {
            logger.debug("checking has next item in RepsIterator");
            boolean hasNext = (rl!=null && reccnt<rssize-1);
            logger.debug("hasNext: "+hasNext);
            return hasNext;
        }


        //load the next item in the list; its entirely permissable to skip
items
        //(ie. because some biz logic indicates they're not suitable for
rendering)
        //if you return false, the list is considered done.
        public boolean loadNext() {
            logger.debug("loading next item in RepsIterator: "+(reccnt+1));
            rmPayee = null;
            try {
                rmPayee = (RepMap) rl.get(++reccnt);
                repTotal = new BigDecimal("0.0");
                //we could actually skip records in the list here...

            } catch (SQLException e) {
                localLogger.warn("Unexpected SQLException: "+e);
                e.printStackTrace();
            }
            logger.debug("got it:"+(rmPayee!=null));
            return (rmPayee!=null);
        }
    }

So basically what happens here is that you provide an iterator which tells
how many times we are going to loop over the contents of that initial chunk
of markup up above. SO...if it the template looked like this:

    <div class="Dir::Block_Iterate.RepsList">
      <table>
        <tr>
          <td><span class="Dir::Get_Data.RepsModel.Foo">Foo</span></td>
        </tr>
      </table>
    </div>

and we had 3 reps in the list, the final chunk would look like this:

    <div>
      <table>
        <tr>
          <td><span class="Dir::Get_Data.RepsModel.Foo">Rep 1</span></td>
        </tr>
      </table>
      <table>
        <tr>
          <td><span class="Dir::Get_Data.RepsModel.Foo">Rep 2</span></td>
        </tr>
      </table>
      <table>
        <tr>
          <td><span class="Dir::Get_Data.RepsModel.Foo">Rep 3</span></td>
        </tr>
      </table>
    </div>

What happens here is that the BlockIterateHandler basically returns the
results of the template straight back to the browser until it hits a
Block_Iterate tag. Then it gets a BlockIterator and loops over the
underlying dataset - for each iteration, it sets up a BTemplate, adds the
appropriate models, renders the component hierarchy, and then renders that
chunk of DOM back to the browser. Then it goes onto the next iteration. When
the iterator is complete, it moves on to the rest of the original template.

Couple of key final comments here:

a) the end tag </div> is what tells the iterate handler to move on to the
next element; there is no Block_Iterate "end" tag or anything like that.

b) the only portions of the template that get processed by a BTemplate are
those inside of Block_Iterate segments...so let's say you have some header
info up at the top of the template, which is NOT part of an iteration - you
still have to create a block iterator for it so that the BlockIterateHandler
knows it needs to be processed (ie. it can't be sent directly back to the
browser).

That about covers it. Questions? Feel free to holler...

Christian
----------------------------------------------
Christian Cryder
Internet Architect, ATMReports.com
Project Chair, BarracudaMVC - http://barracudamvc.org
----------------------------------------------
"Coffee? I could quit anytime, just not today"


> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]]On Behalf Of
> [email protected]
> Sent: Wednesday, October 29, 2003 3:45 PM
> To: [email protected]
> Subject: [Barracuda] Barracuda Streaming
>
>
> Does Barracuda allow any type of streaming?
> I have a very large HTML template that brings up data from a
> backend system but this process is very very slow and I would
> like to stream parts of the HTML back even before the rest of the
> page has been generated.  Is this possible?
>
> Thanks in advance.
>
> _______________________________________________
> Barracuda mailing list
> [email protected]
> http://barracudamvc.org/lists/listinfo/barracuda
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.