Okay, I lied - the bindings are preserved between evaluations.
So go ahead and make whatever changes you need to make.
-Adrian
On 3/14/2012 5:28 AM, Adrian Crum wrote:
The main reason is to supply a function/method argument if
modelService.invoke is not empty.
A script containing a function/method is evaluated twice - once to
evaluate the script as a whole and then again to invoke the
function/method. Any bindings that were created/used in the first
evaluation are lost in the function/method call - so the bindings are
passed as a function/method call argument.
I will update JavaScriptTest.js to illustrate the difference.
-Adrian
On 3/14/2012 5:18 AM, Jacopo Cappellato wrote:
Adrian,
is there a reason for invoking the script from ScriptEngine and
ScriptEventHandler using:
Object resultObj =
ScriptUtil.executeScript(getLocation(modelService),
modelService.invoke, scriptContext, new Object[] { context });
rather than
Object resultObj =
ScriptUtil.executeScript(getLocation(modelService),
modelService.invoke, scriptContext, null);
I don't know what the args argument is used for but now we have to
declare all the Groovy methods (events and services) in this way:
def setLastInventoryCount(Map notUsedInputMap) {
...
}
rather than
def setLastInventoryCount() {
...
}
and I really like the latter form because it is essential and non
technical: the service/event *only* contains business rules
specifications.
Any objections if I change the service/event handlers to pass a null
args?
Please also see my comments inline:
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.
Np, the code is young and I am happy to help to test/debug it.
I'm pretty sure I followed good concurrency practices overall, but
there is always a chance I missed something.
Ok, I didn't look enough closely at the details and in fact it may be
good to go.
Jacopo
-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