Module: Mrdf_Model

Defined in:
lib/ontomde-uml2-java/groovy.rb,
lib/ontomde-uml2-java/java.rb,
lib/ontomde-uml2-java/build.rb,
lib/ontomde-uml2-java/build.rb,
lib/ontomde-uml2-java/javadoc.rb,
lib/ontomde-uml2-java/security.rb,
lib/ontomde-uml2-java/enumAssignable.rb,
lib/ontomde-uml2-java/operationAsClass.rb,
lib/ontomde-uml2-java/enumCompatibilityLayer.rb

Overview

define enum as string compatibility layer

Feature introduced for FLEX for Java 1.5 / Java 1.4 interoperability

Constant Summary collapse

JAVA_GLOBAL_ACCESS_CONTROL_ENUM =

JAVA_GLOBAL_ACCESS_CONTROL_ENUM=“xmda .security.StaticSecurityRole” Enumerated containing the list of all access control criteria

"xmda.security.GlobalComputedAccessControlCriteria"
JAVA_GLOBAL_ACCESS_CONTROL_ENUM_COMMENT =
<<ENDHELP
This enum contains a list of all computed access control criteria.

Generic examples of access control:
* userIsManagerForThisObject
* userOwnsThisObject
* userIsOnDuty

AccessControl criteria are computed in the context of one class instance of the model and one user. (ex: User Martin accessing contract number 3003).

Some criteria migth not need to know what object is beeing accessed (example: userIsOnDuty). Some other will need to know what object is access (Is martin a manager for contract 42000 ?, Does Martin owns product number 13239 ?)

This list is defined at design time because these rules criteria are implemented usign an algorithm (model query, date computation, ...) that require some coding and optimisation at developpement time. It is however possible to add RESERVED elements for future extension (RESERVED1, RESERVED2, ...).
ENDHELP
JAVA_SECURE_ANNOTATION =

Java annotation used to mark a Secured method or field.

"@xmda.security.Secure"

Instance Method Summary collapse

Instance Method Details

#java_addContextJavaFilePathMapping(qualifiedNameRegexp, relativePath) ⇒ Object

Example java_addJavaFilePathMapping(/.example/,“src/main/example/” ]) TODO: add helping error if jfp.nil?



79
80
81
82
# File 'lib/ontomde-uml2-java/java.rb', line 79

def java_addContextJavaFilePathMapping(qualifiedNameRegexp,relativePath)
  jfp=context[:javaFilePathRegexp]
  jfp[qualifiedNameRegexp,relativePath]
end

#java_addEnumAssignable!Object



18
19
20
21
22
23
24
# File 'lib/ontomde-uml2-java/enumAssignable.rb', line 18

def java_addEnumAssignable!
	uml_Class_all.each {|c|
		next if c.kind_of?(Muml_Enumeration)
		next if c.umlx_external?
		c.java_addEnumAssignable!
	}
end

#java_addEnumCompatibilityLayerMethods!Object



16
17
18
19
20
21
# File 'lib/ontomde-uml2-java/enumCompatibilityLayer.rb', line 16

def java_addEnumCompatibilityLayerMethods!
	uml_Class_all.each {|c|
			next unless c.kind_of?(Muml_Class)
			c.java_addEnumPostDeserialiseUpdate!
	}
end

#java_addEnumCompatibilityLayerProperties!Object



8
9
10
11
12
13
14
15
# File 'lib/ontomde-uml2-java/enumCompatibilityLayer.rb', line 8

def java_addEnumCompatibilityLayerProperties!
	uml_Class_all.each {|c|
		next unless c.kind_of?(Muml_Class)
		c.uml_ownedAttribute.each {|e|
			e.java_addEnumStringAttribute!
		}
	}
end

#java_addGroovyImplementations!Object

enhance model operation by enabling groovy implementations. only method with no code are enhanced.



9
10
11
# File 'lib/ontomde-uml2-java/groovy.rb', line 9

def java_addGroovyImplementations!  
  
end

#java_addJavaEnumInterface!Object

generates an EnumAssignable for each model element.



10
11
12
13
14
15
16
17
# File 'lib/ontomde-uml2-java/enumAssignable.rb', line 10

def java_addJavaEnumInterface!
	return unless context[:java_addJavaEnumInterface]
	uml_Class_all.each {|c|
		next unless c.kind_of?(Muml_Enumeration)
		i=c.java_getJavaEnumInterface
		c.umlx_createAndAddImplementation(i)
	}
end

#java_ClassRelativeDirObject

returns directory containing compiled java classes and other ressources in classpath.



16
17
18
19
20
21
22
# File 'lib/ontomde-uml2-java/build.rb', line 16

def java_ClassRelativeDir
	p="#{context[:javaDir]}"
	p="#{context[:webContentRelativeDir,p]}"
	p="#{p}/WEB-INF/classes"
	p="#{context[:javaClassDir,p]}"
	return p
end

#java_generateObject

Main java generator entry point. Triggers the generation of every Java file for the model.



125
126
127
128
129
# File 'lib/ontomde-uml2-java/java.rb', line 125

def java_generate
  uml_Model_all.each {|m|
    m.java_generate
  }
end

#java_generateAntBuildFileObject



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
# File 'lib/ontomde-uml2-java/build.rb', line 26

def java_generateAntBuildFile
	return unless context[:generateAntBuildFile,false]

mtk_writeSession("#{context[:targetDir]}/build.xml") {
	write  %{
<project name="demo" default="all">

<target name="all" depends="compile,log4j" />

<target name="compile">
	<mkdir dir="#{java_ClassRelativeDir}" />
	<sync todir="#{java_ClassRelativeDir}">
		<fileset dir="#{context[:javaRelativeDir]}">
			<include name="**/*"/>
			<exclude name="**/*.java"/>
		</fileset>
		<!-- only supported if ant >=1.7
		<preserveintarget>
			<include name="**/*.class"/>
		</preserveintarget>
		-->
	</sync>
	<javac srcdir="#{context[:javaRelativeDir]}" destdir="#{java_ClassRelativeDir}" debug="yes">
		<classpath>
			<!-- catch-all -->
			<fileset dir="." includes="**/*.jar" />
		</classpath>
		<compilerarg value="-Xlint:deprecation"/>
		<compilerarg value="-Xlint:unchecked"/>
	</javac>
</target>
<target name="log4j">
	<concat destfile="#{java_ClassRelativeDir}/log4j.properties">
      		<header filtering="no" trimleading="yes">
			# ---------------------------------------
			# Changes to this file will be deleted
			# on next ant build because
			# this file is the concatenation of
			# file matching log4j*.properties
			# in #{context[:javaRelativeDir]}"
			# ---------------------------------------
      		</header>

		<fileset dir="#{context[:javaRelativeDir]}" includes="log4j*.properties"/>
	</concat>
</target>
<target name="clean" />

</project>
}
	}
end

#java_generatePackageDocObject

generates java documentation files (package-info.java) for packages directly containing elements (class, enum, interface) cf: java.sun.com/docs/books/jls/third_edition/html/packages.html



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/ontomde-uml2-java/javadoc.rb', line 193

def java_generatePackageDoc
  return unless context[:javadoc]
  java_getUsedPackages.each { |packageName,packageSet|
    fn=nil
    packageSet.each { |package|
      fn="#{package.java_FilePath}/#{package.java_Name}/package-info.java"
      break
    }
    mtk_writeSession(fn) {
      write("/**\n")
      packageSet.each { |package|
        package.uml_ownedComment.each { |comment|
          comment.uml_body_one.java_writeJavadoc(self)
        }
      }
      write("**/\n\n")
      write("package #{packageName};\n")
    }
  }
end

#java_getUsedPackagesObject

returns a hash of package sets for which a javadoc should be generated. hash key is the qualifiedName of the packages (several uml packages may have the same name in different UML models)

A package is included if :

  • it contains a generated class/interface/enum

  • it contains a uml comment



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/ontomde-uml2-java/javadoc.rb', line 158

def java_getUsedPackages

  ps=Hash.new
  uml_Class_all.each  { |e|
    p=e.umlx_owner_one
    next unless p.kind_of?(Muml_Package)
    next if p.kind_of?(Muml_Model)
    next if e.umlx_external?
    pn=p.java_qualifiedName.to_s
    s=ps[pn]
    if s.nil?
      s=Set.new
      ps[pn]=s
    end
    s.add(p)
  }

  each { |k,p|
    next unless p.kind_of?(Muml_Package)
    next if p.kind_of?(Muml_Model)
    next if p.uml_ownedComment.empty?
    pn=p.java_qualifiedName.to_s
    s=ps[pn]
    if s.nil?
      s=Set.new
      ps[pn]=s
    end
    s.add(p)
  }
  return ps
end

#java_transform!Object

trigger Muml_Classifier java_transform! for every class element



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ontomde-uml2-java/java.rb', line 107

def java_transform!
  #must copy before transformation (hash modified runtime error)
  a=Array.new
  each { |k,c|
    next if c.kind_of?(Muml_Stereotype)
    next unless c.kind_of?(Muml_Class) || c.kind_of?(Muml_Interface)||c.kind_of?(Muml_Enumeration)
    a << c
  }
  a.each {|c|
    c.java_transform! unless c.java_ignoreMe?
  }

  #java_addPersistence!
  umlx_processStereotypes!
end

#struts_addAllOperationAggregateParameterClass!Object



17
18
19
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
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/ontomde-uml2-java/operationAsClass.rb', line 17

def struts_addAllOperationAggregateParameterClass!
	return unless context[:withGenerateMethodForm]

	uml_Class_all.each {|c|
		#exclude classes explicitely set to false
		next if (!c.umlx_businessMethod.empty?) && (!c.umlx_businessMethod?)
	c.uml_ownedOperation.each {|biz|
		#next if c.java_isATestFile?
		next unless biz.kind_of?(Muml_Operation)
		next unless biz.umlx_businessMethod?
		next if biz.umlx_isConstructor?
		next if biz.uml_visibility_one.isPrivate?
		next if biz.uml_visibility_one.isProtected?
		next if biz.uml_isStatic?
		#c=biz.umlx_owner_one

		p=c.umlx_package
		if p.nil?
			log.error{"Model modification required !!! class #{c} is in root model element. Classes should be in a package."}
			next
		end
		next unless c.kind_of?(Muml_Class)

		p=p.umlx_getOrCreatePackage(context[:classMethodSubDir,"methods"],p)
		#BUG:biz_uri ne suffisait pas car si 2 classes immplémnetaient 2 fois une méthode d'une classe abstraite
		#la classe crée avait les 2 mêmes uri et donc était zappé par la suite(notamment le java_transform
		mpc=p.umlx_createAndAddClass(c.rdf_uri+biz.rdf_uri+"_mpc2");
		mpc.umlx_businessMethod=RDF_TRUE
		mpc.struts_addAllOperationAggregateParameterClass!(biz)
		mpc.db_isTransient=RDF_TRUE

		m=mpc.umlx_createAndAddOperation(mpc.rdf_uri+"merge","merge");
                #TODO merge referenced items
		m.java_code="return this; "
		p=m.umlx_createAndAddReturnParameter(m.rdf_uri+'_ret',"return")
		p.uml_type=mpc

	}}
end

#umlx_generateStaticSecurityRoleEnumObject

model may contain several enumeration of roles stereotypes staticSecurityRole For implementation use, an enumeration containing every roles is generated. Role container name could be appended to role name but it is not because it would make code refactoring more complex. As a consequence, role name should be unique application wide.



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/ontomde-uml2-java/security.rb', line 105

def  umlx_generateStaticSecurityRoleEnum
  e=umlx_reserved_model.umlx_getOrCreateEnumeration(JAVA_GLOBAL_ACCESS_CONTROL_ENUM,Muml_Classifier::UMLX_SEARCH_EVERY_MODEL)
  e.umlx_createAndAddComment("#{e.rdf_uri}_comment",JAVA_GLOBAL_ACCESS_CONTROL_ENUM_COMMENT) if e.uml_ownedComment.empty?

  self.each_value { |v|
    next unless v.kind_of?(Muml_Enumeration)
    #next unless v.umlx_hasStereotype?("staticSecurityRole")
    next unless v.umlx_hasStereotype?("ComputedAccessControlCriteria")
    v.uml_ownedLiteral.each {|c|
      #role name should be unique
      e.umlx_createAndAddLiteral(c.to_s)
    }
  }
end

#umlx_getSecuredMethodEnumerationObject

Retrieve an enumeration that will contain a list of secured methods



20
21
22
# File 'lib/ontomde-uml2-java/security.rb', line 20

def umlx_getSecuredMethodEnumeration
  return umlx_reserved_model.umlx_getOrCreateEnumeration("xmda.security.SecuredMethodInventory",Muml_Classifier::UMLX_SEARCH_EVERY_MODEL)
end

#umlx_getSecuredPropertyEnumerationObject

Retrieve an enumeration that will contain a list of secured property



121
122
123
# File 'lib/ontomde-uml2-java/security.rb', line 121

def umlx_getSecuredPropertyEnumeration
  return umlx_reserved_model.umlx_getOrCreateEnumeration("xmda.security.SecuredPropertyInventory",Muml_Classifier::UMLX_SEARCH_EVERY_MODEL)
end

#umlx_populateSecuredMethodEnumerationObject



24
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
# File 'lib/ontomde-uml2-java/security.rb', line 24

def umlx_populateSecuredMethodEnumeration
  umlx_generateStaticSecurityRoleEnum
  e=umlx_getSecuredMethodEnumeration

  #populate inventory
  uml_Class_all.each {|c|
    next unless c.umlx_businessMethod?
    next if c.kind_of?(Muml_Interface)
    cn="#{c.java_qualifiedName}.class"
    c.uml_ownedOperation.each  {|op|
      next unless op.umlx_businessMethod?
	next unless op.umlx_isSecured?
      #operation was generated from an interface
      next if (!op.umlx_redefinesMethod.empty?) && (!op.umlx_redefinesMethod_one.umlx_owner_one.kind_of?(Muml_Interface))
      lit=e.umlx_createAndAddLiteral("#{op.umlx_owner_one.java_qualifiedName}_#{op.java_Name}")
      lit.java_initParameterValue_add(cn)
      lit.java_initParameterValue_add(%{"#{op.java_Name}"})
    }
  }

  cc=umlx_reserved_model.umlx_getOrCreateClass("java.lang.Classxx")
  cc.uml_name="Class<?>"
  cc.java_isGeneric=RDF_TRUE

  str=e.umlx_owner_one.umlx_dataType_string
  # add constructor
  c=e.umlx_createAndAddOperation("#{c}.constructor","constructor")
  c.uml_appliedStereotype_add(e.umlx_getOrCreateStereotype("Create"))
  c.uml_visibility=::Cuml_VisibilityKind::Private
  p1=c.umlx_createAndAddParameter("#{c.uri}_p1","_ownerClass")
  p1.uml_type=cc
  p2=c.umlx_createAndAddParameter("#{c.uri}_p2","_operationName")
  p2.uml_type=str
  c.java_code="ownerClass=_ownerClass;\noperationName=_operationName;"

  #add attributes
  a1=e.umlx_createAndAddProperty("#{e}_a1","ownerClass")
  a1.uml_type=cc
  a2=e.umlx_createAndAddProperty("#{e}_a2","operationName")
  a2.uml_type=str

  #add finder
  f=e.umlx_createAndAddOperation("#{e.uri}_find","find")
  f.uml_isStatic=RDF_TRUE
  a1=f.umlx_createAndAddParameter("#{e}_a1","ownerClass")
  a1.uml_type=cc
  a2=f.umlx_createAndAddParameter("#{e}_a2","operationName")
  a2.uml_type=str
  a3=f.umlx_createAndAddReturnParameter("#{e}_ret","enum")
  a3.uml_type=e
  f.java_code=<<END
//TODO !!!!!!!!!!!
return null ; //#{e.java_Name}
END

end

#umlx_populateSecuredPropertyEnumerationObject



125
126
127
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/ontomde-uml2-java/security.rb', line 125

def umlx_populateSecuredPropertyEnumeration
  #umlx_generateStaticSecurityRoleEnum
  e=umlx_getSecuredPropertyEnumeration

  #populate inventory
  uml_Class_all.each {|c|
    next unless c.umlx_businessMethod?
    
    #Hack: transient operation 
    #next if c.db_isTransient?
    
    
    next if c.kind_of?(Muml_Interface)
    cn="#{c.java_qualifiedName}.class"
    c.uml_ownedAttribute.each  {|op|
      #next unless op.umlx_businessMethod?
      #operation was generated from an interface
      #next if (!op.umlx_redefinesProperty.empty?) && (!op.umlx_redefinesProperty_one.umlx_owner_one.kind_of?(Muml_Interface))
      lit=e.umlx_createAndAddLiteral("#{op.umlx_owner_one.java_qualifiedName}_#{op.java_Name}")
      lit.java_initParameterValue_add(cn)
      lit.java_initParameterValue_add(%{"#{op.java_Name}"})
      lit.java_initParameterValue_add(op.umlx_isSecured?)
    }
  }


  #Classxx is on purpose
  cc=umlx_reserved_model.umlx_getOrCreateClass("java.lang.Classxx")
  cc.uml_name="Class<?>"
  cc.java_isGeneric=RDF_TRUE

  str=e.umlx_owner_one.umlx_dataType_string
  bol=e.umlx_owner_one.umlx_dataType_boolean
  # add constructor
  c=e.umlx_createAndAddOperation("#{c}.constructor","constructor")
  c.uml_appliedStereotype_add(e.umlx_getOrCreateStereotype("Create"))
  c.uml_visibility=::Cuml_VisibilityKind::Private
  p1=c.umlx_createAndAddParameter("#{c.uri}_p1","_ownerClass")
  p1.uml_type=cc
  p2=c.umlx_createAndAddParameter("#{c.uri}_p2","_propertyName")
  p2.uml_type=str
  p3=c.umlx_createAndAddParameter("#{c.uri}_p3","_isSecured")
  p3.uml_type=bol
  c.java_code="ownerClass=_ownerClass;\npropertyName=_propertyName;\nisSecured=_isSecured;"

  #add attributes
  a1=e.umlx_createAndAddProperty("#{e}_a1","ownerClass")
  a1.uml_type=cc
  a2=e.umlx_createAndAddProperty("#{e}_a2","propertyName")
  a2.uml_type=str
  a3=e.umlx_createAndAddProperty("#{e}_a2","isSecured")
  a3.uml_type=bol


  #add finder
  f=e.umlx_createAndAddOperation("#{e.uri}_find","find")
  f.uml_isStatic=RDF_TRUE
  a1=f.umlx_createAndAddParameter("#{e}_a1","ownerClass")
  a1.uml_type=cc
  a2=f.umlx_createAndAddParameter("#{e}_a2","propertyName")
  a2.uml_type=str
  a3=f.umlx_createAndAddReturnParameter("#{e}_ret","enum")
  a3.uml_type=e
  f.java_code=<<END
//TODO !!!!!!!!!!!
return null ; //#{e.java_Name}
END

end

#umlx_processSecuredElementsObject

process element marked as secured



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/ontomde-uml2-java/security.rb', line 199

def umlx_processSecuredElements
  e=umlx_reserved_model.umlx_getOrCreateInterface("org.acegisecurity.userdetails.UserDetails")
  
  uml_Class_all.each {|c|
    #sec=false
    next if c.kind_of?(Muml_Interface) || c.kind_of?(Muml_Enumeration)
    c.uml_ownedOperation.each {|o|
      next unless o.umlx_isSecured? 
      o.java_annotation_add(JAVA_SECURE_ANNOTATION)
      #sec=true
    } 
    c.uml_ownedAttribute.each { |a|
      next unless a.umlx_isSecured?
      a.java_annotation_add(JAVA_SECURE_ANNOTATION)
      #sec=true
    }
    c.umlx_addGetStaticRoleOperation! #if sec
  }
end

#umlx_processStereotypes!Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/ontomde-uml2-java/java.rb', line 84

def umlx_processStereotypes!
  return
  each { |k,c|
    next unless c.kind_of?(Muml_Stereotype)
    #log.debug "Registering stereotype #{c.getRubyStereotypeName}"
    eval %{
	module ::Muml_Stereotype_#{c.getRubyStereotypeName}
	end
    }
  }
  each {|k,c|
    next unless c.kind_of?(Muml_Element)
    next if c.appliedStereotype.empty?
    appliedStereotype.each { |s|
      c.class_eval %{

      }
    }
  }

end