Index: ruby/trunk/lib/open_ehr/rm/support/identification.rb
===================================================================
--- ruby/trunk/lib/open_ehr/rm/support/identification.rb	(revision 295)
+++ ruby/trunk/lib/open_ehr/rm/support/identification.rb	(revision 297)
@@ -2,13 +2,13 @@
 # http://www.openehr.org/uml/release-1.0.1/Browsable/_9_0_76d0249_1109331021343_528780_2066Report.html
 # Ticket refs #39
-module OpenEhr
+module OpenEHR
   module RM
     module Support
       module Identification
-        class ObjectId
+        class ObjectID
           attr_reader :value
 
-          def initialize(value)
-            self.value=value
+          def initialize(args = {})
+            self.value=args[:value]
           end
 
@@ -17,6 +17,7 @@
             @value = value            
           end
+
           def ==(object_id)
-            @value == object_id.value
+            self.value == object_id.value
           end
         end # of ObjectID
@@ -25,12 +26,15 @@
           attr_reader :namespace, :type, :id
 
-          def initialize(namespace, type, id)
-            self.namespace = namespace
-            self.type = type
-            self.id = id
+          def initialize(args = {})
+            self.namespace = args[:namespace]
+            self.type = args[:type]
+            self.id = args[:id]
           end
 
           def namespace=(namespace)
-            raise ArgumentError if namespace.nil? or namespace.empty? or !(/([a-z]|[A-Z]).*/ =~ namespace) # error original is =~ #([a-z][A-Z])([a-z]|[A-Z]|\s|[0-9]|[_-\:\/\&\+\?])*/
+            if namespace.nil? or namespace.empty? or 
+                !(/^[a-zA-Z][a-zA-Z0-9_\-\:\/\&\+\?]*$/ =~ namespace)
+              raise ArgumentError
+            end
             @namespace = namespace
           end
@@ -47,20 +51,68 @@
         end
 
-        class ArchetypeId < ObjectId
-          attr_reader :domain_concept, :rm_name, :rm_entity, :rm_originator, :specialisation, :version_id
-
-          def initialize(value, domain_concept, rm_name, rm_entity, rm_originator, specialisation, version_id)
-            super(value)
-            self.domain_concept = domain_concept
-            self.rm_name = rm_name
-            self.rm_entity = rm_entity
-            self.rm_originator = rm_originator
-            self.specialisation = specialisation
-            self.version_id = version_id
+        class ArchetypeID < ObjectID
+          attr_reader :rm_originator, :rm_name, :rm_entity,
+                      :concept_name, :specialisation, :version_id
+          
+          def initialize(args = {})
+            if args[:value].nil?
+              self.rm_originator = args[:rm_originator]
+              self.rm_name = args[:rm_name]
+              self.rm_entity = args[:rm_entity]
+              self.concept_name = args[:concept_name]
+              self.version_id = args[:version_id]
+              self.specialisation = args[:specialisation]
+            else
+              super(args)
+            end
+          end
+
+          def value=(value)
+            if /([a-zA-Z]\w+)-([a-zA-Z]\w+)-([a-zA-Z]\w+)\.([a-zA-Z]\w+)(-([a-zA-Z]\w+))?\.(v[1-9]\d*)/ =~ value
+              self.rm_originator = $1
+              self.rm_name = $2
+              self.rm_entity = $3
+              self.concept_name = $4
+              self.specialisation = $6
+              self.version_id = $7
+            else
+              raise ArgumentError, 'invalid archetype id form'
+            end
+          end
+
+          def qualified_rm_entity
+            return @rm_originator + '-' + @rm_name + '-' + @rm_entity
+          end
+
+          def domain_concept
+            if @specialisation.nil?
+              return @concept_name
+            else
+              return @concept_name + '-' + @specialisation
+            end
+          end
+
+          def value
+            return self.qualified_rm_entity + '.' +
+              self.domain_concept + '.' + @version_id
+          end
+
+          def concept_name=(concept_name)
+            if concept_name.nil? or concept_name.empty?
+              raise ArgumentError, 'concept_name is mandatory'
+            end
+            @concept_name = concept_name
           end
 
           def domain_concept=(domain_concept)
-            raise ArgumentError, "domain concept not valid" if domain_concept.nil? or domain_concept.empty?
-            @domain_concept = domain_concept
+            if domain_concept.nil? or domain_concept.empty?
+              raise ArgumentError, "domain concept not valid"
+            end
+            if /([a-zA-Z]\w+)(-([a-zA-Z]\w))?/ =~ domain_concept
+              self.concept_name = $1
+              self.specialisation = $3
+            else
+              raise ArgumentError, 'invalid domain concept form'
+            end
           end
 
@@ -71,17 +123,24 @@
 
           def rm_entity=(rm_entity)
-            raise ArgumentError, "rm_entity not valid" if rm_entity.nil? or rm_entity.empty?
+            if rm_entity.nil? or rm_entity.empty?
+              raise ArgumentError, "rm_entity is mandatory"
+            end
             @rm_entity = rm_entity
           end
 
           def rm_originator=(rm_originator)
-            raise ArgumentError, "rm_originator not valid" if rm_originator.nil? or rm_originator.empty?
+            if rm_originator.nil? or rm_originator.empty?
+              raise ArgumentError, "rm_originator not valid"
+            end
             @rm_originator = rm_originator
           end
 
           def specialisation=(specialisation)
-            raise ArgumentError, "rm_specialisation not valid" if specialisation.nil? or specialisation.empty?
+            if !specialisation.nil? and specialisation.empty?
+              raise ArgumentError, "rm_specialisation not valid" 
+            end
             @specialisation = specialisation
           end
+
           def version_id=(version_id)
             raise ArgumentError, "version_id not valid" if version_id.nil? or version_id.empty?
@@ -90,9 +149,14 @@
         end
 
-        class TerminologyId < ObjectId
+        class TerminologyID < ObjectID
           attr_reader :name, :version_id
 
-          def initialize(value)
-            super(value)
+          def initialize(args = {})
+            if args[:value].nil?
+              self.name = args[:name]
+              self.version_id = args[:version_id]
+            else
+              super(args)
+            end
           end
 
@@ -108,12 +172,11 @@
           def value=(value)
             raise ArgumentError, "value not valid" if value.nil? or value.empty?
-            if /(.*)\((.*)\)$/ =~ value
-              @name = $1
-              @version_id = $2
-            else
-              @name = value
-              @version_id = ''
-            end
-            @value = value
+            if /(.*)\((.*)\)/ =~ value
+              self.name = $1
+              self.version_id = $2
+            else
+              self.name = value
+              self.version_id = ''
+            end
           end
 
@@ -124,69 +187,76 @@
 
           def version_id=(version_id)
-            raise ArgumentError, "version_id not valid" if version_id.nil?
-            @version_id = version_id
+            if version_id.nil?
+              @version_id = ''
+            else
+              @version_id = version_id
+            end
           end
         end # of Terminology_ID
 
-        class GenericId < ObjectId
+        class GenericID < ObjectID
           attr_reader :scheme
 
-          def initialize(value, scheme)
+          def initialize(args)
+            super(args)
+            self.scheme = args[:scheme]
+          end
+
+          def scheme=(scheme)
+            if scheme.nil? or scheme.empty?
+              raise ArgumentError, "scheme not valid"
+            end
+            @scheme = scheme
+          end
+        end # of Generic_ID
+
+        class TemplateID < ObjectID
+
+        end
+
+        class UIDBasedID < ObjectID
+          attr_reader :root, :extension
+
+          def initialize(args = {})
+            super(args)
+          end
+
+          def value=(value)
             super(value)
-            self.scheme = scheme
-          end
-
-          def scheme=(scheme)
-            raise ArgumentError, "scheme not valid" if scheme.nil? or scheme.empty?
-            @scheme = scheme
-          end
-        end # of Generic_ID
-
-        class TemplateId < ObjectId
-
-        end
-
-        class UidBasedId < ObjectId
-          def initialize(value)
-            super(value)
-          end
-
-          def extension
-            if self.has_extension?
-              @value[/::.*/][2..-1]
-            else
-              ''
+            if /(\S+)::(\S+)/ =~ value
+              @root = UID.new(:value => $1)
+              @extension = $2
+            else
+              @root = UID.new(:value => value)
+              @extension = ''
             end
           end
 
           def has_extension?
-            @value.include? '::'
-          end
-
-          def root
-            if self.has_extension?
-              @value[/.*::/][0..-3]
-            else
-              @value
-            end
-          end
-        end
-
-        class ObjectVersionId < UidBasedId
+            return !@extension.empty?
+          end
+        end
+
+        class ObjectVersionID < UIDBasedID
           attr_reader :object_id, :creating_system_id, :version_tree_id
 
-          def initialize(value)
-            super(value)
-          end
-
-          def value=(value)
-            super(value)
-            if /^(\w+)::(\w+)::((\d|\.)+)$/ =~ value
-              self.object_id = Uid.new($1)
-              self.creating_system_id = Uid.new($2)
-              self.version_tree_id = VersionTreeId.new($3)
+          def initialize(args= {})
+            super(args)
+          end
+
+          def value=(value)
+            if /^(\S+)::(\S+)::((\d|\.)+)$/ =~ value
+              self.object_id = UID.new(:value => $1)
+              self.creating_system_id = UID.new(:value => $2)
+              self.version_tree_id = VersionTreeID.new(:value => $3)
             else
               raise ArgumentError, 'invalid format'
             end
+          end
+
+          def value
+            return @object_id.value + '::' + 
+              @creating_system_id.value + '::' +
+              @version_tree_id.value
           end
 
@@ -216,9 +286,9 @@
 
         class LocatableRef < ObjectRef
-          attr_reader :namespace, :type, :id, :path
-
-          def initialize(namespace, type, id, path)
-            super(namespace, type, id)
-            self.path = path
+          attr_reader :path
+
+          def initialize(args = {})
+            super(args)
+            self.path = args[:path]
           end
 
@@ -234,7 +304,6 @@
 
         class PartyRef < ObjectRef
-
           def type=(type)
-            parties = ['PERSON', 'ORGANISATION', 'GROUP', 'AGENT', 'ROLE','PARTY', 'ACTOR']
+            parties = %w[PERSON ORGANISATION GROUP AGENT ROLE PARTY ACTOR]
             raise ArgumentError, 'type invalid' unless parties.include? type
             @type = type
@@ -243,24 +312,26 @@
 
         class AccessGroupRef < ObjectRef
+          def initialize(args = {})
+            super(args)
+            @type = 'ACCESS_GROUP'
+          end
+
           def type=(type)
-            raise ArgumentError, 'type invalid' unless type == 'ACCESS_GROUP'
-            @type = type
-          end
-        end
-
-        class HierObjectId < UidBasedId
-
-        end
-
-        class VersionTreeId
-          attr_reader :value, :trunk_version, :branch_number, :branch_version
-
-          def initialize(value)
-            self.value = value
+          end
+        end
+
+        class HierObjectID < UIDBasedID
+
+        end
+
+        class VersionTreeID
+          attr_reader :trunk_version, :branch_number, :branch_version
+
+          def initialize(args = {})
+            self.value = args[:value]
           end
 
           def value=(value)
             raise ArgumentError, 'value invalid' if value.nil? or value.empty?
-            @trunk_version = @branch_number = @branch_version = nil
             (trunk_version, branch_number, branch_version) = value.split '.'
             self.trunk_version = trunk_version
@@ -269,42 +340,47 @@
           end
 
-          def trunk_version=(trunk_version)
-            raise ArgumentError, 'trunk_version invalid' if trunk_version.nil? and !trunk_version.to_i >= 1
-            @trunk_version = trunk_version
-            set_value
-          end
-
-          def branch_number=(branch_number)
-            raise ArgumentError, 'branch number invalid' unless branch_number.nil? or branch_number.to_i >= 1
-            @branch_number = branch_number
-            set_value
-          end
-
-          def branch_version=(branch_version)
-            raise ArgumentError, 'branch version invalid' if (!branch_version.nil? and !( branch_version.to_i >= 1)) or (!branch_version.nil? and @branch_number.nil?)
-            @branch_version = branch_version
-            set_value
-          end
-          def is_branch?
-            !@branch_version.nil? and !@branch_number.nil?
-          end
-
-          def is_first?
-            trunk_version == '1'
-          end
-
-          private
-          def set_value
+          def value
             @value = trunk_version
             @value = @value + '.' + @branch_number unless @branch_number.nil?
             @value = @value + '.' + @branch_version unless @branch_version.nil?
-          end
-        end
-
-        class Uid
+            return @value
+          end
+
+          def trunk_version=(trunk_version)
+            if trunk_version.nil? || (trunk_version.to_i < 1)
+              raise ArgumentError, 'trunk_version invalid'
+            end
+            @trunk_version = trunk_version
+          end
+
+          def branch_number=(branch_number)
+            unless branch_number.nil? or branch_number.to_i >= 1
+              raise ArgumentError, 'branch number invalid'
+            end
+            @branch_number = branch_number
+          end
+
+          def branch_version=(branch_version)
+            if (!branch_version.nil? and !(branch_version.to_i >= 1)) or
+                (!branch_version.nil? and @branch_number.nil?)
+              raise ArgumentError, 'branch version invalid'
+            end
+            @branch_version = branch_version
+          end
+
+          def is_branch?
+            !@branch_version.nil? and !@branch_number.nil?
+          end
+
+          def is_first?
+            trunk_version == '1'
+          end
+        end
+
+        class UID
           attr_reader :value
 
-          def initialize(value)
-            self.value = value
+          def initialize(args = {})
+            self.value = args[:value]
           end
 
@@ -315,13 +391,13 @@
         end
 
-        class Uuid < Uid
-
-        end
-
-        class InternetId <Uid
+        class UUID < UID
+
+        end
+
+        class InternetID <UID
           
         end
 
-        class IsoOid <Uid
+        class IsoOID <UID
 
         end        
