Re: [RFC] simple method subsections

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] simple method subsections

cjhowe
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 <[hidden email]>
To: [hidden email]
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 <[hidden email]>
> To: [hidden email]
> 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
>>
>>
>>
>
>
>
>
>




Reply | Threaded
Open this post in threaded view
|

Re: [RFC] simple method subsections

David E Jones

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 <[hidden email]>
> To: [hidden email]
> 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 <[hidden email]>
>> To: [hidden email]
>> 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
>>>
>>>
>>>
>>
>>
>>
>>
>>
>
>
>
>


smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

getPaymentAppliedBd

SkipDever
In PaymentWorker.getPaymentAppliedBd() near line 280

I find this code:

paymentApplications = payment.getRelated("ToPaymentApplication");

There is no ToPaymentApplication entity that I can find.  Is this something
that should be removed or is there some plan to do something really cool.

It also causes log entries that are not really errors in my view.

Should I take this out and submit a patch?

Skip


Reply | Threaded
Open this post in threaded view
|

Re: getPaymentAppliedBd

David E Jones

In this method call "ToPaymentApplication" is a relationship name,  
made up of a prefix and the entity name.

For more info see:

http://ofbiz.apache.org/docs/entity.html

What kinds of log entries are you seeing?

-David



On Nov 16, 2007, at 3:12 PM, skip@thedevers wrote:

> In PaymentWorker.getPaymentAppliedBd() near line 280
>
> I find this code:
>
> paymentApplications = payment.getRelated("ToPaymentApplication");
>
> There is no ToPaymentApplication entity that I can find.  Is this  
> something
> that should be removed or is there some plan to do something really  
> cool.
>
> It also causes log entries that are not really errors in my view.
>
> Should I take this out and submit a patch?
>
> Skip
>
>


smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] simple method subsections

cjhowe
In reply to this post by cjhowe
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 <[hidden email]>
To: [hidden email]
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 <[hidden email]>
> To: [hidden email]
> 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 <[hidden email]>
>> To: [hidden email]
>> 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
>>>
>>>
>>>
>>
>>
>>
>>
>>
>
>
>
>




Reply | Threaded
Open this post in threaded view
|

Re: [RFC] simple method subsections

jonwimp
Wow, thanks for the detailed explanation!

This whole exercise sounds like "breaking up coarse-grained methods into fine-grained decoupled
flexible ones".

Then it should be nothing more than breaking up a giant simple method into independent pieces that
can be reused in many places. Why go through the trouble of creating a new mechanism for
"sectioned methods"? (In Java terms, it's like a simple method is a "class", and the sections are
like "methods".)

Suppose we have a huge method that has 3 sections that seem independent. We break it up into 3
separate methods. That's a refactor. We maintain the 3 separate methods in OFBiz. The 3 new
methods can be reused in hundreds of places in OFBiz. Well, if they are reused in only a few
places in OFBiz, then we had just done a refactor with bad ROI.

Ok, so what if our custom project can reuse the 3 methods in 100s of places, but OFBiz project
won't? Then we should do our own custom refactor, and break the giant method up into 3 methods. No
point doing the refactor in OFBiz where there's bad ROI.

As for overhead caused by "tiny little simple methods each requiring to be wrapped in a service",
that'll come back to the problem of Minilang methods not being able to call other Minilang methods
in the normal way that common programming languages do. If we come to this problem, we may talk
about this more.

Jonathon

Chris Howe wrote:

> 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 <[hidden email]>
> To: [hidden email]
> 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 <[hidden email]>
>> To: [hidden email]
>> 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 <[hidden email]>
>>> To: [hidden email]
>>> 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
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: [RFC] simple method subsections

cjhowe
In reply to this post by cjhowe
Thanks Jonathon for the reply.   While breaking giant methods up and refactoring may be the ideal solution, I'm a bit of a realist and understand that approach will never happen in any community project with enough regularity and discipline to not be consistent roadblocks in an external development.   The speed at which OFBiz moves in adding features and use cases is too valuable to copy and paste the desired code snippet into a custom application that then has to be maintained wholly by an individual business.  If I were to refactor a simple method and delivered a patch right this moment, it would be two to six weeks before someone reviewed sufficiently to ensure it worked as expected.  However, if I were to submit a patch that simply added inert markup, no review would be necessary, because it doesn't do anything to OFBiz.

OT: It's interesting to note people's backgrounds and how they think about problems.  Jonathon obviously has a java background and is fixated on scope and classes.  I have a molecular biology background and the solution that I'm proposing follows the start and stop codon methodology of DNA and protein transcription.  It's kind of cool to bounce these ideas off different mindsets.

----- Original Message ----
From: Jonathon -- Improov <[hidden email]>
To: [hidden email]
Sent: Friday, November 16, 2007 9:37:48 PM
Subject: Re: [RFC] simple method subsections

Wow, thanks for the detailed explanation!

This whole exercise sounds like "breaking up coarse-grained methods
 into fine-grained decoupled
flexible ones".

Then it should be nothing more than breaking up a giant simple method
 into independent pieces that
can be reused in many places. Why go through the trouble of creating a
 new mechanism for
"sectioned methods"? (In Java terms, it's like a simple method is a
 "class", and the sections are
like "methods".)

Suppose we have a huge method that has 3 sections that seem
 independent. We break it up into 3
separate methods. That's a refactor. We maintain the 3 separate methods
 in OFBiz. The 3 new
methods can be reused in hundreds of places in OFBiz. Well, if they are
 reused in only a few
places in OFBiz, then we had just done a refactor with bad ROI.

Ok, so what if our custom project can reuse the 3 methods in 100s of
 places, but OFBiz project
won't? Then we should do our own custom refactor, and break the giant
 method up into 3 methods. No
point doing the refactor in OFBiz where there's bad ROI.

As for overhead caused by "tiny little simple methods each requiring to
 be wrapped in a service",
that'll come back to the problem of Minilang methods not being able to
 call other Minilang methods
in the normal way that common programming languages do. If we come to
 this problem, we may talk
about this more.

Jonathon



Reply | Threaded
Open this post in threaded view
|

Re: [RFC] simple method subsections

jonwimp
Inert markup still needs an engine to process those markup. That'll take time to review. As I
said, the elegant generic-ized mechanism is more complex than just "hacking it and getting job done".

Refactoring a giant simple method into 3 smaller simple methods may not need much review effort.
Not a lot of change propagation required. Ie, we don't need to hunt down all of OFBiz for codes
that call the giant method.

It's just about object-oriented programming or simple abstraction. Yeah, it's IT terms, not
biology. I'm looking to study varsity-level Chemistry and jump to molecular biology right now, by
the way! Curious. :)

Say the giant method is named "GiantMethod". Say there are 100s of areas in OFBiz that calls
GiantMethod. We won't need to affect those 100s of areas. How?

We retain the GiantMethod's signature. We take out GiantMethod's insides, and split them into 3
separate methods named "SmallMethodA", "SmallMethodB", and "SmallMethodC". We rewrite GiantMethod
to call those 3 smaller methods.

The review effort is small. We just need to make sure that the new GiantMethod still functions
exactly the same as the old GiantMethod.

Your custom codes can now call on any combination of the 3 separate methods.

You know, maybe we can help each other. You get me into the bioengineering field, and I'll do what
I can for you in the IT field. What say you? :)

Jonathon

Chris Howe wrote:

> Thanks Jonathon for the reply.   While breaking giant methods up and refactoring may be the ideal solution, I'm a bit of a realist and understand that approach will never happen in any community project with enough regularity and discipline to not be consistent roadblocks in an external development.   The speed at which OFBiz moves in adding features and use cases is too valuable to copy and paste the desired code snippet into a custom application that then has to be maintained wholly by an individual business.  If I were to refactor a simple method and delivered a patch right this moment, it would be two to six weeks before someone reviewed sufficiently to ensure it worked as expected.  However, if I were to submit a patch that simply added inert markup, no review would be necessary, because it doesn't do anything to OFBiz.
>
> OT: It's interesting to note people's backgrounds and how they think about problems.  Jonathon obviously has a java background and is fixated on scope and classes.  I have a molecular biology background and the solution that I'm proposing follows the start and stop codon methodology of DNA and protein transcription.  It's kind of cool to bounce these ideas off different mindsets.
>
> ----- Original Message ----
> From: Jonathon -- Improov <[hidden email]>
> To: [hidden email]
> Sent: Friday, November 16, 2007 9:37:48 PM
> Subject: Re: [RFC] simple method subsections
>
> Wow, thanks for the detailed explanation!
>
> This whole exercise sounds like "breaking up coarse-grained methods
>  into fine-grained decoupled
> flexible ones".
>
> Then it should be nothing more than breaking up a giant simple method
>  into independent pieces that
> can be reused in many places. Why go through the trouble of creating a
>  new mechanism for
> "sectioned methods"? (In Java terms, it's like a simple method is a
>  "class", and the sections are
> like "methods".)
>
> Suppose we have a huge method that has 3 sections that seem
>  independent. We break it up into 3
> separate methods. That's a refactor. We maintain the 3 separate methods
>  in OFBiz. The 3 new
> methods can be reused in hundreds of places in OFBiz. Well, if they are
>  reused in only a few
> places in OFBiz, then we had just done a refactor with bad ROI.
>
> Ok, so what if our custom project can reuse the 3 methods in 100s of
>  places, but OFBiz project
> won't? Then we should do our own custom refactor, and break the giant
>  method up into 3 methods. No
> point doing the refactor in OFBiz where there's bad ROI.
>
> As for overhead caused by "tiny little simple methods each requiring to
>  be wrapped in a service",
> that'll come back to the problem of Minilang methods not being able to
>  call other Minilang methods
> in the normal way that common programming languages do. If we come to
>  this problem, we may talk
> about this more.
>
> Jonathon
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

RE: getPaymentAppliedBd

SkipDever
In reply to this post by David E Jones
David

Thanks, I finally get this.

Skip

-----Original Message-----
From: David E Jones [mailto:[hidden email]]
Sent: Friday, November 16, 2007 2:44 PM
To: [hidden email]
Subject: Re: getPaymentAppliedBd



In this method call "ToPaymentApplication" is a relationship name,  
made up of a prefix and the entity name.

For more info see:

http://ofbiz.apache.org/docs/entity.html

What kinds of log entries are you seeing?

-David



On Nov 16, 2007, at 3:12 PM, skip@thedevers wrote:

> In PaymentWorker.getPaymentAppliedBd() near line 280
>
> I find this code:
>
> paymentApplications = payment.getRelated("ToPaymentApplication");
>
> There is no ToPaymentApplication entity that I can find.  Is this  
> something
> that should be removed or is there some plan to do something really  
> cool.
>
> It also causes log entries that are not really errors in my view.
>
> Should I take this out and submit a patch?
>
> Skip
>
>