Let me see if I can take an easy example.
ofbiz simple-method:
org/ofbiz/party/party/PartyServices#followPartyRelationshipsInline
<simple-method method-name="followPartyRelationshipsInline"
short-description="followPartyRelationshipsInline">
<!--snip comment -->
<if-empty field-name="nowTimestamp"><now-timestamp-to-env
env-name="nowTimestamp"/></if-empty>
<!-- only create these if they don't already exist, more efficient and
avoids potential problems in recursed calls -->
<if-empty field-name="_inline_roleTypeIdFromList">
<field-to-list field-name="roleTypeIdFrom"
list-name="_inline_roleTypeIdFromList"/>
<if-compare field-name="roleTypeIdFromInclueAllChildTypes" operator="equals"
value="Y">
<set value="_inline_roleTypeIdFromList"
field="roleTypeIdListName"/>
<call-simple-method method-name="getChildRoleTypesInline"/>
</if-compare>
</if-empty>
<if-empty field-name="_inline_roleTypeIdToList">
<field-to-list field-name="roleTypeIdTo"
list-name="_inline_roleTypeIdToList"/>
<if-compare field-name="roleTypeIdToInclueAllChildTypes" operator="equals"
value="Y">
<set value="_inline_roleTypeIdToList"
field="roleTypeIdListName"/>
<call-simple-method method-name="getChildRoleTypesInline"/>
</if-compare>
</if-empty>
<call-simple-method
method-name="followPartyRelationshipsInlineRecurse"/>
</simple-method>
after markup:
<simple-method method-name="followPartyRelationshipsInline"
short-description="followPartyRelationshipsInline">
<!--snip comment -->
<section-begin>
<section name="sectionA"/>
</section-begin>
<if-empty field-name="nowTimestamp"><now-timestamp-to-env
env-name="nowTimestamp"/></if-empty>
<!-- only create these if they don't already exist, more
efficient and avoids potential problems in recursed calls -->
<if-empty field-name="_inline_roleTypeIdFromList">
<field-to-list field-name="roleTypeIdFrom"
list-name="_inline_roleTypeIdFromList"/>
<if-compare field-name="roleTypeIdFromInclueAllChildTypes" operator="equals"
value="Y">
<set value="_inline_roleTypeIdFromList"
field="roleTypeIdListName"/>
<call-simple-method method-name="getChildRoleTypesInline"/>
</if-compare>
</if-empty>
<if-empty field-name="_inline_roleTypeIdToList">
<field-to-list field-name="roleTypeIdTo"
list-name="_inline_roleTypeIdToList"/>
<if-compare field-name="roleTypeIdToInclueAllChildTypes" operator="equals"
value="Y">
<set value="_inline_roleTypeIdToList"
field="roleTypeIdListName"/>
<call-simple-method method-name="getChildRoleTypesInline"/>
</if-compare>
</if-empty>
<section-end>
<section name="sectionA"/>
</section-end>
<call-simple-method
method-name="followPartyRelationshipsInlineRecurse"/>
</simple-method>
This simple markup would allow me to create my own simple method as such:
<simple-method method-name="myMethod">
<call-simple-method-section method-name="followPartyRelationshipsInline"
xml-resource="org/ofbiz/party/party/PartyServices.xml" section="sectionA">
<set field="relPartyListSize" value=${bsh:relatedPartyIdList.size()}/>
<if-compare operator="less" field="relPartyListSize" value="100">
<call-simple-method method-name="followPartyRelationshipsInlineRecurse"/>
</if-compare>
</simple-method>
This would allow me to quickly create a method that stops the recursion if
there are more than 100 entries in the list. (note: this may not be the exact
correct place to put this, but I think it demonstrates the concept well enough,
let me know if it doesn't)
Or If I wanted to avoid recursion for party "Company"
<simple-method method-name="myMethod">
<call-simple-method-section
method-name="followPartyRelationshipsInline"
xml-resource="org/ofbiz/party/party/PartyServices.xml"
section="sectionA">
<if-compare operator="not-equals" field="partyIdTo" value="Company">
<call-simple-method method-name="followPartyRelationshipsInlineRecurse"/>
</if-compare>
</simple-method>
I certainly hear you when you say that the ofbiz simple-method "may not be maintained the way you like". However, I think anyone reusing any logic from the project is already taking and accepting that risk. In addition, the reason I've been demonstrating the <section-begin><section name="sectionA"></section-begin>
is that you could just as easily have:
<section-begin><section name="sectionA"><section name="sectionB"></section-begin>
and have the section-end for each at different places. This would mitigate much of the risk as well.
As far as there being more to maintain, the additional lines to the ofbiz
project method would not be added to the method operations, they would be in
effect no different than a comment to ofbiz operations.
I hope this clarifies the intent. Thanks!
----- Original Message ----
From: David E Jones <[EMAIL PROTECTED]>
To: [email protected]
Sent: Friday, November 16, 2007 3:29:23 PM
Subject: Re: [RFC] simple method subsections
I'm still not totally sure what you're trying to accomplish, or maybe
more accurately, what you want to make easier.
Could you throw out some ofbiz-oriented pseudo code for the way you
would do this now that you don't like?
I don't think I really like this section approach in the simple-
methods. It adds a lot of otherwise meaningless stuff to the routines,
and you'd still have to instrument a LOT of code in order to really be
able to use it without modifying the original code, and any code that
was instrumented this way would result in more lines of code to
maintain, and they may not be maintained the way you like, especially
if the purpose or intent isn't clear.
Based on more info about what you're trying to do I'm guessing we can
find a better alternative that is more "automatic" and not so
intrusive in existing code.
-David
On Nov 16, 2007, at 10:47 AM, Chris Howe wrote:
I gave several ideas, the parameterized one is probably the least
plausible because of security considerations. I'm leaning towards
the <section-begin/section-end> tagging that would be otherwise
inert to an ofbiz application.
example:
MySimpleMehtods.xml
<simple-method method-name="myMehtod>
...some logic...
<get-simple-method-section method-name="ofbizMethod" location="org/
ofbiz/ofbizApp/OfbizServices.xml" section="sectionA">
...some more logic...
</simple-method>
OfbizServices.xml
<simple-method method-name="ofbizMethod">
...some ofbiz logic that I don't want to run in myMethod...
<section-begin>
<section name="sectionA">
</section-begin>
...some ofbiz logic that I want to run in myMethod...
<section-end>
<section name="sectionA">
</section-end>
...some more ofbiz logic that I don't want to run in myMethod...
</simple-method>
This would be similar to how <call-simple-method> works except you
would be pulling a node that is a child of <simple-method> instead
of a child node of <simple-methods>. And instead of pulling a node,
you're pulling all elements between a section-begin and a section-
end tag (this would allow for overlapping sections as well as being
able to keep an iteration open).
I'd really appreciate more comments, especially from the framework
committers as this only has value if project simple-methods are
allowed to be salted with <section-begin/section-end> tags.
----- Original Message ----
From: Jonathon -- Improov <[EMAIL PROTECTED]>
To: [email protected]
Sent: Friday, November 16, 2007 10:02:09 AM
Subject: Re: simple method subsections
Are you suggesting something like abstract classes in Java, where
some
methods are implemented and
some are not (blanks to be filled)?
Parameterized simple methods. Sounds interesting.
Some effort is needed to refactor the existing "OFBiz maintained"
simple methods to publish such
"hooks" where you can insert your own custom logics.
Because that kind of elegant refactor takes time, it is often easier
to
just hack it and get the
job done.
Unless we can identify numerous use cases for such elegant
mechanisms,
there's little ROI in doing
such fanciful stuff.
My choices are either to bring he recursion service into my custom
application and make the minor modification or to iterate back
through the list adding the result of the service and then sorting.
I would just reuse the recursion service "as is", and go through the
list with some
after-processing. Maximize reuse, minimize maintenance cost. Project
time frame is seldom less
than cruel!
If that ever becomes a performance bottle-neck, I'll then do
something
about it.
Jonathon
Chris Howe wrote:
Thanks for the reply. Scope isn't my problem. My problem is a
trade-off between code reuse and performance. Lets say I'm doing
one of the
recursive party relationship services that returns a list of related
parties, but I also need to run the partyNameForDate service before
adding it to the list and I need to sort by name before displaying
it on
the screen. My choices are either to bring he recursion service
into my
custom application and make the minor modification or to iterate back
through the list adding the result of the service and then sorting.
----- Original Message ----
From: Jonathon -- Improov <[EMAIL PROTECTED]>
To: [email protected]
Sent: Thursday, November 15, 2007 9:38:42 PM
Subject: Re: simple method subsections
Chris,
Have a look at a thread I started at
http://www.nabble.com/forum/ViewPost.jtp?post=10803536&framed=y .
You
also responded to that
thread too.
When you say "extend" a simple method, it might be easier to simply
think of how you would extend
a Java method. We would create a new method that first calls the old
method, and then perform some
custom actions after that (or the order could be flipped).
Your suggestion with "selective reuse of parts of a simple method"
would mean changing the
original method (by inserting <section-begin> <section-end>), to
"generic-ize" the original
method. Then you might as well not call it "extension", but
"customization" or "enhancement" or
"refactor" instead.
In that thread I pointed to, I had implemented a
<call-simple-method-scoped> which allows simple
methods to call other simple methods *exactly like how Java methods
can
call other Java methods*.
Unfortunately, the client I worked for now has exclusive rights to
that
new and convenient
artifact. :/
So what's the problem of having simple methods call other simple
methods now, you may ask? Scope
is all mixed up into a single bowl of alphabet soup, single
namespace.
For those of us who know
Java (or C or VB or just about any programming language at all), we
know this isn't conventional,
barely "right".
To offer a solution to your question, I've found that the only way
to
call other methods in
Minilang with proper scope (stored in call stack) is to use the
Service
Engine. Yeah, it means
that for every simple method you want to call, wrap them in a
service
and call the service instead.
Jonathon
Chris Howe wrote:
I'm looking for some feedback on an idea I'm tossing around
Problem: When creating a custom application, often times you will
be
creating business logic that is exactly like what is in OFBiz but
needs
to be slightly modified before sending it to the entity engine for
storage or before creating a result. (changing the way a price is
calculated, adding specialized field information, etc).
It would helpful to be able to call the OFBiz maintained method and
then extend it through a custom call.
A couple ideas on how to accomplish this
1) Add two new element groups,
<section-begin>
<section name="sectionA"/>
</section-begin
...some logic...
<section-end>
<section name="sectionA"/>
</section-end>
...more logic...
and salt the ofbiz method so that you can pull only the logic
between the two
2) mimic the screen-widget's decorator pattern
3) add a map of simple-methods to the method's context that allows
running extended code
extendMethod.myLocation#myMethod
and then salt the ofbiz method to call if it exist.
TIA for any thoughts
,Chris