Adrian, all,

I am summarizing here the results of my initial tests of the Groovy service and 
event executed by Adrian's  Script* classes (using JSR-223).

First of all, here are the service and events updated to work with the new code 
(they run with the latest enhancements I committed to framework code):

=====================================================================
import org.ofbiz.base.util.UtilDateTime
import org.ofbiz.entity.util.EntityUtil

// THIS IS A SERVICE
def setLastInventoryCount() {
    inventoryItem = ofbiz.findOne('InventoryItem')
    if (!inventoryItem) {
        ofbiz.logWarning("The InventoryItem with 
inventoryItemId=${parameters.inventoryItemId} doesn't exist.")
        return ofbiz.failure("Inventory item with id 
${parameters.inventoryItemId} was not found.")
    }
    List productFacilities = ofbiz.findList('ProductFacility', 
[productId:inventoryItem.productId, facilityId:inventoryItem.facilityId])
    productFacilities.each {
        countResult = ofbiz.runService('getInventoryAvailableByFacility', 
[productId:it.productId, facilityId: it.facilityId])
        result = ofbiz.runService('updateProductFacility', 
[productId:it.productId, facilityId:it.facilityId, 
lastInventoryCount:countResult.availableToPromiseTotal])
    }
    return ofbiz.success("Updated inventory count for product 
${inventoryItem.productId}.")
}

// THIS IS AN EVENT
def updateProductCategoryMember() {
    thruDate = parameters.thruDate
    if (!thruDate) {
        thruDate = UtilDateTime.nowTimestamp()
    }
    try {
        productCategoryMember = 
EntityUtil.getFirst(EntityUtil.filterByDate(ofbiz.findList('ProductCategoryMember',
 [productCategoryId: parameters.productCategoryId, productId: 
parameters.productId])))
        if (productCategoryMember) {
            productCategoryMember.setString('thruDate', thruDate)
            productCategoryMember.store()
        }
    } catch(Exception e) {
        return ofbiz.error("The following error occurred setting thruDate on 
category ${parameters.productCategoryId} for product ${parameters.productId}: 
${e.getMessage()}")
    }
    return ofbiz.success("Set thruDate ${thruDate} on category 
${parameters.productCategoryId} for product ${parameters.productId}")
}
=====================================================================

And here are some comments, each with a face to highlight the result:
:-)  good
:-/  so and so
:-( bad

* the code above is the whole content of the file I have created: as you can 
see is still very clear: no need to declare classes, define accessors; you 
simply have to write the business logic
** :-)
* after the switch to JSR-223 the "DSL method" are accessed thru the "ofbiz" 
reference (instead of being directly available as method calls)
** :-/  (because of the small added complexity) but also :-) because now the 
IDE is able to autocomplete the method calls to the "ofbiz" object (with a 
small tweak that I will explain); this is actually a nice to have feature
* after the switch to JSR-223 the debugger of my IDE (Idea) is no more able to 
walk the Groovy services and events; it is working like a charm when using the 
Groovy specific service engine and event handler
** :-( this is really a bummer! is this only an issue with Idea? is it working 
with Eclipse? Need to research on this

The summary is:
* the new mechanism works fine and still allows to implement very nice services 
and events; this is really good
* the debug issue is rather big one (the lack of debugging tools for Minilang 
was one of the most frequent complains) but this is an issue that can be 
researched/addressed and shouldn't block the evaluation/adoption of this "new" 
language for services/events; even if we will fail to find a solution we could 
easily run the Groovy services/events using the custom engine/handler and this 
will not require any code change to the services/events

Next step:
it would be really nice to continue this proof of concepts by converting some 
interesting Java services/events and Minilang services/events to Groovy: this 
will help to complete the ScriptHelper classes and greatly help to appreciate 
pros and cons.
Is there any interest in this effort? I see a big potential in this approach, 
but the opinion from the community will be important.

Kind regards,

Jacopo



On Mar 13, 2012, at 4:59 PM, Adrian Crum wrote:

> Cool - thanks! My apologies - I had not given much thought to the object 
> construction sequence in that section of code.
> 
> I'm pretty sure I followed good concurrency practices overall, but there is 
> always a chance I missed something.
> 
> -Adrian
> 
> On 3/13/2012 3:49 PM, Jacopo Cappellato wrote:
>> This is now fixed in rev. 1300202
>> By the way: we will need to carefully review the way 
>> ScriptHelper/ContextHelper are built (and especially how the context is 
>> passed) in order to make sure the code is thread safe.
>> 
>> Jacopo
>> 
>> On Mar 13, 2012, at 11:42 AM, Jacopo Cappellato wrote:
>> 
>>> Ok thanks... it doesn't work for me because the scriptType is set to 
>>> UNKNOWN instead of SERVICE... I am debugging it now.
>>> 
>>> Jacopo
>>> 
>>> On Mar 13, 2012, at 11:16 AM, Adrian Crum wrote:
>>> 
>>>> org.ofbiz.service.engine.ScriptEngine.java, line 85 and below.
>>>> 
>>>> -Adrian
>>>> 
>>>> On 3/13/2012 10:11 AM, Jacopo Cappellato wrote:
>>>>> Hey Adrian,
>>>>> 
>>>>> a quick question before I dig into the details.
>>>>> I am using the success(..)/error(...) methods to get a result Map (for 
>>>>> services) or result String (for Events) and I have noticed that in the 
>>>>> new implementation they are saved using the ContextHelper.putResults 
>>>>> method.
>>>>> Who is supposed to call the ContextHelper.getResults() method? It would 
>>>>> be nice if this was done automatically by the framework (service/event 
>>>>> handlers) rather than the script itself... but I am testing it with a 
>>>>> service and I can't get the message back.
>>>>> If you could show me a code snippet it would help... if not do not worry 
>>>>> I will figure it out.
>>>>> 
>>>>> Thanks,
>>>>> 
>>>>> Jacopo
>>>>> 
>>>>> On Mar 13, 2012, at 8:58 AM, Adrian Crum wrote:
>>>>> 
>>>>>> On 3/13/2012 7:46 AM, Jacopo Cappellato wrote:
>>>>>>> On Mar 13, 2012, at 7:59 AM, Adrian Crum wrote:
>>>>>>> 
>>>>>>>> Jacopo,
>>>>>>>> 
>>>>>>>> Could you share with the rest of us the limitations caused by the 
>>>>>>>> refactoring?
>>>>>>>> 
>>>>>>> Definitely: I will review, study and use the new code and I will 
>>>>>>> provide feedback about the gaps I see.
>>>>>> Oh. I thought you were talking about the ScriptUtil refactoring.
>>>>>> 
>>>>>>> One thing that I am not sure I like is the fact that now some of the 
>>>>>>> strings in Groovy will be expanded using the FlexibleStringExpander 
>>>>>>> rather than the Groovy GStrings... this could be confusing when you are 
>>>>>>> programming in Groovy.
>>>>>>> I was also planning to use closures to manage nicely 
>>>>>>> EntityListIterators... but I can probably still do this in the 
>>>>>>> GroovyBaseScript.
>>>>>>> 
>>>>>>>> The work I committed is just a springboard - anyone can modify 
>>>>>>>> it/extend it in any way they want.
>>>>>>> Ok, this is good... and dangerous if anyone will add what they want 
>>>>>>> without first agreeing/understanding on the purpose of this class. Do 
>>>>>>> we all agree that it should stay clean and light by providing simple 
>>>>>>> access for common operations rather than providing access to all the 
>>>>>>> possible operations? I mean, it should provide a mechanism to perform 
>>>>>>> tasks in the most common ways; for special (less frequent) tasks the 
>>>>>>> calling script should use the features provided natively by the 
>>>>>>> language and the standard API (delegator/dispatcher/etc...).
>>>>>> I agree. Let's keep the API limited to OFBiz-specific artifacts: entity 
>>>>>> engine, service engine, logging, etc.
>>>>>> 
>>>>>>>> As I mentioned previously, the GroovyBaseScript class can simply 
>>>>>>>> delegate to the helper class:
>>>>>>> Yes, I will re-implement it following this design and let you know how 
>>>>>>> it goes; but we will still need the Groovy service engine and Groovy 
>>>>>>> event handlers... in order to keep the architecture clean should we 
>>>>>>> start to think to them as extensions for the applications only? I mean 
>>>>>>> that they could be part of the future release of "OFBiz Applications" 
>>>>>>> and not part of the future release "OFBiz Framework". In this way the 
>>>>>>> dependency and custom Groovy code will all be in the Applications (if 
>>>>>>> they will be reimplemented in Groovy) and the framework will stay clean 
>>>>>>> and light.
>>>>>> I was planning on having mini-lang's MethodContext extend ScriptHelper 
>>>>>> so all scripting languages (including mini-lang) are running on the same 
>>>>>> code base.
>>>>>> 
>>>>>> I'm thinking all of this will tie up rather nicely once we have a 
>>>>>> reduced framework. Scripting can be its own component that runs on top 
>>>>>> of the new framework. Higher-level applications can then extend the 
>>>>>> scripting component
>>>>>> 
>>>>>> 
>>>>>>> Jacopo
>>>>>>> 
>>>>>>>> abstract class GroovyBaseScript extends Script implements ScriptHelper 
>>>>>>>> {
>>>>>>>>   ...
>>>>>>>> 
>>>>>>>>   private final ScriptHelper helper;
>>>>>>>> 
>>>>>>>>   Map runService(String serviceName, Map inputMap) throws 
>>>>>>>> ScriptException {
>>>>>>>>       return helper.runService(serviceName, inputMap);
>>>>>>>>   }
>>>>>>>> 
>>>>>>>>   Map makeValue(String entityName) throws ScriptException {
>>>>>>>>       return helper.makeValue(entityName);
>>>>>>>>   }
>>>>>>>> 
>>>>>>>>   ...
>>>>>>>> 
>>>>>>>> }
>>>>>>>> 
>>>>>>>> -Adrian
>>>>>>>> 
>>>>>>>> 
>>>>>>>> On 3/13/2012 5:49 AM, Jacopo Cappellato wrote:
>>>>>>>>> Adrian, thank you for your work.
>>>>>>>>> 
>>>>>>>>> What I was writing was actually an extension to Groovy for making it 
>>>>>>>>> OFBiz friendly; now we have a "reusable" (? by other languages) 
>>>>>>>>> version of it... my guess is that you did it because you liked the 
>>>>>>>>> ideas in it (and I appreciate it) and you thought it was useful for 
>>>>>>>>> other languages as well; and you may be right about this even if, as 
>>>>>>>>> I initially mentioned, I would have preferred to complete my work, or 
>>>>>>>>> at least add a bit more to it, test the DSL with more poc and 
>>>>>>>>> Minilang-->Groovy conversions before crystallizing it into an 
>>>>>>>>> interface (one of the advantages in doing it in Groovy was that I 
>>>>>>>>> could implement it without the need to build/restart the system)... 
>>>>>>>>> now I have an interface and an implementation of it to take care of.
>>>>>>>>> But I don't want to complain (*) and I will review your work closely 
>>>>>>>>> and see what I can do to use it properly in Groovy. This refactoring 
>>>>>>>>> has introduced a series of limitations that I am determined to 
>>>>>>>>> resolve and it will require some more study around Groovy and ideas 
>>>>>>>>> to cope with them... I really want that, if we will ever adopt Groovy 
>>>>>>>>> as our next language for the applications, it will look as perfect 
>>>>>>>>> and simple and natural and integrated as possible: the natural 
>>>>>>>>> language for OFBiz (like Minilang is now) rather than OFBiz 
>>>>>>>>> implemented in Groovy.
>>>>>>>>> 
>>>>>>>>> But before I proceed: what is the next step in your plan? What should 
>>>>>>>>> go in the ScriptHelper interface? Am I allowed to enhance it based on 
>>>>>>>>> my discoveries in my poc work (Minilang-->Groovy) or should I 
>>>>>>>>> consider it a final interface that doesn't have to be modified? 
>>>>>>>>> Should I ask before enhancing it? I don't want to hijack your work. 
>>>>>>>>> And more importantly: can I assume that this helper class will stay 
>>>>>>>>> light and simple? I really don't want to see it transformed into a 
>>>>>>>>> huge class containing a big amount of methods from different APIs... 
>>>>>>>>> the fact that all languages will potentially use it and may wish to 
>>>>>>>>> extend it with util methods that make sense to them concerns me a 
>>>>>>>>> little bit (for example, a language with weak support for Map 
>>>>>>>>> handling may need utils methods to manage Maps that could be useless 
>>>>>>>>> for Groovy).
>>>>>>>>> 
>>>>>>>>> Kind regards and again thank you,
>>>>>>>>> 
>>>>>>>>> Jacopo
>>>>>>>>> 
>>>>>>>>> (*) even if I find a bit annoying to see my work intercepted and 
>>>>>>>>> re-routed while I was in the middle of it, I also appreciate the time 
>>>>>>>>> and effort you spent on it and I really want to accept the fact that 
>>>>>>>>> working in a community means that I have to blend and negotiate my 
>>>>>>>>> own ideas and plans with the ones from others: sometimes it means 
>>>>>>>>> that you get great help, sometimes it means that your own beautiful 
>>>>>>>>> and perfect ideas are touched and rearranged to fit other's plans and 
>>>>>>>>> other's beautiful ideas.
>>>>>>>>> I hope that the good attitude and flexibility I am trying to apply 
>>>>>>>>> here will be also used by you and others when it will be time for you 
>>>>>>>>> to accept other's proposals/changes
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> On Mar 13, 2012, at 12:35 AM, Adrian Crum wrote:
>>>>>>>>> 
>>>>>>>>>> Jacopo,
>>>>>>>>>> 
>>>>>>>>>> I committed a generic, reusable version of this idea in rev 1299924.
>>>>>>>>>> 
>>>>>>>>>> -Adrian
>>>>>>>>>> 
>>>>>>>>>> On 3/8/2012 6:02 PM, Jacopo Cappellato wrote:
>>>>>>>>>>> Hi all,
>>>>>>>>>>> 
>>>>>>>>>>> I have just completed my first pass in the implementation of a DSL 
>>>>>>>>>>> (Domain Specific Language) for OFBiz that can be used by Groovy 
>>>>>>>>>>> services to act like a modern version of Minilang.
>>>>>>>>>>> 
>>>>>>>>>>> Please review my notes here:
>>>>>>>>>>> 
>>>>>>>>>>> https://cwiki.apache.org/confluence/display/OFBIZ/Groovy+Services+and+DSL+for+OFBiz
>>>>>>>>>>> 
>>>>>>>>>>> I look forward to your comments and feedback but please consider 
>>>>>>>>>>> that 1) it is a work in progress, 2) I spent a lot of time and 
>>>>>>>>>>> mental energy in the effort (reaching simplicity is really complex 
>>>>>>>>>>> task!)... so please don't be too picky :-)
>>>>>>>>>>> 
>>>>>>>>>>> Regards,
>>>>>>>>>>> 
>>>>>>>>>>> Jacopo
>>>>>>>>>>> 
>>>>>>>>>>> PS: if you find it useful, I can commit the Groovy service 
>>>>>>>>>>> mentioned in the page in Confluence

Reply via email to