Index: /ruby/branches/0.5/lib/open_ehr/rm/composition.rb
===================================================================
--- /ruby/branches/0.5/lib/open_ehr/rm/composition.rb	(revision 345)
+++ /ruby/branches/0.5/lib/open_ehr/rm/composition.rb	(revision 345)
@@ -0,0 +1,100 @@
+# rm::composition
+# composition module
+# http://www.openehr.org/uml/release-1.0.1/Browsable/_9_0_76d0249_1109005072243_448526_217Report.html
+# refs #79
+include OpenEHR::RM::Common::Archetyped
+module OpenEHR
+  module RM
+    module Composition
+      class Composition < Locatable
+        attr_reader :language, :category, :territory, :composer
+        attr_accessor :content, :context
+
+        def initialize(args = { })
+          super(args)
+          self.language = args[:language]
+          self.category = args[:category]
+          self.territory = args[:territory]
+          self.composer = args[:composer]
+          self.content = args[:content]
+          self.context = args[:context]
+        end
+
+        def language=(language)
+          if language.nil?
+            raise ArgumentError, 'language is mandatory'
+          end
+          @language = language
+        end
+
+        def category=(category)
+          if category.nil?
+            raise ArgumentError, 'category is mandatory'
+          end
+          @category = category
+        end
+
+        def territory=(territory)
+          if territory.nil?
+            raise ArgumentError, 'territory is mandatory'
+          end
+          @territory = territory
+        end
+
+        def composer=(composer)
+          if composer.nil?
+            raise ArgumentError, 'composer is mandatory'
+          end
+          @composer = composer
+        end
+
+        def is_persistent?
+          return category.value == 'persistent'
+        end
+      end
+
+      class EventContext < Pathable
+        attr_reader :start_time, :setting, :participations, :location
+        attr_accessor :end_time, :other_context
+
+        def initialize(args = { })
+          super(args)
+          self.start_time = args[:start_time]
+          self.setting = args[:setting]
+          self.end_time = args[:end_time]
+          self.participations = args[:participations]
+          self.location = args[:location]
+          self.other_context = args[:other_context]
+        end
+
+        def start_time=(start_time)
+          if start_time.nil?
+            raise ArgumentError, 'start_time is mandatory'
+          end
+          @start_time = start_time
+        end
+
+        def setting=(setting)
+          if setting.nil?
+            raise ArgumentError, 'setting is mandatory'
+          end
+          @setting = setting
+        end
+
+        def participations=(participations)
+          if !participations.nil? and participations.empty?
+            raise ArgumentError, 'participations should not be empty'
+          end
+          @participations = participations
+        end
+
+        def location=(location)
+          if !location.nil? and location.empty?
+            raise ArgumentError, 'location should not be empty'
+          end
+          @location = location
+        end
+      end
+    end # end of Composition
+  end # end of RM
+end # end of OpenEHR
Index: /ruby/branches/0.5/spec/lib/open_ehr/rm/composition/composition_spec.rb
===================================================================
--- /ruby/branches/0.5/spec/lib/open_ehr/rm/composition/composition_spec.rb	(revision 345)
+++ /ruby/branches/0.5/spec/lib/open_ehr/rm/composition/composition_spec.rb	(revision 345)
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/../../../../spec_helper'
+include OpenEHR::RM::Composition
+include OpenEHR::RM::DataTypes::Text
+include OpenEHR::RM::Support::Identification
+include OpenEHR::RM::Common::Generic
+
+describe Composition do
+  before(:each) do
+    name = DvText.new(:value => 'composition test')
+    language = stub(CodePhrase, :code_string => 'ja')
+    category = stub(DvCodedText, :value => 'event')
+    territory = stub(CodePhrase, :code_string => 'jpn')
+    external_ref = stub(PartyRef, :type =>  'ROLE')
+    composer = stub(PartyProxy, :external_ref => external_ref)
+    content = stub(Array, :size => 3)
+    context = stub(EventContext, :location => 'lab1')
+    @composition = Composition.new(:archetype_node_id => 'at0001',
+                                   :name => name,
+                                   :language => language,
+                                   :category => category,
+                                   :territory => territory,
+                                   :composer => composer,
+                                   :content => content,
+                                   :context => context)
+  end
+
+  it 'should be an instance of Composition' do
+    @composition.should be_an_instance_of Composition
+  end
+
+  it 'language should be assigned properly' do
+    @composition.language.code_string.should == 'ja'
+  end
+
+  it 'should validate language with Termonology service'
+
+  it 'should raise ArgumentError with nil language' do
+    lambda {
+      @composition.language = nil
+    }.should raise_error ArgumentError
+  end
+
+  it 'category should be assigned properly' do
+    @composition.category.value.should == 'event'
+  end
+
+  it 'should validate category with Terminology service'
+
+  it 'should raise ArgumentError with nil category' do
+    lambda {
+      @composition.category = nil
+    }.should raise_error ArgumentError
+  end
+
+  it 'territory should be assined properly' do
+    @composition.territory.code_string.should == 'jpn'
+  end
+
+  it 'should raise ArgumentError with nil territory' do
+    lambda {
+      @composition.territory = nil
+    }.should raise_error ArgumentError
+  end
+
+  it 'composer should be assigned properly' do
+    @composition.composer.external_ref.type.should == 'ROLE'
+  end
+
+  it 'should raise ArgumentError with nil comosser' do
+    lambda {
+      @composition.composer = nil
+    }.should raise_error ArgumentError
+  end
+
+  it 'is_persistent? should be false when category is not persistent' do
+    @composition.is_persistent?.should be_false
+  end
+
+  it 'is_persistent? should be true when category is persistent' do
+    category = stub(DvCodedText, :value => 'persistent')
+    @composition.category = category
+    @composition.is_persistent?.should be_true
+  end
+
+  it 'content should be assigned properly' do
+    @composition.content.size.should == 3
+  end
+
+  it 'context should be assigned properly' do
+    @composition.context.location.should == 'lab1'
+  end
+end
Index: /ruby/branches/0.5/spec/lib/open_ehr/rm/composition/event_context_spec.rb
===================================================================
--- /ruby/branches/0.5/spec/lib/open_ehr/rm/composition/event_context_spec.rb	(revision 345)
+++ /ruby/branches/0.5/spec/lib/open_ehr/rm/composition/event_context_spec.rb	(revision 345)
@@ -0,0 +1,88 @@
+require File.dirname(__FILE__) + '/../../../../spec_helper'
+include OpenEHR::RM::Composition
+include OpenEHR::RM::DataTypes::Quantity::DateTime
+include OpenEHR::RM::DataTypes::Text
+include OpenEHR::RM::DataStructures::ItemStructure
+
+describe EventContext do
+  before(:each) do
+    start = DvDateTime.new(:value => '2009-11-13T20:46:57')
+    setting_group = stub(CodePhrase, :code_string => '225')
+    setting = stub(DvCodedText, :defining_code => setting_group)
+    ending = DvDateTime.new(:value => '2010-10-14T09:00:00')
+    participations = stub(Array, :size => 5, :empty? => false)
+    other_context = stub(ItemStructure, :archetype_node_id => 'at0002')
+    @event_context = EventContext.new(:start_time => start,
+                                      :end_time => ending,
+                                      :setting => setting,
+                                      :participations => participations,
+                                      :location => 'ehime',
+                                      :other_context => other_context)
+  end
+
+  it 'should be an instance of EventContext' do
+    @event_context.should be_an_instance_of EventContext
+  end
+
+  it 'start_time should be assigned properly' do
+    @event_context.start_time.value.should == '2009-11-13T20:46:57'
+  end
+
+  it 'should raise ArgumentError with nil start_time' do
+    lambda {
+      @event_context.start_time = nil
+    }.should raise_error ArgumentError
+  end
+  
+  it 'setting should be assigned properly' do
+    @event_context.setting.defining_code.code_string.should == '225'
+  end
+
+  it 'should raise ArgumentError with nil setting' do
+    lambda {
+      @event_context.setting = nil
+    }.should raise_error ArgumentError
+  end
+
+  it 'should vaildate setting code with Terminology service'
+
+  it 'end_time should be assigned properly' do
+    @event_context.end_time.value.should == '2010-10-14T09:00:00'
+  end
+
+  it 'participations should be properly assigned' do
+    @event_context.participations.size.should be_equal 5
+  end
+
+  it 'should raise ArgumentError with empty participations' do
+    lambda {
+      @event_context.participations = [ ]
+    }.should raise_error ArgumentError
+  end
+
+  it 'should not raise ArgumentError with nil participations' do
+    lambda {
+      @event_context.participations = nil
+    }.should_not raise_error ArgumentError
+  end
+
+  it 'location should be assigned properly' do
+    @event_context.location.should == 'ehime'
+  end
+
+  it 'should raise ArgumentError with empty location' do
+    lambda {
+      @event_context.location = ''
+    }.should raise_error ArgumentError
+  end
+
+  it 'should not raise ArgumentError with nil location' do
+    lambda {
+      @event_context.location = nil
+    }.should_not raise_error ArgumentError
+  end
+
+  it 'other_context should be assigned properly' do
+    @event_context.other_context.archetype_node_id.should == 'at0002'
+  end
+end
