PROTON-799: Added the Event classes to the Ruby engine APIs.

Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/3ae96328
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/3ae96328
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/3ae96328

Branch: refs/heads/ruby-engine-apis
Commit: 3ae96328538972ef50d3672138fce33ba1147936
Parents: 5b9e8ff
Author: Darryl L. Pierce <mcpie...@gmail.com>
Authored: Tue Feb 3 17:17:18 2015 -0500
Committer: Darryl L. Pierce <mcpie...@gmail.com>
Committed: Tue May 19 08:03:54 2015 -0400

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/event/event.rb      | 296 ++++++++++++++++++++
 proton-c/bindings/ruby/lib/event/event_base.rb |  91 ++++++
 proton-c/bindings/ruby/lib/event/event_type.rb |  71 +++++
 proton-c/bindings/ruby/lib/qpid_proton.rb      |   3 +
 4 files changed, 461 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/3ae96328/proton-c/bindings/ruby/lib/event/event.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/event/event.rb 
b/proton-c/bindings/ruby/lib/event/event.rb
new file mode 100644
index 0000000..dd5d869
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/event/event.rb
@@ -0,0 +1,296 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid::Proton
+
+  module Event
+
+    # @private
+    def self.event_type(const_name, method_name = nil) # :nodoc:
+      unless Cproton.const_defined?(const_name)
+        raise RuntimeError.new("no such constant: #{const_name}")
+      end
+
+      const_value = Cproton.const_get(const_name)
+      method_name = "on_#{const_name.to_s[3..-1]}".downcase if method_name.nil?
+
+      EventType.new(const_value, method_name)
+    end
+
+    # Defined as a programming convenience. No even of this type will ever
+    # be generated.
+    NONE = event_type(:PN_EVENT_NONE)
+
+    # A timer event has occurred.
+    TIMER_TASK = event_type(:PN_TIMER_TASK)
+
+    # A connection has been created. This is the first even that will ever
+    # be issued for a connection.
+    CONNECTION_INIT = event_type(:PN_CONNECTION_INIT)
+    # A conneciton has been bound toa  transport.
+    CONNECTION_BOUND = event_type(:PN_CONNECTION_BOUND)
+    # A connection has been unbound from its transport.
+    CONNECTION_UNBOUND = event_type(:PN_CONNECTION_UNBOUND)
+    # A local connection endpoint has been opened.
+    CONNECTION_LOCAL_OPEN = event_type(:PN_CONNECTION_LOCAL_OPEN)
+    # A local connection endpoint has been closed.
+    CONNECTION_LOCAL_CLOSE = event_type(:PN_CONNECTION_LOCAL_CLOSE)
+    # A remote endpoint has opened its connection.
+    CONNECTION_REMOTE_OPEN = event_type(:PN_CONNECTION_REMOTE_OPEN)
+    # A remote endpoint has closed its connection.
+    CONNECTION_REMOTE_CLOSE = event_type(:PN_CONNECTION_REMOTE_CLOSE)
+    # A connection has been freed and any outstanding processing has been
+    # completed. This is the final event htat will ever be issued for a
+    # connection
+    CONNECTION_FINAL = event_type(:PN_CONNECTION_FINAL)
+
+    # A session has been created. This is the first event that will ever be
+    # issues for a session.
+    SESSION_INIT = event_type(:PN_SESSION_INIT)
+    # A local session endpoint has been opened.
+    SESSION_LOCAL_OPEN = event_type(:PN_SESSION_LOCAL_OPEN)
+    # A local session endpoint has been closed.
+    SESSION_LOCAL_CLOSE = event_type(:PN_SESSION_LOCAL_CLOSE)
+    # A remote endpoint has opened its session.
+    SESSION_REMOTE_OPEN = event_type(:PN_SESSION_REMOTE_OPEN)
+    # A remote endpoint has closed its session.
+    SESSION_REMOTE_CLOSE = event_type(:PN_SESSION_REMOTE_CLOSE)
+    # A session has been freed and any outstanding processing has been
+    # completed. This is the final event that will ever be issued for a
+    # session
+    SESSION_FINAL = event_type(:PN_SESSION_FINAL)
+
+    # A link has been created. This is the first event that will ever be
+    # issued for a link.
+    LINK_INIT = event_type(:PN_LINK_INIT)
+    # A local link endpoint has been opened.
+    LINK_LOCAL_OPEN = event_type(:PN_LINK_LOCAL_OPEN)
+    # A local link endpoint has been closed.
+    LINK_LOCAL_CLOSE = event_type(:PN_LINK_LOCAL_CLOSE)
+    # A local link endpoint has been detached.
+    LINK_LOCAL_DETACH = event_type(:PN_LINK_LOCAL_DETACH)
+    # A remote endpoint has opened its link.
+    LINK_REMOTE_OPEN = event_type(:PN_LINK_REMOTE_OPEN)
+    # A remote endpoint has closed its link.
+    LINK_REMOTE_CLOSE = event_type(:PN_LINK_REMOTE_CLOSE)
+    # A remote endpoint has detached its link.
+    LINK_REMOTE_DETACH = event_type(:PN_LINK_REMOTE_DETACH)
+    # The flow control state for a link has changed.
+    LINK_FLOW = event_type(:PN_LINK_FLOW)
+    # A link has been freed and any outstanding processing has been completed.
+    # This is the final event htat will ever be issued for a link.
+    LINK_FINAL = event_type(:PN_LINK_FINAL)
+
+    # A delivery has been created or updated.
+    DELIVERY = event_type(:PN_DELIVERY)
+
+    # A transport has new data to read and/or write.
+    TRANSPORT = event_type(:PN_TRANSPORT)
+    # Indicates that a transport error has occurred.
+    # @see Transport#condition To access the details of the error.
+    TRANSPORT_ERROR = event_type(:PN_TRANSPORT_ERROR)
+    # Indicates that the head of a transport has been closed. This means the
+    # transport will never produce more bytes for output to the network.
+    TRANSPORT_HEAD_CLOSED = event_type(:PN_TRANSPORT_HEAD_CLOSED)
+    # Indicates that the trail of a transport has been closed. This means the
+    # transport will never be able to process more bytes from the network.
+    TRANSPORT_TAIL_CLOSED = event_type(:PN_TRANSPORT_TAIL_CLOSED)
+    # Indicates that both the head and tail of a transport are closed.
+    TRANSPORT_CLOSED = event_type(:PN_TRANSPORT_CLOSED)
+
+    SELECTABLE_INIT = event_type(:PN_SELECTABLE_INIT)
+    SELECTABLE_UPDATED = event_type(:PN_SELECTABLE_UPDATED)
+    SELECTABLE_READABLE = event_type(:PN_SELECTABLE_READABLE)
+    SELECTABLE_WRITABLE = event_type(:PN_SELECTABLE_WRITABLE)
+    SELECTABLE_EXPIRED = event_type(:PN_SELECTABLE_EXPIRED)
+    SELECTABLE_ERROR = event_type(:PN_SELECTABLE_ERROR)
+    SELECTABLE_FINAL = event_type(:PN_SELECTABLE_FINAL)
+
+    # An Event provides notification of a state change within the protocol
+    # engine.
+    #
+    # Every event has a type that identifies what sort of state change has
+    # occurred, along with a pointer to the object whose state has changed,
+    # and also any associated objects.
+    #
+    # For more details on working with Event, please refer to Collector.
+    #
+    # @see Qpid::Proton::Event The list of predefined events.
+    #
+    class Event < EventBase
+
+      # @private
+      include Qpid::Proton::Util::ClassWrapper
+      # @private
+      include Qpid::Proton::Util::Wrapper
+
+      # Creates a Ruby object for the given pn_event_t.
+      #
+      # @private
+      def self.wrap(impl, number = nil)
+        return nil if impl.nil?
+
+        result = self.fetch_instance(impl, :pn_event_attachments)
+        return result unless result.nil?
+        number = Cproton.pn_event_type(impl) if number.nil?
+        event = Event.new(impl, number)
+        return event.context if event.context.is_a? EventBase
+        return event
+      end
+
+      # @private
+      def initialize(impl, number)
+        @impl = impl
+        class_name = Cproton.pn_class_name(Cproton.pn_event_class(impl))
+        context = class_wrapper(class_name, Cproton.pn_event_context(impl))
+        event_type = EventType.by_type(Cproton.pn_event_type(impl))
+        super(class_name, context, event_type)
+        @type = EventType.by_type(number)
+        self.class.store_instance(self, :pn_event_attachments)
+      end
+
+      # Notifies the handler(s) of this event.
+      #
+      # If a handler responds to the event's method then that method is invoked
+      # and passed the event. Otherwise, if the handler defines the
+      # +on_unhandled+ method, then that will be invoked instead.
+      #
+      # If the handler defines a +handlers+ method then that will be invoked 
and
+      # passed the event afterward.
+      #
+      # @example
+      #
+      #   class FallbackEventHandler
+      #
+      #     # since it now defines a handlers method, any event will iterate
+      #     # through them and invoke the +dispatch+ method on each
+      #     attr_accessor handlers
+      #
+      #     def initialize
+      #       @handlers = []
+      #     end
+      #
+      #     # invoked for any event not otherwise handled
+      #     def on_unhandled(event)
+      #       puts "Unable to invoke #{event.type.method} on #{event.context}."
+      #     end
+      #
+      #   end
+      #
+      # @param handler [Object] An object which implements either the event's
+      #    handler method or else responds to :handlers with an array of other
+      #    handlers.
+      #
+      def dispatch(handler, type = nil)
+        type = @type if type.nil?
+        #notify any and all attached handlers
+        if handler.respond_to?(:handlers?) && handler.handlers?
+          handler.handlers.each {|hndlr| self.dispatch(hndlr, type)}
+        end
+        if handler.respond_to?(type.method)
+          handler.__send__(type.method, self)
+        elsif handler.respond_to?(:on_unhandled)
+          handler.on_unhandled(self)
+        end
+      end
+
+      # Returns the transport for this event.
+      #
+      # @return [Transport, nil] The transport.
+      #
+      def transport
+        Qpid::Proton::Transport.wrap(Cproton.pn_event_transport(@impl))
+      end
+
+      # Returns the Connection for this event.
+      #
+      # @return [Connection, nil] The connection.
+      #
+      def connection
+        Qpid::Proton::Connection.wrap(Cproton.pn_event_connection(@impl))
+      end
+
+      # Returns the Session for this event.
+      #
+      # @return [Session, nil] The session
+      #
+      def session
+        Qpid::Proton::Session.wrap(Cproton.pn_event_session(@impl))
+      end
+
+      # Returns the Link for this event.
+      #
+      # @return [Link, nil] The link.
+      #
+      def link
+        Qpid::Proton::Link.wrap(Cproton.pn_event_link(@impl))
+      end
+
+      # Returns the Sender, or nil if there is no Link, associated  with this
+      # event if that link is a sender.
+      #
+      # @return [Sender, nil] The sender.
+      #
+      def sender
+        return self.link if !self.link.nil? && self.link.sender?
+      end
+
+      # Returns the Receiver, or nil if there is no Link, associated with this
+      # event if that link is a receiver.
+      #
+      # @return [Receiver, nil] The receiver.
+      #
+      def receiver
+        return self.link if !self.link.nil? && self.link.receiver?
+      end
+
+      # Returns the Delivery associated with this event.
+      #
+      # @return [Delivery, nil] The delivery.
+      #
+      def delivery
+        Qpid::Proton::Delivery.wrap(Cproton.pn_event_delivery(@impl))
+      end
+
+      # Sets the message.
+      #
+      # @param message [Qpid::Proton::Message] The message
+      #
+      def message=(message)
+        @message = message
+      end
+
+      # Returns the message.
+      #
+      # @return [Qpid::Proton::Message] The message.
+      #
+      def message
+        @message
+      end
+
+      # @private
+      def to_s
+        "#{self.type}(#{self.context})"
+      end
+
+    end
+
+  end
+
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/3ae96328/proton-c/bindings/ruby/lib/event/event_base.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/event/event_base.rb 
b/proton-c/bindings/ruby/lib/event/event_base.rb
new file mode 100644
index 0000000..6ae6959
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/event/event_base.rb
@@ -0,0 +1,91 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid::Proton::Event
+
+  # @private
+  def self.dispatch(handler, method, *args)
+    args = args.last unless args.nil?
+    if handler.respond_to? method.to_sym
+      return handler.__send__(method, args)
+    elsif handler.respond_to? :on_unhandled
+      return handler.__send__(:on_unhandled, method, args)
+    end
+  end
+
+  # EventBase is the foundation for creating application-specific events.
+  #
+  # @example
+  #
+  #   # SCENARIO: A continuation of the example in EventType.
+  #   #
+  #   #           An Event class is defined to handle receiving encrypted
+  #   #           data from a remote endpoint.
+  #
+  #   class EncryptedDataEvent < EventBase
+  #     def initialize(message)
+  #       super(EncryptedDataEvent, message,
+  #             Qpid::Proton::Event::ENCRYPTED_RECV)
+  #     end
+  #   end
+  #
+  #   # at another point, when encrypted data is received
+  #   msg = Qpid::Proton::Message.new
+  #   msg.decode(link.receive(link.pending))
+  #   if encrypted?(msg)
+  #     collector.put(EncryptedDataEvent.new(msg)
+  #   end
+  #
+  # @see EventType The EventType class for how ENCRYPTED_RECV was defined.
+  #
+  class EventBase
+
+    # Returns the name for the class associated with this event.
+    attr_reader :class_name
+
+    # Returns the associated context object for the event.
+    attr_reader :context
+
+    # Returns the type of the event.
+    attr_reader :type
+
+    # Creates a new event with the specific class_name and context of the
+    # specified type.
+    #
+    # @param class_name [String] The name of the class.
+    # @param context [Object] The event context.
+    # @param type [EventType] The event type.
+    #
+    def initialize(class_name, context, type)
+      @class_name = class_name
+      @context = context
+      @type = type
+    end
+
+    # Invokes the type-specific method on the provided handler.
+    #
+    # @param handler [Object] The handler to be notified of this event.
+    #
+    def dispatch(handler)
+      Qpid::Proton.dispatch(handler, @type.method, self)
+    end
+
+  end
+
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/3ae96328/proton-c/bindings/ruby/lib/event/event_type.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/event/event_type.rb 
b/proton-c/bindings/ruby/lib/event/event_type.rb
new file mode 100644
index 0000000..aa5944d
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/event/event_type.rb
@@ -0,0 +1,71 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid::Proton::Event
+
+  # Manages the association between an Event and the method which should
+  # process on the context object associated with an occurance of the event.
+  #
+  # Each type is identified by a unique #type value.
+  #
+  # @example
+  #
+  #   # SCENARIO: A part of an application handles extracting and decrypting
+  #   #            data received from a remote endpoint.
+  #   #
+  #   #            An EventType is created to notify handlers that such a
+  #   #            situation has occurred.
+  #
+  #   ENCRYPTED_RECV = 10000 # the unique constant value for the event
+  #
+  #   # create a new event type which, when it occurs, invokes a method
+  #   # named :on_encrypted_data when a handler is notified of its occurrance
+  #   Qpid::Proton::Event::ENCRYPTED_RECV =
+  #     Qpid::Proton::Event::EventType.new(ENCRYPTED_RECV, :on_encrypted_data)
+  #
+  # @see EventBase EventBase for the rest of this example.
+  # @see Qpid::Proton::Event::Event The Event class for more details on events.
+  #
+  class EventType
+
+    # The method to invoke on any potential handler.
+    attr_reader :method
+    attr_reader :number
+
+    def initialize(number, method)
+      @number = number
+      @name = Cproton.pn_event_type_name(@number)
+      @method = method
+      @@types ||= {}
+      @@types[number] = self
+    end
+
+    # @private
+    def to_s
+      @name
+    end
+
+    # @private
+    def self.by_type(type) # :nodoc:
+      @@types[type]
+    end
+
+  end
+
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/3ae96328/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb 
b/proton-c/bindings/ruby/lib/qpid_proton.rb
index 9060b54..58b95d0 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -51,6 +51,9 @@ require "codec/mapping"
 require "codec/data"
 
 # Event API classes
+require "event/event_type"
+require "event/event_base"
+require "event/event"
 require "event/collector"
 
 # Main Proton classes


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to