<% define 'GenerateMetamodel', :for => EPackage do |filename| %>
<% file filename do %>
require 'rgen/metamodel_builder'
<%nl%>
<% if needClassReorder? %>
<% expand 'GeneratePackagesOnly' %>
<% expand 'GenerateClassesReordered' %>
<% else %>
<% expand 'GeneratePackage' %>
<% end %>
<%nl%>
<% expand 'GenerateAssocs' %>
<% end %>
<% end %>
<% define 'GeneratePackage', :for => EPackage do %>
module <%= moduleName %><% iinc %>
extend RGen::MetamodelBuilder::ModuleExtension
include RGen::MetamodelBuilder::DataTypes
<% expand 'annotations::Annotations' %>
<%nl%>
<% expand 'EnumTypes' %>
<% for c in ownClasses %><%nl%>
<% expand 'ClassHeader', this, :for => c %><%iinc%>
<% if c.abstract %>abstract<% end %>
<% expand 'annotations::Annotations', :for => c %>
<% expand 'Attribute', this, :foreach => c.eAttributes %>
<%idec%>
end
<% end %><%nl%>
<% for p in eSubpackages %>
<%nl%><% expand 'GeneratePackage', :for => p %>
<% end %><%idec%>
end
<% end %>
<% define 'GenerateClassesReordered', :for => EPackage do %>
<% for c in allClassesSorted %><%nl%>
<% expand 'ClassHeaderFullyQualified', this, :for => c %><%iinc%>
<% if c.abstract %>abstract<% end %>
<% expand 'annotations::Annotations', :for => c %>
<% expand 'Attribute', this, :foreach => c.eAttributes %>
<%idec%>
end
<% end %><%nl%>
<% end %>
<% define 'GeneratePackagesOnly', :for => EPackage do %>
module <%= moduleName %><% iinc %>
extend RGen::MetamodelBuilder::ModuleExtension
include RGen::MetamodelBuilder::DataTypes
<% expand 'annotations::Annotations' %>
<%nl%>
<% expand 'EnumTypes' %>
<% for p in eSubpackages %>
<%nl%><% expand 'GeneratePackagesOnly', :for => p %>
<% end %><%idec%>
end
<% end %>
<% define 'Attribute', :for => EAttribute do |rootp| %>
<% if upperBound == 1%>has_attr<% else %>has_many_attr<% end %> '<%= name %>', <%nows%>
<% if eType.is_a?(EEnum) %><%nows%>
<%= eType.qualifiedClassifierName(rootp) %><%nows%>
<% else %><%nows%>
<%= eType && eType.instanceClass.to_s %><%nows%>
<% end %><%nows%>
<% for p in RGen::MetamodelBuilder::Intermediate::Attribute.properties %>
<% unless p == :name || (p == :upperBound && (upperBound == 1 || upperBound == -1)) ||
RGen::MetamodelBuilder::Intermediate::Attribute.default_value(p) == getGeneric(p) %>
, :<%=p%> => <%nows%>
<% if getGeneric(p).is_a?(String) %>
"<%= getGeneric(p) %>"<%nows%>
<% elsif getGeneric(p).is_a?(Symbol) %>
:<%= getGeneric(p) %><%nows%>
<% else %>
<%= getGeneric(p) %><%nows%>
<% end %>
<% end %>
<% end %>
<%ws%><% expand 'annotations::Annotations' %><%nl%>
<% end %>
<% define 'EnumTypes', :for => EPackage do %>
<% for enum in eClassifiers.select{|c| c.is_a?(EEnum)} %>
<%= enum.name %> = Enum.new(:name => '<%= enum.name %>', :literals =>[ <%nows%>
<%= enum.eLiterals.collect { |lit| ":"+(lit.name =~ /^\d|\W/ ? "'"+lit.name+"'" : lit.name) }.join(', ') %> ])
<% end %>
<% end %>
<% define 'GenerateAssocs', :for => EPackage do %>
<% refDone = {} %>
<% for ref in eAllClassifiers.select{|c| c.is_a?(EClass)}.eReferences %>
<% if !refDone[ref] && ref.eOpposite %>
<% ref = ref.eOpposite if ref.eOpposite.containment %>
<% refDone[ref] = refDone[ref.eOpposite] = true %>
<% if !ref.many && !ref.eOpposite.many %>
<% if ref.containment %>
<% expand 'Reference', "contains_one", this, :for => ref %>
<% else %>
<% expand 'Reference', "one_to_one", this, :for => ref %>
<% end %>
<% elsif !ref.many && ref.eOpposite.many %>
<% expand 'Reference', "many_to_one", this, :for => ref %>
<% elsif ref.many && !ref.eOpposite.many %>
<% if ref.containment %>
<% expand 'Reference', "contains_many", this, :for => ref %>
<% else %>
<% expand 'Reference', "one_to_many", this, :for => ref %>
<% end %>
<% elsif ref.many && ref.eOpposite.many %>
<% expand 'Reference', "many_to_many", this, :for => ref %>
<% end %>
<% expand 'annotations::Annotations', :for => ref %><%nl%>
<% elsif !refDone[ref] %>
<% refDone[ref] = true %>
<% if !ref.many %>
<% if ref.containment %>
<% expand 'Reference', "contains_one_uni", this, :for => ref %>
<% else %>
<% expand 'Reference', "has_one", this, :for => ref %>
<% end %>
<% elsif ref.many %>
<% if ref.containment %>
<% expand 'Reference', "contains_many_uni", this, :for => ref %>
<% else %>
<% expand 'Reference', "has_many", this, :for => ref %>
<% end %>
<% end %>
<% expand 'annotations::Annotations', :for => ref %><%nl%>
<% end %>
<% end %>
<% end %>
<% define 'Reference', :for => EReference do |cmd, rootpackage| %>
<%= eContainingClass.qualifiedClassifierName(rootpackage) %>.<%= cmd %> '<%= name %>', <%= eType && eType.qualifiedClassifierName(rootpackage) %><%nows%>
<% if eOpposite %><%nows%>
, '<%= eOpposite.name%>'<%nows%>
<% end %><%nows%>
<% pset = RGen::MetamodelBuilder::Intermediate::Reference.properties.reject{|p| p == :name || p == :upperBound || p == :containment} %>
<% for p in pset.reject{|p| RGen::MetamodelBuilder::Intermediate::Reference.default_value(p) == getGeneric(p)} %>
, :<%=p%> => <%=getGeneric(p)%><%nows%>
<% end %>
<% if eOpposite %>
<% for p in pset.reject{|p| RGen::MetamodelBuilder::Intermediate::Reference.default_value(p) == eOpposite.getGeneric(p)} %>
, :opposite_<%=p%> => <%=eOpposite.getGeneric(p)%><%nows%>
<% end %>
<% end %><%ws%>
<% end %>
<% define 'ClassHeader', :for => EClass do |rootp| %>
class <%= classifierName %> < <% nows %>
<% if eSuperTypes.size > 1 %><% nows %>
RGen::MetamodelBuilder::MMMultiple(<%= eSuperTypes.collect{|t| t.qualifiedClassifierNameIfRequired(rootp)}.join(', ') %>)
<% elsif eSuperTypes.size > 0 %><% nows %>
<%= eSuperTypes.first.qualifiedClassifierNameIfRequired(rootp) %>
<% else %><% nows %>
RGen::MetamodelBuilder::MMBase
<% end %>
<% end %>
<% define 'ClassHeaderFullyQualified', :for => EClass do |rootp| %>
class <%= qualifiedClassifierName(rootp) %> < <% nows %>
<% if eSuperTypes.size > 1 %><% nows %>
RGen::MetamodelBuilder::MMMultiple(<%= eSuperTypes.collect{|t| t.qualifiedClassifierName(rootp)}.join(', ') %>)
<% elsif eSuperTypes.size > 0 %><% nows %>
<%= eSuperTypes.first.qualifiedClassifierName(rootp) %>
<% else %><% nows %>
RGen::MetamodelBuilder::MMBase
<% end %>
<% end %>