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]

Reply via email to