Module: Muml_Class

Defined in:
lib/ontomde-uml2/uml2.rb,
lib/ontomde-uml2/umlx.rb,
lib/ontomde-uml2/umlx.rb,
lib/ontomde-uml2/umlx.rb,
lib/ontomde-uml2/nocode.rb,
lib/ontomde-uml2/component.rb,
lib/ontomde-uml2/dotDiagram.rb,
lib/ontomde-uml2/kb/protege.rb,
lib/ontomde-uml2/createAndAdd.rb,
lib/ontomde-uml2/autoImplement.rb,
lib/ontomde-uml2/autoImplement.rb,
lib/ontomde-uml2/versionSignature.rb,
lib/ontomde-uml2/multipleInheritance.rb

Instance Method Summary collapse

Instance Method Details

#prot_writeSubClassOfObject

writes sub class of rdf instructions



392
393
394
395
396
397
# File 'lib/ontomde-uml2/kb/protege.rb', line 392

def prot_writeSubClassOf
  super # Classifier
  uml_implementation.each { |g|
    write("<#{prot_uri}> <#{RDF_SUBCLASSOF_URI}> <#{g.uml_supplier_one.prot_uri}> .\n")
  }
end

#uml_addVersionSignature(interface) ⇒ Object



26
27
28
# File 'lib/ontomde-uml2/versionSignature.rb', line 26

def uml_addVersionSignature(interface)
  umlx_createAndAddImplementation(interface)
end

#umlx_addDependencies(s = Set.new) ⇒ Object



35
36
# File 'lib/ontomde-uml2/nocode.rb', line 35

def umlx_addDependencies(s=Set.new)
end

#umlx_autoCreateImplicitComponent!Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/ontomde-uml2/component.rb', line 20

def umlx_autoCreateImplicitComponent!
  # next if uml_isAbstract?
  
  p=umlx_owner_one  
  p=p.umlx_getOrCreatePackage(context[:componentPackage,"component"],p)
  co=p.umlx_createAndAddComponent(rdf_uri+"_component","#{uml_name} Component")
  co.umlx_implicitClass=self
  
  uml_ownedOperation.each { |op|
    #log.debug { "Copy operation #{op} to interface #{i}" }
    nop=co.umlx_createAndAddOperation("#{op.rdf_uri}_interface",op.uml_name.to_s)
    #copy parameter
    op.uml_ownedParameter.each { |pa|
      np=nop.umlx_createAndAddParameter("#{pa.rdf_uri}_interface",pa.uml_name.to_s)
      pa.umlx_copyToAttributeProperty(np)
    }
    #copy return parameter
    op.uml_returnResult.each { |pa|
      np=nop.umlx_createAndAddReturnParameter("#{pa.rdf_uri}_interface",pa.uml_name.to_s)
      pa.umlx_copyToAttributeProperty(np)
    }
  }
  
  
end

#umlx_autoImplementOperation!Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/ontomde-uml2/autoImplement.rb', line 128

def umlx_autoImplementOperation!
  return if umlx_autoImplementCompleteOperation?
  return if uml_isAbstract?
  umlx_autoImplementCompleteOperation=RDF_TRUE

  #Recurse begining at top of inheritance
  uml_generalization.each { |gen|
    gen.uml_general_one.umlx_autoImplementOperation!
  }

  #OK my ancesters have been processed
  #Now if I don't implement an operation, it is my duty.
  impOper=umlx_ImplementedOperations
  umlx_operationIShouldImplement.each { |sig,ia|
    next if impOper.keys.include?(ia.umlx_signature)
    c=umlx_createAndAddOperation(ia.rdf_uri+"_implem",ia.uml_name.to_s);
    c.uml_ownedComment=ia.uml_ownedComment unless ia.uml_ownedComment.empty?
    ia.umlx_autoImplementedBy_add(c) # used by javadoc
    c.umlx_copyStereotypesFrom!(ia)
    (ia.uml_ownedParameter+ia.uml_returnResult).each { |p|
      cp=c.umlx_createAndAddParameter(p.rdf_uri+"_implem",p.uml_name_one)
      p.umlx_copyToAttributeProperty(cp)
      cp.uml_direction=p.uml_direction
      cp.umlx_copyStereotypesFrom!(p)
    }
    # the new method is considered business Method if the original method is one
    #NOTE: umlx_businessMethod? changed to umlx_businessMethod
    c.umlx_businessMethod=ia.umlx_businessMethod
    c.umlx_redefinesMethod=ia
  }
end

#umlx_autoImplementProperty!Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/ontomde-uml2/autoImplement.rb', line 28

def umlx_autoImplementProperty!
  return if umlx_autoImplementComplete?
  umlx_autoImplementComplete=RDF_TRUE

  #Recurse begining at top of inheritance
  uml_generalization.each { |gen|
    gen.uml_general_one.umlx_autoImplementProperty!
  }

  #OK my ancesters have been processed
  #Now if I don't implement an attribute, it is my duty.
  impAttNames=umlx_ImplementedAttributesNames
  umlx_ImplementedAttributes.each { |ia|
    #log.debug { "umlx_autoImplementProperty #{ia} for #{self} #{ia.umlx_isAssociation?}" }
    next if impAttNames.include?(ia.uml_name.to_s)
    if(ia.umlx_isAttribute?)
      att=self.umlx_createAndAddProperty(self.rdf_uri+ia.rdf_uri.to_s.str_to_uri)
      att.uml_name=ia.uml_name
      att.uml_type=ia.uml_type
	att.umlx_copyStereotypesFrom!(ia)
	att.uml_upperValue=ia.uml_upperValue unless ia.uml_upperValue.empty?
	att.uml_lowerValue=ia.uml_lowerValue unless ia.uml_lowerValue.empty?
	att.uml_ownedComment=ia.uml_ownedComment unless ia.uml_ownedComment.empty?
    else
      #puts "create and add ..."
      ms=ia.uml_association_one
      ms1=ia
      ms2=ia.umlx_otherEnd;
      #puts "ms=#{ms}"
      #puts "ms1=#{ms1} #{ms1.uml_type}"
      #puts "ms2=#{ms2} #{ms2.uml_type}"
      m,m1,m2=self.umlx_createAndAddAssociation(self.rdf_uri+ia.rdf_uri.to_s.str_to_uri,ia.uml_type)
      m1.uml_aggregation=ms1.uml_aggregation
      m2.uml_aggregation=ms2.uml_aggregation
      m1.uml_name=ms1.uml_name
      m2.uml_name=ms2.uml_name

	m.umlx_copyStereotypesFrom!(ms)
	m1.umlx_copyStereotypesFrom!(ms1)
	m2.umlx_copyStereotypesFrom!(ms2)

      ms1.umlx_copyToAttributeProperty(m1)
      ms2.umlx_copyToAttributeProperty(m2)

	m1.uml_ownedComment=ms1.uml_ownedComment unless ms1.uml_ownedComment.empty?
	m2.uml_ownedComment=ms2.uml_ownedComment unless ms2.uml_ownedComment.empty?

      #puts "m=#{m}"
      #puts "m1=#{m1} #{m1.uml_type}"
      #puts "m2=#{m2} #{m2.uml_type}"
    end
  }
end

#umlx_carryComposition?Boolean

returns true if this class carries directly a composition See: #umlx_carryCompositionRec? for recursive behavior.

Returns:

  • (Boolean)


270
271
272
273
274
275
276
277
278
279
# File 'lib/ontomde-uml2/uml2.rb', line 270

def umlx_carryComposition?
  (self.uml_ownedAttribute+self.umlx_ownedAttribute).each { |a|
    #next if !p.kind_of?(Cuml_Property)
    #log.debug "#{self.uml_name} --> #{a.umlx_otherEnd.class.name}"
    [a, a.umlx_otherEnd].each { |p|

      return true if (!p.nil?) && (!p.uml_aggregation_one0.nil?)&& (p.uml_aggregation_one.isComposite?)
    }}
  return false
end

#umlx_carryCompositionRec?Boolean

returns true if this class or one of its inherited classes carries directly a composition See: #umlx_carryComposition? for non recursive behavior.

Returns:

  • (Boolean)


283
284
285
286
287
288
289
# File 'lib/ontomde-uml2/uml2.rb', line 283

def umlx_carryCompositionRec?
  return true if umlx_carryComposition?
  self.umlx_classifier_generalization_indirect.each {|c|
    return true if c.umlx_carryCompositionRec?
  }
  return false
end

#umlx_classDiagram_dotFileObject

generates a standard class diagram for this class in the dot language. Note:

1 level of Generalization is included.
Attributes are included


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ontomde-uml2/dotDiagram.rb', line 81

def umlx_classDiagram_dotFile
  write("digraph {\n")
  #write("rankdir=LR;\n");
  write("node [shape=box,#{DOT_NODE_COLOR_SECONDARY}];\n")

  write(%{#{dotId} [label="#{uml_name}",#{DOT_NODE_COLOR_PRIMARY}]\n})

  uml_generalization.each { |g|
    g.umlx_classDiagram_dotFragment
  }
  uml_ownedAttribute.each { |oa|
    oa.umlx_classDiagram_dotFragment
  }
  write("}\n")
end

#umlx_createAndAddClass(new_uri, new_name = nil) ⇒ Object

Creates and add a new UML Class. Return the newly created element. new_uri should be globaly unique.



42
43
44
45
46
47
48
49
50
51
# File 'lib/ontomde-uml2/createAndAdd.rb', line 42

def umlx_createAndAddClass(new_uri,new_name=nil)
  c=Cuml_Class.new(rdf_Repository,new_uri)
  #uml_ownedMember_add(c)
  uml_nestedClassifier_add(c)
  c.umlx_owner=self
  c.uml_name=new_name unless new_name.nil?
  c.uml_visibility=::Cuml_VisibilityKind::Public
  #puts "création classe #{new_name} in #{self.java_qualifiedName}"
  return c
end

#umlx_createAndAddGeneralization(gen) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/ontomde-uml2/createAndAdd.rb', line 52

def umlx_createAndAddGeneralization(gen)
  g=Cuml_Generalization.new(rdf_Repository,nil)
  g.uml_general=gen
  g.uml_specific=self
  self.uml_generalization_add(g)
  return g
end

#umlx_createAndAddImplementation(gen) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/ontomde-uml2/createAndAdd.rb', line 60

def umlx_createAndAddImplementation(gen)
  g=Cuml_Implementation.new(rdf_Repository,nil)
  g.uml_supplier=gen
  g.uml_implementingClassifier=self
  self.uml_implementation_add(g)
  return g
end

#umlx_getCompositeObject

returns direct composite element for this class if it exists, nil otherwise. Note:

This method returns direct relations only.

See: #umlx_isComposante?



229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/ontomde-uml2/uml2.rb', line 229

def umlx_getComposite
  #(self.umlx_ownedAttribute-self.uml_ownedAttribute).each { |a|
  (self.umlx_ownedAttribute).each { |a|
    next if self.uml_ownedAttribute.include?(a)
    #next if !p.kind_of?(Cuml_Property)
    #log.debug "#{self.uml_name} --> #{a.umlx_otherEnd.class.name}"
    #[a, a.umlx_otherEnd].each { |p|
    [a].each { |p|

      return p if (!p.nil?) && (!p.uml_aggregation_one0.nil?)&& (p.uml_aggregation_one.isComposite?)
    }}
  return nil
end

#umlx_getCompositeRecObject

returns first composite found. See: #umlx_isComposanteRec? for non recursive behavior.



256
257
258
259
260
261
262
263
264
265
# File 'lib/ontomde-uml2/uml2.rb', line 256

def umlx_getCompositeRec()
  ci=umlx_getComposite
  return ci unless ci.nil?
  
  self.umlx_classifier_generalization_indirect.each {|c|
    ci=c.umlx_getCompositeRec()
    return ci unless ci.nil?
  }
  return nil
end

#umlx_ImplementedAttributes(ret = Set.new()) ⇒ Object



91
92
93
94
95
96
# File 'lib/ontomde-uml2/autoImplement.rb', line 91

def umlx_ImplementedAttributes(ret=Set.new())
  uml_implementation.each { |g|
    g.uml_supplier_one.umlx_ImplementedAttributes(ret)
  }
  return ret
end

#umlx_ImplementedAttributesNames(ret = Set.new()) ⇒ Object



81
82
83
84
85
86
87
88
89
90
# File 'lib/ontomde-uml2/autoImplement.rb', line 81

def umlx_ImplementedAttributesNames(ret=Set.new())
  uml_generalization.each { |gen|
    gen.uml_general_one.umlx_ImplementedAttributesNames(ret)
  }
  uml_ownedAttribute.each { |oa|
    next if oa.uml_isStatic? || (oa.respond_to?(:java_isFinal?) && oa.java_isFinal?)
    ret << oa.uml_name.to_s
  }
  return ret
end

#umlx_ImplementedOperations(ret = Hash.new()) ⇒ Object



160
161
162
163
164
165
166
167
168
169
# File 'lib/ontomde-uml2/autoImplement.rb', line 160

def umlx_ImplementedOperations(ret=Hash.new())
  uml_generalization.each { |gen|
    gen.uml_general_one.umlx_ImplementedOperations(ret)
  }
  uml_ownedOperation.each { |oa|
    next if oa.uml_isAbstract?
    ret[oa.umlx_signature]=oa
  }
  return ret
end

#umlx_isAnException?Boolean

TO BE DONE Returns true if this class is used as an exception

NOTE:

  • Is a class meant to be an exception is not used in a throws clause, it will not be detected

Returns:

  • (Boolean)


204
205
# File 'lib/ontomde-uml2/umlx.rb', line 204

def umlx_isAnException?
end

#umlx_isARootException?Boolean

TO BE DONE

Returns:

  • (Boolean)


208
209
# File 'lib/ontomde-uml2/umlx.rb', line 208

def umlx_isARootException?
end

#umlx_isComposante?Boolean

returns true if this class is a direct composante member end of a composition. Note:

This method returns direct relations only.

See:

  • #umlx_isComposanteRec? for recursive behavior.

  • #umlx_getComposite

Returns:

  • (Boolean)


221
222
223
# File 'lib/ontomde-uml2/uml2.rb', line 221

def umlx_isComposante?
 return !umlx_getComposite.nil?
end

#umlx_isComposanteRec?Boolean

returns true if this class is this class or one of its inheriting class is a direct composante member end of a composition. See: #umlx_isComposante? for non recursive behavior.

Returns:

  • (Boolean)


246
247
248
249
250
251
252
# File 'lib/ontomde-uml2/uml2.rb', line 246

def umlx_isComposanteRec?
  return true if umlx_isComposante?
  self.umlx_classifier_generalization_indirect.each {|c|
    return true if c.umlx_isComposanteRec?
  }
  return false
end

#umlx_isReallyAClass?Boolean

return true if uml_ownedAttribute_inv is a “regular” class

Returns:

  • (Boolean)


653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
# File 'lib/ontomde-uml2/umlx.rb', line 653

def umlx_isReallyAClass?
  ret=kind_of?(Cuml_Class)
  #ret=!(
  #	 kind_of?(Muml_Stereotype)||
  #	 kind_of?(Muml_StateMachine)||
  #	 kind_of?(Muml_Activity)||
  #	 kind_of?(Muml_Interaction)
  #	 kind_of?(Muml_Component)||
  #	 kind_of?(Muml_Device)||
  #	 kind_of?(Muml_ExecutionEnvironment)||
  #	 kind_of?(Muml_Node)
  #	)
  #log.debug { "umlx_isReallyAClass #{ret}::#{self.class.name}" }
  return ret
end

#umlx_mapMultipleInheritanceToInterface!(nl) ⇒ Object

nl : no loop



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ontomde-uml2/multipleInheritance.rb', line 25

def umlx_mapMultipleInheritanceToInterface!(nl)
  if nl.include?(self)
    log.error {"umlx_mapMultipleInheritanceToInterface!: multiple call detected for #{self}" }
    return
  end
  nl<< self
  log.debug { "umlx_mapMultipleInheritanceToInterface! #{self}::#{self.class.name}" }
  #Create an interface to replace this class
  #Interface will have the name of the class
  #Class implements the interface
  i=umlx_owner_one.umlx_createAndAddInterface("#{self.rdf_uri}_interface",self.uml_name.to_s)
  self.umlx_createAndAddImplementation(i)

  #Obviously The class name must change to avoid a name clash.
  self.uml_name="#{self.uml_name}_Implem"

  #process type 3 elements (refer to diagram)
  #(type 3 are handled as type 1 from the other extremity)
  #Change classes this class generalize to interface
  ug_copy=Array.new ; uml_generalization.each {|g| ug_copy<< g }
  ug_copy.each { |general|
    t=general.uml_general_one
    #log.debug { "mi recursing trough generalization from #{self} to #{t}"}
    i2=t.umlx_mapMultipleInheritanceToInterface!(nl)
    i.umlx_createAndAddGeneralization(i2)
  }



  #process type 2 elements (refer to diagram)
  #replace this class as attribute with interface i everywhere in model
  uml_type_inv.each {|m|
    #log.debug { "Changing attribut #{m} type from #{self} to #{i}" }
    m.uml_type=i
  }

  #process type 1 elements (refer to diagram)
  #replace this class generalization with i interface implementation
  uml_general_inv.each { |general|
    general.uml_generalization_inv.each {|cgen|
      #log.debug { "Changing #{cgen} generalization #{self} to implement #{i}" }
      #create new implementation
      cgen.umlx_createAndAddImplementation(i)
      #remove old generalization
      cgen.uml_generalization.delete(general)
    }
  }

  #process type 4 and 5 elements (refer to diagram)
  #copy property from this class to interface i
  uml_ownedAttribute.each { |a|
    #log.debug { "Copy property #{a} to interface #{i}" }
    na=i.umlx_createAndAddProperty("#{a.rdf_uri}_interface",a.uml_name.to_s);
    a.umlx_copyToAttributeProperty(na)
  }

  #process type 7 elements (refer to diagram)
  #copy method from this class to interface i
  uml_ownedOperation.each { |op|
    #log.debug { "Copy operation #{op} to interface #{i}" }
    nop=i.umlx_createAndAddOperation("#{op.rdf_uri}_interface",op.uml_name.to_s)
    #copy parameter
    op.uml_ownedParameter.each { |p|
      np=nop.umlx_createAndAddParameter("#{p.rdf_uri}_interface",p.uml_name.to_s)
      p.umlx_copyToAttributeProperty(np)
    }
    #copy return parameter
    op.uml_returnResult.each { |p|
      np=nop.umlx_createAndAddReturnParameter("#{p.rdf_uri}_interface",p.uml_name.to_s)
      p.umlx_copyToAttributeProperty(np)
    }
  }


  return i
end

#umlx_operationIShouldImplement(ret = Hash.new()) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/ontomde-uml2/autoImplement.rb', line 171

def umlx_operationIShouldImplement(ret=Hash.new())

  #SR16252
  umlx_classifier_generalization_indirect.each { |i|
    i.uml_ownedOperation.each { |oo|
      next unless oo.uml_isAbstract?
      ret[oo.umlx_signature]=oo
    }
  }
  uml_implementation.each { |g|
    g.uml_supplier_one.uml_ownedOperation.each { |oo|
      ret[oo.umlx_signature]=oo
    }
    #interface implemented via an interface inheritance
    g.uml_supplier_one.umlx_classifier_generalization_indirect.each { |i|
      i.uml_ownedOperation.each { |oo|
        ret[oo.umlx_signature]=oo
      }}
  }
  return ret
end

#umlx_ownedAttributeObject

returns ownedAttribute including non navigable ones.



204
205
206
207
208
209
210
211
212
213
# File 'lib/ontomde-uml2/uml2.rb', line 204

def umlx_ownedAttribute
  ret=Array.new
  ext_isReferencedBy.each { |res|
    next if !res.kind_of?(Cuml_Property)
    ##log.debug "referencedBy : #{res.class.name}"
    next if res.uml_type_one!=self
    ret << res
  }
  return ret
end

#umlx_sanitizeAbstractsInHierarchy!Object

Suppose A derives from B and B is not abstract This transformater will 1) rename B to Babstract 2) mark Babstract as abstract 3) Create a new class B that derives from Babstract 4) (TBD) create facade constructors in (new) B.



545
546
547
548
549
550
551
552
# File 'lib/ontomde-uml2/umlx.rb', line 545

def umlx_sanitizeAbstractsInHierarchy!
  #log.debug { "sanitize #{uml_name} #{uml_isAbstract}==#{uml_isAbstract?}" }
  self.uml_isAbstract=RDF_TRUE
  c=umlx_package.umlx_createAndAddClass(rdf_uri+"_concret","_concrete")
  c.uml_name="#{uml_name}"
  self.uml_name="#{uml_name}Abstract"
  c.umlx_createAndAddGeneralization(self)
end