RE: CVS Update: Barracuda
"Christian Cryder" <[email protected]>
| Newsgroups | gmane.comp.java.enhydra.barracuda.general |
|---|---|
| Message-ID | <[email protected]> |
Hi Jake,
> It certainly is possible (see above).
<snip>
> If it is ok with you, I will look into addding the concept of the
> "delegate runtime value" supporting the ServletContext
> object....of course making sure not to break any existing functionality.
Ok, thanks for the explanation. Its clearer now (a bit anyways ;-).
Out of curiousity, where else would you envision using this type of
functionality? (ie. what else would you use to configure besides the DOM
Factory class?
As a final thought, maybe the real question here is "what should a scripting
semantic look like". I think that's probably what rubbed me wrong from the
get-go. Consider the following:
<dom-loader
factory="org.enhydra.barracuda.core.util.dom.XMLCDeferredParsingDOMFactory">
<set-property name="servletContext" delegateRuntimeValue="true" />
</dom-loader>
Its not at all clear to me as a casual observer (and even after you've
explained it to me either) exactly what is going on here. For instance, I
see the reference to <dom-loader>...is this a custom tag which means
something special to the scripting interpreter, or does it mean "find some
object named dom-loader and do something too it", or what.
Likewise, its not at all clear what the factory attribute does...is this an
attribute in the object that dom-loader points to? Does it actually cause
XMLCDeferredParsingDOMFactory to be instantiated? Its unclear to me.
Likewause, with servletContext, I'm not really certain whether that's a
property of the dom-loader thing, the Factory object, or something else.
delegateRuntimeValue is equally mysterious (ie. what would happen if the
value was false?)
The point here is NOT that your approach sucks (it doesn't); but rather that
the semantics of what you are doing are not intuitive to me - now I've
probably missed some salient details from your emails, but I did read all of
them...it just never clicked for me exactly what was going on.
Something that might really help here would be if you provided examples of
what else you would script using your approach. Some psuedo-code explaining
step by step what is going on would also be tremendously helpful.
Now, one of the things that I'd like to try and explain further is how this
approach to scripting you have proposed seems to have a very different feel
to the way the existing ObjectRepositoryAssembler scripting works.
As an example, consider the following:
<object name="$ds" class="com.foo.SomeClass">
<method name="setURL">jdbc://some_jdbc_url</method>
<method name="setMinPoolSize">2</method>
<method name="setMaxPoolSize">10</method>
<method name="setMaxIdleTime">60</method>
<method name="setManagementCycleTime">2</method>
</object>
<object name="$dsw" class="com.foo.SomeOtherClass" arg1="$ds"/>
<register key="DB_PUBS" val="$dsw"/>
Now, here's how that translates into psuedo-code:
1. create an instance of SomeClass and save a reference to it named $ds
2. invoke the various methods on $ds (notice that this approach handles
different data types - setURL takes a String, the other methods takes ints,
etc). What is not shown here is how it handles multiple param methods...for
that you'd use arg1, arg2, arg3, etc)
3. instantiate another object, this time of SomeOtherClass, and pass in the
SomeClass instance ($ds) to the constructor. This new object is named $dsw.
4. finally register the $dsw object in the global repository under the key
DB_PUBS.
Now, the beauty of this approach (IMO) is that its simple and readable.
There are shortcomings however - it doesn't currently provide a way to
access the servlet object (ie. with a 'this'), and it doesn't have a way to
get Objects back from a method. But those two things would be very easy to
address. For instance, consider what the result would look like when applied
to you're particular scripting needs:
<object name="$this">
<method name="getServletContext" return="$sc"/>
</object>
<object class="org.enhydra.barracuda.core.util.dom.DefaultDOMLoader">
<method name="getGlobalInstance" return="$dl" />
</object>
<object name="$dl">
<method name="setServletContext" arg1="$sc" />
</object>
Translated into pseudo-code,
1. grab the current object ('this'...in this case a Servlet), and invoke
getServletContext() on it, saving the return value in an object named "$sc"
2. create an instance of DefaultDOMLoader, invoke getGlobalInstance(), and
save the result in "$dl"
3. finally, invoke $dl.setServletContext($sc)
Something like this would be much more palatable to me because its easy to
follow, still very simple to write, and its much more in line with the
current way scripting works in ObjectRepositoryAssembler. This is ultimately
why I don't feel good about the <dom-loader> implementation going into
ObjectRepositoryAssembler...it just seems way too different from the
approach to scripting already found there.
Now, please don't take all this as me saying "my way's right and yours is
wrong" - I don't mean it to be that at all. Rather, I'm trying to explain
what I find confusing about the approach you've suggested, as well as trying
to explain what I do like about the existing scripting approach, and to
possibly suggest a way the existing approach could be tweaked to accomplish
the same thing you are after while sticking with the same basic approach
that we've already taken with ObjectRepositoryAssembler.
ObjectRepositoryAssembler was never intended to be a be-all/end-all
scripting solution - it was just designed to be simple, clean, quick, and
(most importantly) relatively intuitive, and its proven to be very useful
over time (much more than I ever originally anticipated). That said, I don't
think we should try and radically alter it either - I'm fine with tweaks
here and there (such as I've suggested above with the addition of a 'this'
reference and the ability to get return values from a method), but if we
want to try something significantly different, then I'd rather just see that
approach done with a new/different assembler and format - after all, there's
no reason why someone can't create a BetterScriptingAssembler or something
like that...its just a servlet, and there's nothing that says you have to
run ObjectRepositoryAssembler.
Any way, hopefully that helps explain where I'm coming from on this. If you
really want to put your logic in there, go ahead and do it, but I still
think its the wrong thing to do (my gut level reaction hasn't really changed
here).
I'd love to hear what others think about these things as well...
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 Jacob Kjome
> Sent: Thursday, June 19, 2003 3:27 PM
> To: [email protected]
> Subject: RE: [Barracuda] CVS Update: Barracuda
>
>
> Hi Christian,
>
> At 02:14 PM 6/19/2003 -0600, you wrote:
>
> Hi Jake!
>
> Good discussion ;-)
>
> > I suppose this could be done, but that means that a servlet would
> > have had to set up the object repository. This is easy to
> > guarantee in the framework, but what about the example that I
> > just showed where a Barracuda DOMLoader+DOMFactory does the
> > equivalent job of XMLCContext in a demo that knows nothing about
> > Barracuda except for the two classes I was using from Barracuda?
> > I was able to set the servlet context to
> > setServletContext(Servletcontext) because I had it available
> > already. Seems like setting up an object repository in that case
> > would be a bit of overkill.
>
> Hmm...well, yes, the servlet has to put the info into the object
> repository,
> but any program could do that. The whole point of the object repository
> stuff is to decouple the servlet stuff from the application stuff, to make
> it so you don't have to pass references around.
>
>
> If I don't require an object repository other than to store the
> ServletContext, I'd rather just add it to my object via a
> bean-like method such as setServletContext(ServletContext) than
> have the overhead of storing an object repository. The "delegate
> runtime value" configuration is just a way, without any other
> overhead, to set the bean method with an object that can't
> possibly be described in a configuration file. Once it is set
> there, its there. I don't need to pass it around anymore nor do
> I require any external reference to it.
>
>
> > Hmm.... the object repository can solve some things, but for
> > some reason I'm a bit uncomfortable with it in this situation.
>
> Fair enough, but I'm equally uncomfortable with the delegate runtime
> approach...
>
>
> It's just an alternative. I'm not uncomfortable with the object
> repository in general. If it is an object that I need to use in
> 20 places in my app, then the object repository is, without
> question, the way to go. That just isn't the case here. I'm
> uncomfortable with not having the choice of which way to do
> things. I think there is room for both ideas and I've already
> proven the "delegate runtime value" works in the
> DefaultApplicationAssembler and not just for <dom-loader> but
> also for anything you want to do <set-property> upon (of course
> limited to setting certain objects. In this case, only the
> ServletContext is currently supported, but there aren't a lot of
> other runtime objects one would need in a webapp environment
> anyway. It wouldn't be hard to support others if need be, though).
>
>
> > The assumption I make in the DOMFactory is that one is able to
> > call setServletContext(ServletContext) if they want to. The
> > configuration side with the concept of a "delegate runtime value"
> > is just a way to be able to call this method as if it was being
> > done programatically by user defined code
>
> And that's what lead me to suggest the object repositor assembler approach
> in the first place - it already has built in functionality to instantiate
> any object (even those that take parameters) and to invoke
> methods on them.
> So rather than inventing _another_ approach (with different
> syntax, etc), I
> was thinking that it might make sense to try and use what's already there.
>
>
> Yes, except that the configuration side of the object repository
> doesn't support calling methods of instantiated objects that take
> complex objects as parameters which can't be described in a
> configuration file (such as the ServletContext). It requires a
> programmatic step of actually adding the servlet context object
> to the object repository. As I've said before, if I don't
> require an object repository for any other reason other than
> getting a servlet context object into the method of a
> configuration-instantiated object, then the object repository is
> just overhead and an unnecessary extra step. Additionally,
> sometimes I might not even care that it is set at all. In the
> case of the XMLCDeferredParsingDOMFactory, it is entirely
> optional. No need to store a reference if I don't need to which
> I couldn't control if I added the ServletContext to the object
> repository in the ApplicationGateway and ComponentGateway.
>
> Again, this just points out that the choice is up to the
> implementor and if we give both the choice of adding stuff to the
> object repository and the choice of doing the scripting, but not
> adding it to the object repository then everyone wins and no one loses.
>
>
> With that said, though, I'm not sure if it even _could_ be added to the
> object-repository.xml stuff...the obj repos assembler is its own servlet,
> which runs BEFORE ApplicationGateway even starts up, so there is
> not really
> an easy way to even refer to the servlet config object which will
> be used in
> a different servlet.
>
>
> I was wondering if you were just mistyping or just weren't quite
> seeing which object I was talking about in previous emails. I am
> talking about the "ServletContext", not the "ServletConfig". One
> may obtain the servlet context from a servlet config object,
> however, I don't care about any particular servlet's
> ServletConfig object. The ServletContext, of which there is only
> one per webapp, is what I am concerned with. It doesn't matter
> how or where you get the ServletContext from. It is all the same
> object reference.
>
>
> > I think adding the concept of the "delegate runtime value" to the
> > the configuration side of the object repository (just like the
> > ApplicationGateway supports) without necessarily storing the value
> > in the object repository would be a nice alternative feature.
>
> Based on my previous paragraph, do you think this is even
> possible? I guess
> I'm not opposed to you doing it, provided it doesn't break
> anything (which I
> don't think it will), but it just feels quite a bit different from the
> existing approach that ObjectRepositoryAssembler takes (and I like
> consistency ;-)
>
>
> It certainly is possible (see above). Also, it is just an option
> and doesn't have to be used by anyone if they don't want to. If
> the object repository assembler truly is the scripting framework
> used by Barracuda, then it should be consistent to script
> something without necessarily adding it to the object repository
> or even be necessary to use a runtime object repository at all
> even while using the scripting framework. Otherwise, I think
> there needs to be more of a separation between the scripting
> framework and the runtime object repository. So, I don't think
> this breaks any consistencies.
>
> If it is ok with you, I will look into addding the concept of the
> "delegate runtime value" supporting the ServletContext
> object....of course making sure not to break any existing functionality.
>
> Jake
>
>
> Let me know what you think...
>
> 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 Jacob Kjome
> > Sent: Thursday, June 19, 2003 12:55 PM
> > To: [email protected]
> > Subject: RE: [Barracuda] RE: [Barracuda-commit] CVS Update: Barracuda
> >
> >
> > At 12:02 PM 6/19/2003 -0600, you wrote:
> >
> > > So, it is the "factory" class we are configuring, not the
> > > "class" class of the <dom-loader>.
> >
> > Ok, so if I understand correctly, the bottom line of all this
> is that your
> > factory class needs to be able to get access to the ServletConfig
> > object, is
> > this correct?
> >
> > What if all you had to do in your factory class was this:
> >
> > ObjectRepository lor = ObjectRepository.getLocalRepository();
> > ServletConfig sc = (ServletConfig)
> > lor.get(ServletConfig.class.getName());
> >
> > It seems to me that the cleanest way to solve your problem is simply to
> >
> > a) use ObjectRepositoryAssembler to configure a static var that will
> > determine which specific implementation gets used (thereby achieving the
> > desired pluggability)
> >
> >
> > Well, it is more than just the default implementation. It is
> > also specific implementations per/DOM class (if desired). And
> > this is all per DOMLoader instance with the global loader storing
> > the default instance which is obtained via getGlobalInstance().
> >
> >
> > b) modify ComponentGateway and ApplicationGateway to store references to
> > servlet specific objects (ServletConfig, HttpServletRequest,
> > HttpServletResponse) in the local repository (using their class names as
> > keys), which makes it possible for any downline classes to access and
> > utilize them without having to know anything about ComponentGateway,
> > ApplicationGateway, etc.
> >
> > Thoughts?
> >
> >
> > I suppose this could be done, but that means that a servlet would
> > have had to set up the object repository. This is easy to
> > guarantee in the framework, but what about the example that I
> > just showed where a Barracuda DOMLoader+DOMFactory does the
> > equivalent job of XMLCContext in a demo that knows nothing about
> > Barracuda except for the two classes I was using from Barracuda?
> > I was able to set the servlet context to
> > setServletContext(Servletcontext) because I had it available
> > already. Seems like setting up an object repository in that case
> > would be a bit of overkill.
> >
> > Hmm.... the object repository can solve some things, but for
> > some reason I'm a bit uncomfortable with it in this situation.
> > The assumption I make in the DOMFactory is that one is able to
> > call setServletContext(ServletContext) if they want to. The
> > configuration side with the concept of a "delegate runtime value"
> > is just a way to be able to call this method as if it was being
> > done programatically by user defined code so that the DOMFactory
> > really don't have any knowledge about where it might get the
> > ServletContext object from. Once it has it, it uses it. If it
> > doesn't have it, it doesn't use it. It is optional.
> >
> > There are lots of cases where the object repository seems like a
> > good way to go. I'm just not convinced if this is one of those
> > cases. I think adding the concept of the "delegate runtime
> > value" to the the configuration side of the object repository
> > (just like the ApplicationAssembler supports) without necessarily
> > storing the value in the object repository would be a nice
> > alternative feature. People can choose whatever method makes
> > sense to them for their own code.
> >
> > Your thoughts?
> >
> > Jake
> >
> >
> > 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 Jacob Kjome
> > > Sent: Thursday, June 19, 2003 10:55 AM
> > > To: [email protected]
> > > Subject: Re: [Barracuda] RE: [Barracuda-commit] CVS Update: Barracuda
> > >
> > >
> > > Hi Christian,
> > >
> > > At 09:19 AM 6/19/2003 -0600, you wrote:
> > >
> > > Hi Jake!
> > >
> > > I read your description of what you did, but I'm still a bit
> confused...
> > >
> > > > concept of a "delegate runtime value". What this means is that
> > > > the value of the parameter to be set is a runtime object rather
> > > > than something that can be provided as a literal value in the
> > > > configuration file. Currently, the only supported delegate
> > >
> > > Do you mean by this that all you are doing is invoking a method on an
> > > object? (rather than setting a static variable?)
> > >
> > >
> > > yes
> > >
> > >
> > > Looking at your example in the Barracuda event-gateway.xml file,
> > > I see this:
> > >
> > > <dom-loader
> > > factory="org.enhydra.barracuda.core.util.dom.XMLCDeferredParsingDO
> > > MFactory">
> > > <set-property name="servletContext"
> > delegateRuntimeValue="true" />
> > > </dom-loader>
> > >
> > > What exactly is this doing (ie. in terms of psuedo-code)? I'm
> > guessing it
> > > involves instantiating the XMLCDeferredParsingDOMFactory and
> > then calling
> > > setServletContext() on it, but I'm probably wrong about some of the
> > > specifics.
> > >
> > >
> > > That's just about exactly right. Of course, optionally, a
> > > DOMLoader class can be specified to store the DOMFactory
> > > instance, but the DefaultDOMLoader is used by default. Since
> > > DOMLoaders store a single instance of a DOMFactory, creating a
> > > single DOMFactory object, configuring it, and storing it in the
> > > DOMLoader works perfectly.
> > >
> > >
> > > To step back a level, what is the high level objective of
> this? It looks
> > > like you are trying to
> > > a) specify a pluggable implementation of the DOMLoader
> > >
> > > Well, yes, but more to the point, pluggable DOMFactory
> > > implementations to a specified DOMLoader of which the
> > > DefaultDOMLoader is used if on does not specify one using the
> > > "class" attribute of the <dom-loader> element. The DOMLoader
> > > must have defined a public static getGlobalInstance() method. I
> > > would have defined that in the DOMLoader interface, but static
> > > methods can't be defined in interfaces. The
> > > DefaultApplicationAssembler simply throws a SAXException in this case.
> > >
> > > So, once the implementation of the DOMLoader has been created and
> > > its global loader defined (returned by getGlobalInstance()), we
> > > can instantiate a DOMFactory and set it as the default dom
> > > factory of the global loader. So, we are setting the servlet
> > > context object to the DOMFactory in this case, not the DOMLoader.
> > > So, it is the "factory" class we are configuring, not the
> > > "class" class of the <dom-loader>.
> > >
> > >
> > > b) make it possible for that DOMLoader to get a reference to
> the servlet
> > > context
> > >
> > >
> > > Like I said above, it is the DOMFactory that gets the reference
> > > to the servlet. The DOMLoader is pretty stupid. It is the
> > > DOMFactory that has all the knowledge about loading DOM documents
> > > from class or from file so that is what requires the reference to
> > > the servlet context.
> > >
> > >
> > > Can you confirm/correct my understanding of that? If I understand it
> > > correctly, then I think there may be an easier way to do this,
> > > but I'll wait
> > > to hear from you first before commenting further...
> > >
> > >
> > > Sure, I'd like to hear it. Note that the reason the servlet
> > > context is being stored is to be able to obtain configuration
> > > from web.xml just like XMLC's XMLCContext does. In fact,
> > > XMLCContext and a DOMLoader + DOMFactory implementation are
> > > totally interchangeable.
> > >
> > > Here is the setup of XMLCContext.....
> > > XMLCContext context = XMLCContext.getContext(this);
> > > XMLCFactory factory = context.getXMLCFactory();
> > > ....
> > > ....
> > > Document doc1 = factory.create(docClass);
> > > //or
> > > Document doc2 =
> > > ((XMLCDeferredParsingFactory)factory).createFromFile(docFile);
> > > //might get exception if cast fails
> > >
> > > And here is the equivalent setup of a DOMLoader + DOMFactory....
> > > DOMLoader loader = DefaultDOMLoader.getGlobalInstance();
> > > XMLCDeferredParsingDOMFactory lfactory = new
> > > XMLCDeferredParsingDOMFactory();
> > > lfactory.setServletContext(this.getServletContext());
> > > loader.setDefaultDOMFactory(lfactory);
> > > ....
> > > ....
> > > Document doc1 = loader.getDOM(docClass);
> > > //or
> > > Document doc2 = loader.getDOMFromFile(doc); //might get
> > > exception if underlying dom factory doesn't support loading from file
> > >
> > >
> > > All the configuration for the above is done using <context-param>
> > > entries in web.xml. For instance....
> > >
> > > <context-param>
> > > <param-name>xmlcReparseResourceDirs</param-name>
> > >
> > > <param-value>D:\xmlc\examples\tomcat\res;D:\xmlc\examples\tomcat\r
> > > es\pkg</param-value>
> > > </context-param>
> > > <context-param>
> > > <param-name>xmlcReparsePackagePrefixes</param-name>
> > > <param-value>xmlc</param-value>
> > > </context-param>
> > > <context-param>
> > > <param-name>xmlcReparseDefaultMetaDataPath</param-name>
> > > <param-value>options.xmlc</param-value>
> > > </context-param>
> > >
> > > XMLCContext supports a few more options, but these are either
> > > redundant or irrelevant to Barracuda's config requirements. I've
> > > attached a couple examples taken from XMLC's tomcat example app
> > > and modified one to use Barracuda for dom loading just as I've
> > > described above.
> > >
> > > Note that in the case above I was able to directly set up the
> > > XMLCDeferredParsingDOMFactory with the servlet context. However,
> > > given that I really don't have access to the servlet context at
> > > runtime, and given that I shouldn't I need to do this
> > > programmatically since that would tie my code to a specific
> > > DOMFactory implementation, the assembler configuration with the
> > > "delegate runtime value" functionality is required.
> > >
> > > Jake
> > >
> > >
> > > Christian
> > > ----------------------------------------------
> > > Christian Cryder
> > > Internet Architect, ATMReports.com
> > > Project Chair, BarracudaMVC - http://barracudamvc.org
> > > ----------------------------------------------
> > > "Coffee? I could quit anytime, just not today"
> > >
> > >
> > > > -----Original Message-----
> > > > From: Jacob Kjome [mailto:[email protected]]
> > > > Sent: Wednesday, June 18, 2003 10:37 PM
> > > > To: Christian Cryder
> > > > Subject: Re: [Barracuda-commit] CVS Update: Barracuda
> > > >
> > > >
> > > > Hi Christian,
> > > >
> > > >
> > > >
> > > > Log message:
> > > > <b>csc_061803.1</b> - Modified ObjectRepositoryAssembler
> > > > to support the setting of
> > > > Shorts, Longs, Doubles and Floats in addition to the
> > > > String, Boolean, and Integer
> > > > support that was already there. While I was at it I
> > > > discovered that the previous
> > > > implementation only supported the setting of primitives,
> > > > so I modified things so that
> > > > you can set both primitives and their first class
> > counterparts.
> > > >
> > > >
> > > >
> > > > Might we want to add the notion of the "delegate runtime value"
> > > > which I added to the DefaultApplicationAssembler? Here is my
> > > > comment from A_Changes_History about that....
> > > >
> > > > <quote>
> > > > jrk_20030529.1 - Updated handling of <set-property> and
> > > > <constant> in DefaultApplicationAssembler to recognize the
> > > > concept of a "delegate runtime value". What this means is that
> > > > the value of the parameter to be set is a runtime object rather
> > > > than something that can be provided as a literal value in the
> > > > configuration file. Currently, the only supported delegate
> > > > runtime value is a ServletContext object. The syntax of this new
> > > > configuration option is...
> > > >
> > > >
> > > > <set-property name="servletContext"
> > > > delegateRuntimeValue="true"/>
> > > >
> > > >
> > > >
> > > > Obviously this assumes that the class this property is to act
> > > > upon have either a public "setServletContext()" method or a
> > > > public "servletContext" field.
> > > >
> > > > Also updated XMLCDeferredParsingDOMFactory to take advantage of
> > > > this feature, the reason being that it needs to read context init
> > > > parameters to provide extra optional information to the
> > > > DeferredParsingFactory which the DeferredParsingDOMFactory backs.
> > > > Also modified it to create the DeferredParsingFactory once
> > > > instead of every time DOMFactory#getInstance() is called. This
> > > > should provide a slight performance improvement.
> > > > </quote>
> > > >
> > > >
> > > > So, this just says "I, the configuration file writer, delegate
> > > > the responsibility of the setting of a runtime object to a method
> > > > that I specify because I cannot possibly script this value in a
> > > > configuration file."
> > > >
> > > > does that make sense? Of course, only certain specified
> > > > "delegate runtime values" would be supported, but you can look at
> > > > DefaultApplicationAssembler to see how I implemented this for
> > > > methods taking the current runtime ServletContext object. It
> > > > works perfectly and allowed me to duplicate the web.xml
> > > > configuration functionality of XMLCContext in the
> > > > XMLCDeferredParsingDOMFactory.
> > > >
> > > >
> > > > Jake
> > >
> > > _______________________________________________
> > > Barracuda mailing list
> > > [email protected]
> > > http://barracudamvc.org/lists/listinfo/barracuda
> >
> > _______________________________________________
> > Barracuda mailing list
> > [email protected]
> > http://barracudamvc.org/lists/listinfo/barracuda
>
> _______________________________________________
> Barracuda mailing list
> [email protected]
> http://barracudamvc.org/lists/listinfo/barracuda