ant elder wrote:
[snip]
With the change in r442461 you say ComponentType files are now
optional and
the Ruby implementation now automatically creates a default
serviceType and
referenceTypes as needed. Could you say a bit about how that works so we
can try and do the same for the Java runtime?
...ant
The RubyCalculator sample under
http://svn.apache.org/repos/asf/incubator/tuscany/cpp/sca/samples/RubyCalculator/sample.calculator/
shows the programming model for Ruby, as implemented in the Tuscany/C++
Ruby extension:
- A client can get a proxy to a service with:
require("libtuscany_sca_ruby")
and
calculator = SCA::locateService("CalculatorComponent/CalculatorService")
- You then simply call a business method on "calculator", like this:
x = calculator.add(1, 2)
- A Ruby component is implemented by either functions in a Ruby module
or a Ruby class, like this:
<component name="CalculatorComponent">
<implementation.ruby script="CalculatorImpl.rb"
class="CalculatorImpl"/>
</component>
- Public attributes of a Ruby component implementation class can be
wired to target services, like this:
class CalculatorImpl
attr_writer :divideService
def div(arg1, arg2)
print "Ruby - CalculatorImpl.div\n"
@divideService.divide(arg1, arg2)
end
end
and in your composite file:
<component name="CalculatorComponent">
<implementation.ruby script="CalculatorImpl.rb" class="CalculatorImpl"/>
<reference
name="divideService">DivideComponent/DivideService</reference>
</component>
- Public attributes of a Ruby component implementation class can be
configured as component properties, like this:
class DivideImpl
attr_writer :round
def divide(arg1, arg2)
res = arg1.to_f / arg2.to_f
if @round then
res = res.round
end
res
end
and in your composite file:
<component name="DivideComponent">
<implementation.ruby script="DivideImpl.rb" class="DivideImpl"/>
<property name="round">true</property>
</component>
Lastly, you can write a componentType file for your Ruby component, but
you don't have to, the Ruby extension introspects Ruby component
implementation classes for you and binds public attributes to references
and properties.
The runtime extension uses the Ruby C API. The Ruby interpreter is
written in C with a nice API so it's a pretty good fit. I'm not sure how
much of the design you can transpose to JRuby, but here's a summary:
- The Tuscany C++ Ruby extension embeds the Ruby interpreter. This
allows the runtime to run a Ruby component from any other SCA component,
the Axis2 HTTP server or the Axis2 Apache mod when running behind the
HTTP server.
- The extension also acts as a Ruby extension library, to allow
standalone Ruby scripts to invoke SCA services.
- SCA::locateService is declared to Ruby as a module function in module
SCA. Again I am using the Ruby C API to declare the module and the function.
- I am also using the Ruby C API to introspect each Ruby component
implementation class, find public setter methods, and the Ruby
attributes to SCA references and properties.
- SCA references are handled by a Ruby proxy class, defined by the
extension (written in C), which exposes a Ruby interface and dispatches
all calls to the C++ runtime to handle the SCA invocation.
- The extension currently handles the conversion of simple types between
Ruby and C types. I'll probably map DataObjects to Ruby strings for now
unless somebody is interested in implementing an SDO Ruby language binding.
The code of the Tuscany/C++ Ruby extension is there:
http://svn.apache.org/repos/asf/incubator/tuscany/cpp/sca/runtime/extensions/ruby/
Hope this helps...
--
Jean-Sebastien
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]