rgen-0.7.0/0000755000004100000410000000000012352210062012472 5ustar www-datawww-datargen-0.7.0/Rakefile0000644000004100000410000000306112352210062014137 0ustar www-datawww-datarequire 'rubygems/package_task' require 'rdoc/task' RGenGemSpec = Gem::Specification.new do |s| s.name = %q{rgen} s.version = "0.7.0" s.date = Time.now.strftime("%Y-%m-%d") s.summary = %q{Ruby Modelling and Generator Framework} s.email = %q{martin dot thiede at gmx de} s.homepage = %q{http://ruby-gen.org} s.rubyforge_project = %q{rgen} s.description = %q{RGen is a framework for Model Driven Software Development (MDSD) in Ruby. This means that it helps you build Metamodels, instantiate Models, modify and transform Models and finally generate arbitrary textual content from it.} s.authors = ["Martin Thiede"] gemfiles = Rake::FileList.new gemfiles.include("{lib,test}/**/*") gemfiles.include("README.rdoc", "CHANGELOG", "MIT-LICENSE", "Rakefile") gemfiles.exclude(/\b\.bak\b/) s.files = gemfiles s.rdoc_options = ["--main", "README.rdoc", "-x", "test", "-x", "metamodels", "-x", "ea_support/uml13*"] s.extra_rdoc_files = ["README.rdoc", "CHANGELOG", "MIT-LICENSE"] end RDoc::Task.new do |rd| rd.main = "README.rdoc" rd.rdoc_files.include("README.rdoc", "CHANGELOG", "MIT-LICENSE", "lib/**/*.rb") rd.rdoc_files.exclude("lib/metamodels/*") rd.rdoc_files.exclude("lib/ea_support/uml13*") rd.rdoc_dir = "doc" end RGenPackageTask = Gem::PackageTask.new(RGenGemSpec) do |p| p.need_zip = false end task :prepare_package_rdoc => :rdoc do RGenPackageTask.package_files.include("doc/**/*") end task :release => [:prepare_package_rdoc, :package] task :clobber => [:clobber_rdoc, :clobber_package] rgen-0.7.0/CHANGELOG0000644000004100000410000002122212352210062013703 0ustar www-datawww-data=0.1.0 (August 3rd, 2006) * First public release =0.2.0 (September 3rd, 2006) * Added model transformation language (Transformer) * Now RGen is distributed as a gem * More complete documentation =0.3.0 (October 9th, 2006) * Improved XML Instantiator (Namespaces, Resolver, Customization) * Added many_to_one builder method * Added attribute reflection to MMBase (one_attributes, many_attributes) * Added +copy+ method to Transformer * Added simple model dumper module * Fixed mmgen/mmgen.rb =0.4.0 (Aug 8th, 2007) * Added ECore metamodel and use it as the core metametamodel * Revised and extended MetamodelBuilder language * There is an ECore instance describing each metamodel built using MetamodelBuilder now * Metamodel generator is now ECore based * Added Ruby implementation of Boolean and Enum types * Switched XML Instantiator to xmlscan for performance reasons * Cleaned up instantiator file structure * Renamed RGen::XMLInstantiator into RGen::Instantiator::DefaultXMLInstantiator * Included xmlscan as a redistributed module * Added support for chardata within XML tags * Added (Enterprise Architect) XMI to ECore instantiator * Some minor fixes in NameHelper * Some fixes to template language * Added UML1.3 Metamodel * Added tranformation from UML1.3 to ECore =0.4.1 (Nov 25th, 2007) * Template language performance improvement * Bugfix: use true/false instead of symbols for boolean attribute default values in metamodel classes * Minor fixes on metamodel generator and ecore primitive type handling * Made transformer implementation non-recursive to prevent "stack level too deep" exception for large models * Minor fixes on EAInstantiator * Made transformer search for matching rules for superclasses * Bugfix: Enums are now added to EPackages created using the "ecore" method on a module * Bugfix: Metamodel generator now writes enum names * Performance improvement: don't require ecore transformer every time someone calls "ecore" * Major performance improvement of template engine (no Regexps to check \n at end of line) * Major performance improvement: AbstractXMLInstantiator optionally controls the garbage collector * Major performance improvement: ERB templates are reused in metamodel_builder * Added delete method to Environment =0.4.2 (Mar 2nd, 2008) * Performance improvement: collection feature of array extension uses hashes now to speed up array union * Performance improvement: find on environment hashes elements by class * Extended Transformer to allow sharing of result maps between several Transformer instances * Bugfix: User defined upper bound values are no longer overwritten by -1 in all "many" metamodel builder methods =0.4.3 (Aug 12th, 2008) * Performance improvement: significant speed up of metamodel reverse registration * Bugfix: Use object identity for metamodel to-many add/remove methods * Bugfix: If expand's :for expression evaluates to nil an error is generated (silently used current context before) * Template language indentation string can be set on DirectoryTemplateContainer and with the "file" command =0.4.4 (Sep 10th, 2008) * Added "abstract" metamodel DSL command * Added ecore_ext.rb with convenience methods * Added XMI1.1 serializer, revised XMLSerializer super class =0.4.5 (Nov 17th, 2008) * Updated XMI1.1 serializer to support explicit placement of elements on content level of the XMI file =0.4.6 (Mar 1st, 2009) * Bugfix: expand :foreach silently assumed current context if :foreach evalutated to nil * Bugfix: fixed unit test for non-Windows plattforms (\r\n) * Bugfix: depending on the Ruby version and/or platform constants used in templates could not be resolved * Added automatic line ending detection (\n or \r\n) for template language +nl+ command =0.5.0 (Jun 8th, 2009) * Added ModelBuilder and ModelSerializer * Added template language "define_local" command * Added template language "evaluate" command * Fixed template language bug: indentation problem when expand continues a non-empty line * Fixed template language bug: template content expands several times when a template container is called recursively * Fixed template language bug: template resolution problem if a template file has the same name as a template directory * Cleaned up EA support * Added method to clear ecore metamodel reflection cache * Improved overriding of metamodel features in reopened classes =0.5.1 (Nov 10th, 2009) * Fixed metamodel builder bug: _register at one-side did not unregister from the element referenced by the old value * Added helper class for building simple model comparators =0.5.2 (Jun 13th, 2010) * Added has_many_attr to metamodel builder, support for "many" attributes * Added JSON support (json instantiator and serializer) * Added QualifiedNameResolver instantiation helper * Added reference proxy support * Added more generic access methods on metaclasses * Added ReferenceResolver resolver mixin * Fixed ecore xml instantiator and serializer to handle references to builtin datatypes correctly * Fixed bug in ecore xml serializer to not output references which are opposites of containment references =0.5.3 (Aug 13th, 2010) * Fixed string escaping in JSON instantiator and serializer * Fixed order of eClassifiers and eSubpackages within an EPackage created by reflection on a RGen module =0.5.4 * Fixed undeterministic order of child elements in ModelSerializer * Fixed undeterministic order of attributes in XMI serializers * Fixed ModelSerializer to always serialize the to-one part of bidirectional 1:N references * Fixed ModelSerializer to add :as => in case of ambiguous child roles * Made JsonInstantiator search subpackages for unqualified class names =0.6.0 * Added exception when trying to instantiate abstract class * Replaced xmlscan by dependency to nokogiri * Made RGen work with Ruby 1.9 * Cleaned up intermediate attribute and reference description, improvement of metamodel load time * Added optional data property for MMProxy * Added ECoreToRuby which can create Ruby classes and modules from ECore models in memory (without metamodel generator) * Refactored out QualifiedNameProvider and OppositeReferenceFilter * Added model fragment/fragmented models support * Extended Instantiator::ReferenceResolver and changed it into a class * Moved utilities into util folder/module * Added FileCacheMap * Fixed template language bug: indenting not correct after callback into same template container and iinc/idec * Added support for fragmented models * Added FileChangeDetector utility * Added CachedGlob utility * Added index parameter to model element add methods * Added MMGeneric * Modified has_many_attr to allow the same value in the same attribute multiple times * Made Environment#delete faster on large models * Added type check of ecore defaultValueLiteral content in MetamodelBuilder * Many-feature setters can work with an Enumerable instead of an Array * Added pattern matcher utility * Fixed problem of Ruby hanging when exceptions occur * Fixed metamodel generator to quote illegal enum literal symbols * Imporved UML to ECore transformer and EA support =0.6.1 * Fixed metamodel builder to not overwrite a model element's 'class' method * Added enum type transformation to ECoreToUML13 transformer, primitive type mapping based on instanceClassName * Fixed default value appearing on read after setting a feature value to nil * Added eIsSet and eUnset methods * Added eContainer and eContainingFeature methods * Fixed ModelFragment#elements not containing root elements * Added optional output of invalidation reason to FileCacheMap#load_data =0.6.2 * Made qualified name provider work with unidirectional containment references * Fixed array_extension breaking the Hash[] method =0.6.3 * Added BigDecimal support =0.6.4 * Made FileChangeDetector and FileCacheMap robust against missing files =0.6.5 * Fixed missing default argument of FragmentedModel#resolve * Added to_str to methods which aren't forwarded by array extension on empty arrays =0.6.6 * Added ModelFragment#mark_resolved and ResolutionHelper * Added ReferenceResolver option to output failed resolutions * Major performance improvement of FragmentedModel#resolve * Fixed a Ruby 2.0 related warning =0.7.0 * Enforce unique container rule by automatically disconnecting elements from other containers * Added support for long typed values (ELong), thanks to Thomas Hallgren; Note that this is merely an EMF compatibility thing, RGen could already handle big integers before * Added eContents and eAllContents methods * Added setNilOrRemoveGeneric and setNilOrRemoveAllGeneric methods * Added disconnectContainer method rgen-0.7.0/MIT-LICENSE0000644000004100000410000000204112352210062014123 0ustar www-datawww-dataCopyright (c) 2013 Martin Thiede Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. rgen-0.7.0/README.rdoc0000644000004100000410000000406712352210062014307 0ustar www-datawww-data= RGen - Ruby Modelling and Generator Framework RGen is a framework for Model Driven Software Development (MDSD)in Ruby. This means that it helps you build Metamodels, instantiate Models, modify and transform Models and finally generate arbitrary textual content from it. RGen features include: * Supporting Ruby 1.8.6, 1.8.7 and 1.9.x * Metamodel definition language (internal Ruby DSL) * ECore Meta-metamodel with an ECore instance available for every Metamodel * Generator creating the Ruby metamodel definition from an ECore instance * Transformer creating Ruby metamodel classes/modules from an ECore instance * Instantiation of Metamodels, i.e. creation of Models (e.g. from XML) * Model builder, internal Ruby DSL * Model fragmentation over several several files and per-fragment caching * Model Transformation language (internal Ruby DSL) * Powerful template based generator language (internal Ruby DSL inside of ERB) * UML 1.3 metamodel and XMI 1.1 instantiator included * ECore XML support (XMI 2.0) * UML-to-ECore and ECore-to-UML transformation (UML class models) * Enterprise Architect support (UML1.3/XMI1.1) == Download Get the latest release from Github: https://github.com/mthiede/rgen == Installation Install RGen as a Ruby gem: gem install rgen == Running the Tests Change to the 'test' folder and run the test suite: cd test ruby rgen_test.rb == Documentation RDoc documentation is available at Github: http://mthiede.github.com/rgen/ Find the main documentation parts for: * RGen::MetamodelBuilder * RGen::Transformer * RGen::TemplateLanguage * RGen::Fragment::FragmentedModel == Examples There are several examples of using RGen within the framework itself. Metamodel Definition: lib/rgen/ecore/ecore.rb lib/metamodels/uml13_metamodel.rb Instantiation: lib/rgen/instantiator/xmi11_instantiator.rb lib/rgen/instantiator/ecore_xml_instantiator.rb Transformations: lib/rgen/ecore/ruby_to_ecore.rb lib/transformers/uml13_to_ecore.rb Generators: lib/mmgen/metamodel_generator.rb == License RGen is released under the MIT license. rgen-0.7.0/lib/0000755000004100000410000000000012352210062013240 5ustar www-datawww-datargen-0.7.0/lib/ea_support/0000755000004100000410000000000012352210062015421 5ustar www-datawww-datargen-0.7.0/lib/ea_support/uml13_ea_metamodel_generator.rb0000644000004100000410000000362312352210062023455 0ustar www-datawww-datarequire 'metamodels/uml13_metamodel' require 'mmgen/metamodel_generator' require 'rgen/transformer' require 'rgen/environment' require 'rgen/ecore/ecore' include MMGen::MetamodelGenerator class ECoreCopyTransformer < RGen::Transformer copy_all RGen::ECore end eaMMRoot = ECoreCopyTransformer.new.trans(UML13.ecore) eaMMRoot.name = "UML13EA" eaMMRoot.eClassifiers.find{|c| c.name == "ActivityGraph"}.name = "ActivityModel" eaMMRoot.eClassifiers.find{|c| c.name == "Pseudostate"}.name = "PseudoState" compositeState = eaMMRoot.eClassifiers.find{|c| c.name == "CompositeState"} compositeState.eReferences.find{|r| r.name == "subvertex"}.name = "substate" generalization = eaMMRoot.eClassifiers.find{|c| c.name == "Generalization"} generalization.eReferences.find{|r| r.name == "parent"}.name = "supertype" generalization.eReferences.find{|r| r.name == "child"}.name = "subtype" assocEnd = eaMMRoot.eClassifiers.find{|c| c.name == "AssociationEnd"} assocEnd.eAttributes.find{|r| r.name == "ordering"}.name = "isOrdered" assocEnd.eAttributes.find{|r| r.name == "changeability"}.name = "changeable" assocEnd.eAttributes.find{|r| r.name == "isOrdered"}.eType = RGen::ECore::EBoolean assocEnd.eAttributes.find{|r| r.name == "changeable"}.eType.eLiterals.find{|l| l.name == "frozen"}.name = "none" multRef = assocEnd.eStructuralFeatures.find{|f| f.name == "multiplicity"} multRef.eType = nil assocEnd.removeEStructuralFeatures(multRef) assocEnd.addEStructuralFeatures(RGen::ECore::EAttribute.new(:name => "multiplicity", :eType => RGen::ECore::EString)) xmiIdProvider = RGen::ECore::EClass.new(:name => "XmiIdProvider", :ePackage => eaMMRoot) eaMMRoot.eClassifiers.each do |c| if %w(Package Class Generalization Association AssociationEnd StateVertex).include?(c.name) c.addESuperTypes(xmiIdProvider) end end generateMetamodel(eaMMRoot, File.dirname(__FILE__)+"/uml13_ea_metamodel.rb") rgen-0.7.0/lib/ea_support/id_store.rb0000644000004100000410000000117612352210062017563 0ustar www-datawww-datarequire 'yaml' class IdStore def initialize(fileName=nil) if fileName raise "Base directory does not exist: #{File.dirname(fileName)}" \ unless File.exist?(File.dirname(fileName)) @idsFileName = fileName end @idHash = nil end def idHash load unless @idHash @idHash end def load if @idsFileName && File.exist?(@idsFileName) @idHash = YAML.load_file(@idsFileName) || {} else @idHash = {} end end def store return unless @idsFileName File.open(@idsFileName,"w") do |f| YAML.dump(@idHash, f) end end endrgen-0.7.0/lib/ea_support/uml13_ea_metamodel_ext.rb0000644000004100000410000000220312352210062022260 0ustar www-datawww-datamodule UML13EA class << self attr_accessor :idStore end module ModelElement::ClassModule def qualifiedName _name = (respond_to?(:_name) ? self._name : name) || "unnamed" _namespace = respond_to?(:_namespace) ? self._namespace : namespace _namespace && _namespace.qualifiedName ? _namespace.qualifiedName+"::"+_name : _name end end module XmiIdProvider::ClassModule def _xmi_id UML13EA.idStore.idHash[qualifiedName] ||= "EAID_"+object_id.to_s end end module Package::ClassModule def _xmi_id UML13EA.idStore.idHash[qualifiedName] ||= "EAPK_"+object_id.to_s end end module Generalization::ClassModule def _name "#{subtype.name}_#{supertype.name}" end end module Association::ClassModule def _name connection.collect{|c| "#{c.getType.name}_#{c.name}"}.sort.join("_") end end module AssociationEnd::ClassModule def _name "#{getType.name}_#{name}" end def _namespace association end end module StateVertex::ClassModule def _namespace container end end end rgen-0.7.0/lib/ea_support/uml13_ea_to_uml13.rb0000644000004100000410000000635512352210062021110 0ustar www-datawww-datarequire 'rgen/transformer' require 'metamodels/uml13_metamodel' require 'ea_support/uml13_ea_metamodel' class UML13EAToUML13 < RGen::Transformer include UML13EA def transform trans(:class => Package) trans(:class => Class) @env_out.find(:class => UML13::Attribute).each do |me| # remove tagged vales internally used by EA which have been converted to UML me.taggedValue = me.taggedValue.reject{|tv| ["lowerBound", "upperBound"].include?(tv.tag)} end end def cleanModel @env_out.find(:class => UML13::ModelElement).each do |me| me.taggedValue = [] end end copy_all UML13EA, :to => UML13, :except => %w( XmiIdProvider AssociationEnd AssociationEndRole StructuralFeature Attribute Generalization ActivityModel CompositeState PseudoState Dependency ) transform AssociationEndRole, :to => UML13::AssociationEndRole do copyAssociationEnd end transform AssociationEnd, :to => UML13::AssociationEnd do copyAssociationEnd end def copyAssociationEnd copy_features :except => [:isOrdered, :changeable] do {:ordering => isOrdered ? :ordered : :unordered, :changeability => {:none => :frozen}[changeable] || changeable, :aggregation => {:shared => :aggregate}[aggregation] || aggregation, :multiplicity => UML13::Multiplicity.new( :range => [UML13::MultiplicityRange.new( :lower => multiplicity && multiplicity.split("..").first, :upper => multiplicity && multiplicity.split("..").last)])} end end transform StructuralFeature, :to => UML13::StructuralFeature, :if => lambda{|c| !@current_object.is_a?(UML13EA::Attribute)} do copy_features :except => [:changeable] do {:changeability => {:none => :frozen}[changeable] } end end transform StructuralFeature, :to => UML13::Attribute, :if => lambda{|c| @current_object.is_a?(UML13EA::Attribute)} do _lowerBound = taggedValue.find{|tv| tv.tag == "lowerBound"} _upperBound = taggedValue.find{|tv| tv.tag == "upperBound"} if _lowerBound || _upperBound _multiplicity = UML13::Multiplicity.new( :range => [UML13::MultiplicityRange.new( :lower => (_lowerBound && _lowerBound.value) || "0", :upper => (_upperBound && _upperBound.value) || "1" )]) end copy_features :except => [:changeable] do {:changeability => {:none => :frozen}[changeable], :multiplicity => _multiplicity } end end transform Generalization, :to => UML13::Generalization do copy_features :except => [:subtype, :supertype] do { :child => trans(subtype), :parent => trans(supertype) } end end copy ActivityModel, :to => UML13::ActivityGraph transform CompositeState, :to => UML13::CompositeState do copy_features :except => [:substate] do { :subvertex => trans(substate) } end end copy PseudoState, :to => UML13::Pseudostate transform Dependency, :to => UML13::Dependency do _name_tag = taggedValue.find{|tv| tv.tag == "dst_name"} copy_features do { :name => (_name_tag && _name_tag.value) || "Anonymous" } end end end rgen-0.7.0/lib/ea_support/uml13_to_uml13_ea.rb0000644000004100000410000000605712352210062021107 0ustar www-datawww-datarequire 'rgen/transformer' require 'metamodels/uml13_metamodel' require 'ea_support/uml13_ea_metamodel' require 'ea_support/uml13_ea_metamodel_ext' class UML13ToUML13EA < RGen::Transformer include UML13 def transform trans(:class => Package) trans(:class => Class) end copy_all UML13, :to => UML13EA, :except => %w( ActivityGraph CompositeState SimpleState Class Association AssociationEnd AssociationEndRole Generalization Pseudostate Attribute ) copy ActivityGraph, :to => UML13EA::ActivityModel copy Pseudostate, :to => UML13EA::PseudoState transform CompositeState, :to => UML13EA::CompositeState do copy_features :except => [:subvertex] do { :substate => trans(subvertex) } end end transform SimpleState, :to => UML13EA::SimpleState do copy_features :except => [:container] do { :taggedValue => trans(taggedValue) + [@env_out.new(UML13EA::TaggedValue, :tag => "ea_stype", :value => "State")] + (container ? [ @env_out.new(UML13EA::TaggedValue, :tag => "owner", :value => trans(container)._xmi_id)] : []) } end end transform Class, :to => UML13EA::Class do copy_features do { :taggedValue => trans(taggedValue) + [@env_out.new(UML13EA::TaggedValue, :tag => "ea_stype", :value => "Class")]} end end transform Association, :to => UML13EA::Association do copy_features do { :connection => trans(connection[1].isNavigable ? [connection[0], connection[1]] : [connection[1], connection[0]]), :taggedValue => trans(taggedValue) + [ @env_out.new(UML13EA::TaggedValue, :tag => "ea_type", :value => "Association"), @env_out.new(UML13EA::TaggedValue, :tag => "direction", :value => connection.all?{|c| c.isNavigable} ? "Bi-Directional" : "Source -> Destination")] } end end transform AssociationEnd, :to => UML13EA::AssociationEnd do copyAssociationEnd end transform AssociationEndRole, :to => UML13EA::AssociationEndRole do copyAssociationEnd end def copyAssociationEnd _lower = multiplicity && multiplicity.range.first.lower _upper = multiplicity && multiplicity.range.first.upper copy_features :except => [:multiplicity, :ordering, :changeability] do { :multiplicity => _lower == _upper ? _lower : "#{_lower}..#{_upper}", :isOrdered => ordering == :ordered, :changeable => :none } #{:frozen => :none}[changeability] || changeability} end end transform Attribute, :to => UML13EA::Attribute do copy_features :except => [:changeability] do { :changeable => {:frozen => :none}[changeability] } end end transform Generalization, :to => UML13EA::Generalization do copy_features :except => [:child, :parent] do { :taggedValue => trans(taggedValue) + [@env_out.new(UML13EA::TaggedValue, :tag => "ea_type", :value => "Generalization")], :subtype => trans(child), :supertype => trans(parent)} end end end rgen-0.7.0/lib/ea_support/uml13_ea_metamodel.rb0000644000004100000410000005205512352210062021412 0ustar www-datawww-datarequire 'rgen/metamodel_builder' module UML13EA extend RGen::MetamodelBuilder::ModuleExtension include RGen::MetamodelBuilder::DataTypes OperationDirectionKind = Enum.new(:name => 'OperationDirectionKind', :literals =>[ ]) MessageDirectionKind = Enum.new(:name => 'MessageDirectionKind', :literals =>[ ]) ChangeableKind = Enum.new(:name => 'ChangeableKind', :literals =>[ :changeable, :none, :addOnly ]) PseudostateKind = Enum.new(:name => 'PseudostateKind', :literals =>[ :initial, :deepHistory, :shallowHistory, :join, :fork, :branch, :junction, :final ]) ParameterDirectionKind = Enum.new(:name => 'ParameterDirectionKind', :literals =>[ :in, :inout, :out, :return ]) ScopeKind = Enum.new(:name => 'ScopeKind', :literals =>[ :instance, :classifier ]) OrderingKind = Enum.new(:name => 'OrderingKind', :literals =>[ :unordered, :ordered, :sorted ]) CallConcurrencyKind = Enum.new(:name => 'CallConcurrencyKind', :literals =>[ :sequential, :guarded, :concurrent ]) AggregationKind = Enum.new(:name => 'AggregationKind', :literals =>[ :none, :aggregate, :composite, :shared ]) VisibilityKind = Enum.new(:name => 'VisibilityKind', :literals =>[ :public, :protected, :private ]) end class UML13EA::Expression < RGen::MetamodelBuilder::MMBase has_attr 'language', String has_attr 'body', String end class UML13EA::ActionExpression < UML13EA::Expression end class UML13EA::Element < RGen::MetamodelBuilder::MMBase end class UML13EA::ModelElement < UML13EA::Element has_attr 'name', String has_attr 'visibility', UML13EA::VisibilityKind, :defaultValueLiteral => "public" has_attr 'isSpecification', Boolean end class UML13EA::Namespace < UML13EA::ModelElement end class UML13EA::GeneralizableElement < UML13EA::ModelElement has_attr 'isRoot', Boolean has_attr 'isLeaf', Boolean has_attr 'isAbstract', Boolean end class UML13EA::Classifier < RGen::MetamodelBuilder::MMMultiple(UML13EA::GeneralizableElement, UML13EA::Namespace) end class UML13EA::ClassifierRole < UML13EA::Classifier end class UML13EA::PresentationElement < UML13EA::Element end class UML13EA::DiagramElement < UML13EA::PresentationElement has_attr 'geometry', String has_attr 'style', String end class UML13EA::Feature < UML13EA::ModelElement has_attr 'ownerScope', UML13EA::ScopeKind, :defaultValueLiteral => "instance" end class UML13EA::BehavioralFeature < UML13EA::Feature has_attr 'isQuery', Boolean end class UML13EA::Method < UML13EA::BehavioralFeature end class UML13EA::Actor < UML13EA::Classifier end class UML13EA::DataType < UML13EA::Classifier end class UML13EA::Primitive < UML13EA::DataType end class UML13EA::Action < UML13EA::ModelElement has_attr 'isAsynchronous', Boolean end class UML13EA::SendAction < UML13EA::Action end class UML13EA::Interface < UML13EA::Classifier end class UML13EA::Event < UML13EA::ModelElement end class UML13EA::ChangeEvent < UML13EA::Event end class UML13EA::Partition < UML13EA::ModelElement end class UML13EA::Comment < UML13EA::ModelElement has_attr 'body', String end class UML13EA::ProgrammingLanguageType < UML13EA::DataType end class UML13EA::StateMachine < UML13EA::ModelElement end class UML13EA::Call < RGen::MetamodelBuilder::MMBase end class UML13EA::Operation < UML13EA::BehavioralFeature has_attr 'concurrency', UML13EA::CallConcurrencyKind, :defaultValueLiteral => "sequential" has_attr 'isRoot', Boolean has_attr 'isLeaf', Boolean has_attr 'isAbstract', Boolean end class UML13EA::XmiIdProvider < RGen::MetamodelBuilder::MMBase end class UML13EA::StateVertex < RGen::MetamodelBuilder::MMMultiple(UML13EA::ModelElement, UML13EA::XmiIdProvider) end class UML13EA::SynchState < UML13EA::StateVertex has_attr 'bound', Integer end class UML13EA::ClassifierInState < UML13EA::Classifier end class UML13EA::Link < UML13EA::ModelElement end class UML13EA::ProcedureExpression < UML13EA::Expression end class UML13EA::CallEvent < UML13EA::Event end class UML13EA::AssignmentAction < UML13EA::Action end class UML13EA::Relationship < UML13EA::ModelElement end class UML13EA::Association < RGen::MetamodelBuilder::MMMultiple(UML13EA::GeneralizableElement, UML13EA::Relationship, UML13EA::XmiIdProvider) end class UML13EA::AssociationRole < UML13EA::Association end class UML13EA::Diagram < UML13EA::PresentationElement has_attr 'name', String has_attr 'toolName', String has_attr 'diagramType', String has_attr 'style', String end class UML13EA::MultiplicityRange < RGen::MetamodelBuilder::MMBase has_attr 'lower', String has_attr 'upper', String end class UML13EA::ActionSequence < UML13EA::Action end class UML13EA::Constraint < UML13EA::ModelElement end class UML13EA::Instance < UML13EA::ModelElement end class UML13EA::UseCaseInstance < UML13EA::Instance end class UML13EA::State < UML13EA::StateVertex end class UML13EA::CompositeState < UML13EA::State has_attr 'isConcurrent', Boolean end class UML13EA::SubmachineState < UML13EA::CompositeState end class UML13EA::SubactivityState < UML13EA::SubmachineState has_attr 'isDynamic', Boolean end class UML13EA::StructuralFeature < UML13EA::Feature has_attr 'changeable', UML13EA::ChangeableKind, :defaultValueLiteral => "changeable" has_attr 'targetScope', UML13EA::ScopeKind, :defaultValueLiteral => "instance" end class UML13EA::Attribute < UML13EA::StructuralFeature end class UML13EA::Flow < UML13EA::Relationship end class UML13EA::Class < RGen::MetamodelBuilder::MMMultiple(UML13EA::Classifier, UML13EA::XmiIdProvider) has_attr 'isActive', Boolean end class UML13EA::Guard < UML13EA::ModelElement end class UML13EA::CreateAction < UML13EA::Action end class UML13EA::IterationExpression < UML13EA::Expression end class UML13EA::ReturnAction < UML13EA::Action end class UML13EA::Parameter < UML13EA::ModelElement has_attr 'kind', UML13EA::ParameterDirectionKind, :defaultValueLiteral => "inout" end class UML13EA::Dependency < UML13EA::Relationship end class UML13EA::Binding < UML13EA::Dependency end class UML13EA::Package < RGen::MetamodelBuilder::MMMultiple(UML13EA::Namespace, UML13EA::GeneralizableElement, UML13EA::XmiIdProvider) end class UML13EA::ObjectSetExpression < UML13EA::Expression end class UML13EA::StubState < UML13EA::StateVertex has_attr 'referenceState', String end class UML13EA::Stereotype < UML13EA::GeneralizableElement has_attr 'icon', String has_attr 'baseClass', String end class UML13EA::Object < UML13EA::Instance end class UML13EA::LinkObject < RGen::MetamodelBuilder::MMMultiple(UML13EA::Link, UML13EA::Object) end class UML13EA::ComponentInstance < UML13EA::Instance end class UML13EA::Usage < UML13EA::Dependency end class UML13EA::SignalEvent < UML13EA::Event end class UML13EA::Structure < UML13EA::DataType end class UML13EA::AssociationEnd < RGen::MetamodelBuilder::MMMultiple(UML13EA::ModelElement, UML13EA::XmiIdProvider) has_attr 'isNavigable', Boolean, :defaultValueLiteral => "false" has_attr 'isOrdered', Boolean, :defaultValueLiteral => "false" has_attr 'aggregation', UML13EA::AggregationKind, :defaultValueLiteral => "none" has_attr 'targetScope', UML13EA::ScopeKind, :defaultValueLiteral => "instance" has_attr 'changeable', UML13EA::ChangeableKind, :defaultValueLiteral => "changeable" has_attr 'multiplicity', String end class UML13EA::AssociationEndRole < UML13EA::AssociationEnd end class UML13EA::Signal < UML13EA::Classifier end class UML13EA::Exception < UML13EA::Signal end class UML13EA::Extend < UML13EA::Relationship end class UML13EA::Argument < UML13EA::ModelElement end class UML13EA::TemplateParameter < RGen::MetamodelBuilder::MMBase end class UML13EA::PseudoState < UML13EA::StateVertex has_attr 'kind', UML13EA::PseudostateKind, :defaultValueLiteral => "initial" end class UML13EA::SimpleState < UML13EA::State end class UML13EA::ActionState < UML13EA::SimpleState has_attr 'isDynamic', Boolean end class UML13EA::TypeExpression < UML13EA::Expression end class UML13EA::DestroyAction < UML13EA::Action end class UML13EA::TerminateAction < UML13EA::Action end class UML13EA::Generalization < RGen::MetamodelBuilder::MMMultiple(UML13EA::Relationship, UML13EA::XmiIdProvider) has_attr 'discriminator', String end class UML13EA::FinalState < UML13EA::State end class UML13EA::Subsystem < RGen::MetamodelBuilder::MMMultiple(UML13EA::Package, UML13EA::Classifier) has_attr 'isInstantiable', Boolean end class UML13EA::TimeExpression < UML13EA::Expression end class UML13EA::TaggedValue < UML13EA::Element has_attr 'tag', String has_attr 'value', String end class UML13EA::DataValue < UML13EA::Instance end class UML13EA::Transition < UML13EA::ModelElement end class UML13EA::NodeInstance < UML13EA::Instance end class UML13EA::Component < UML13EA::Classifier end class UML13EA::Message < UML13EA::ModelElement end class UML13EA::Enumeration < UML13EA::DataType end class UML13EA::Reception < UML13EA::BehavioralFeature has_attr 'isPolymorphic', Boolean has_attr 'specification', String end class UML13EA::Include < UML13EA::Relationship end class UML13EA::CallState < UML13EA::ActionState end class UML13EA::ElementResidence < RGen::MetamodelBuilder::MMBase has_attr 'visibility', UML13EA::VisibilityKind, :defaultValueLiteral => "public" end class UML13EA::UninterpretedAction < UML13EA::Action end class UML13EA::ArgListsExpression < UML13EA::Expression end class UML13EA::Stimulus < UML13EA::ModelElement end class UML13EA::AssociationClass < RGen::MetamodelBuilder::MMMultiple(UML13EA::Class, UML13EA::Association) end class UML13EA::Node < UML13EA::Classifier end class UML13EA::ElementImport < RGen::MetamodelBuilder::MMBase has_attr 'visibility', UML13EA::VisibilityKind, :defaultValueLiteral => "public" has_attr 'alias', String end class UML13EA::BooleanExpression < UML13EA::Expression end class UML13EA::Collaboration < RGen::MetamodelBuilder::MMMultiple(UML13EA::GeneralizableElement, UML13EA::Namespace) end class UML13EA::CallAction < UML13EA::Action end class UML13EA::UseCase < UML13EA::Classifier end class UML13EA::ActivityModel < UML13EA::StateMachine end class UML13EA::Permission < UML13EA::Dependency end class UML13EA::Interaction < UML13EA::ModelElement end class UML13EA::EnumerationLiteral < RGen::MetamodelBuilder::MMBase has_attr 'name', String end class UML13EA::Model < UML13EA::Package end class UML13EA::LinkEnd < UML13EA::ModelElement end class UML13EA::ExtensionPoint < UML13EA::ModelElement has_attr 'location', String end class UML13EA::Multiplicity < RGen::MetamodelBuilder::MMBase end class UML13EA::ObjectFlowState < UML13EA::SimpleState has_attr 'isSynch', Boolean end class UML13EA::AttributeLink < UML13EA::ModelElement end class UML13EA::MappingExpression < UML13EA::Expression end class UML13EA::TimeEvent < UML13EA::Event end class UML13EA::Abstraction < UML13EA::Dependency end class UML13EA::ActionInstance < RGen::MetamodelBuilder::MMBase end UML13EA::ClassifierRole.contains_one_uni 'multiplicity', UML13EA::Multiplicity UML13EA::ClassifierRole.has_many 'availableContents', UML13EA::ModelElement UML13EA::ClassifierRole.has_many 'availableFeature', UML13EA::Feature UML13EA::ClassifierRole.has_one 'base', UML13EA::Classifier, :lowerBound => 1 UML13EA::Diagram.contains_many 'element', UML13EA::DiagramElement, 'diagram' UML13EA::Method.many_to_one 'specification', UML13EA::Operation, 'method' UML13EA::Method.contains_one_uni 'body', UML13EA::ProcedureExpression UML13EA::SendAction.has_one 'signal', UML13EA::Signal, :lowerBound => 1 UML13EA::ChangeEvent.contains_one_uni 'changeExpression', UML13EA::BooleanExpression UML13EA::Partition.has_many 'contents', UML13EA::ModelElement UML13EA::Comment.many_to_many 'annotatedElement', UML13EA::ModelElement, 'comment' UML13EA::ProgrammingLanguageType.contains_one_uni 'type', UML13EA::TypeExpression UML13EA::Action.contains_one_uni 'recurrence', UML13EA::IterationExpression UML13EA::Action.contains_one_uni 'target', UML13EA::ObjectSetExpression UML13EA::Action.contains_one_uni 'script', UML13EA::ActionExpression UML13EA::Action.contains_many_uni 'actualArgument', UML13EA::Argument UML13EA::StateMachine.many_to_one 'context', UML13EA::ModelElement, 'behavior' UML13EA::StateMachine.contains_many_uni 'transitions', UML13EA::Transition UML13EA::StateMachine.contains_one_uni 'top', UML13EA::State, :lowerBound => 1 UML13EA::Operation.one_to_many 'occurrence', UML13EA::CallEvent, 'operation' UML13EA::ClassifierInState.has_one 'type', UML13EA::Classifier, :lowerBound => 1 UML13EA::ClassifierInState.has_many 'inState', UML13EA::State UML13EA::Link.contains_many_uni 'connection', UML13EA::LinkEnd, :lowerBound => 2 UML13EA::Link.has_one 'association', UML13EA::Association, :lowerBound => 1 UML13EA::PresentationElement.many_to_many 'subject', UML13EA::ModelElement, 'presentation' UML13EA::AssociationRole.contains_one_uni 'multiplicity', UML13EA::Multiplicity UML13EA::AssociationRole.has_one 'base', UML13EA::Association UML13EA::Diagram.has_one 'owner', UML13EA::ModelElement, :lowerBound => 1 UML13EA::ActionSequence.contains_many_uni 'action', UML13EA::Action UML13EA::Constraint.contains_one_uni 'body', UML13EA::BooleanExpression UML13EA::Constraint.many_to_many 'constrainedElement', UML13EA::ModelElement, 'constraint', :lowerBound => 1 UML13EA::SubactivityState.contains_one_uni 'dynamicArguments', UML13EA::ArgListsExpression UML13EA::AssociationEnd.contains_many 'qualifier', UML13EA::Attribute, 'associationEnd' UML13EA::Attribute.contains_one_uni 'initialValue', UML13EA::Expression UML13EA::Flow.many_to_many 'source', UML13EA::ModelElement, 'sourceFlow' UML13EA::Flow.many_to_many 'target', UML13EA::ModelElement, 'targetFlow' UML13EA::Guard.contains_one_uni 'expression', UML13EA::BooleanExpression UML13EA::CreateAction.has_one 'instantiation', UML13EA::Classifier, :lowerBound => 1 UML13EA::Namespace.contains_many 'ownedElement', UML13EA::ModelElement, 'namespace' UML13EA::Parameter.contains_one_uni 'defaultValue', UML13EA::Expression UML13EA::Parameter.many_to_many 'state', UML13EA::ObjectFlowState, 'parameter' UML13EA::Parameter.has_one 'type', UML13EA::Classifier, :lowerBound => 1 UML13EA::Binding.has_many 'argument', UML13EA::ModelElement, :lowerBound => 1 UML13EA::Event.contains_many_uni 'parameters', UML13EA::Parameter UML13EA::Dependency.many_to_many 'supplier', UML13EA::ModelElement, 'supplierDependency', :opposite_lowerBound => 1 UML13EA::Dependency.many_to_many 'client', UML13EA::ModelElement, 'clientDependency', :opposite_lowerBound => 1 UML13EA::Package.contains_many 'importedElement', UML13EA::ElementImport, 'package' UML13EA::Classifier.contains_many 'feature', UML13EA::Feature, 'owner' UML13EA::Stereotype.one_to_many 'extendedElement', UML13EA::ModelElement, 'stereotype' UML13EA::Stereotype.has_many 'requiredTag', UML13EA::TaggedValue UML13EA::ComponentInstance.has_many 'resident', UML13EA::Instance UML13EA::SignalEvent.many_to_one 'signal', UML13EA::Signal, 'occurrence', :lowerBound => 1 UML13EA::Instance.contains_many_uni 'slot', UML13EA::AttributeLink UML13EA::Instance.one_to_many 'linkEnd', UML13EA::LinkEnd, 'instance' UML13EA::Instance.has_many 'classifier', UML13EA::Classifier, :lowerBound => 1 UML13EA::AssociationEndRole.has_many 'availableQualifier', UML13EA::Attribute UML13EA::AssociationEndRole.has_one 'base', UML13EA::AssociationEnd UML13EA::Extend.many_to_one 'extension', UML13EA::UseCase, 'extend' UML13EA::Extend.contains_one_uni 'condition', UML13EA::BooleanExpression UML13EA::Extend.has_many 'extensionPoint', UML13EA::ExtensionPoint, :lowerBound => 1 UML13EA::Extend.has_one 'base', UML13EA::UseCase, :lowerBound => 1 UML13EA::Argument.contains_one_uni 'value', UML13EA::Expression UML13EA::TemplateParameter.has_one 'modelElement', UML13EA::ModelElement UML13EA::TemplateParameter.has_one 'defaultElement', UML13EA::ModelElement UML13EA::ActionState.contains_one_uni 'dynamicArguments', UML13EA::ArgListsExpression UML13EA::GeneralizableElement.one_to_many 'specialization', UML13EA::Generalization, 'supertype' UML13EA::GeneralizableElement.one_to_many 'generalization', UML13EA::Generalization, 'subtype' UML13EA::StateVertex.one_to_many 'incoming', UML13EA::Transition, 'target', :opposite_lowerBound => 1 UML13EA::StateVertex.one_to_many 'outgoing', UML13EA::Transition, 'source', :opposite_lowerBound => 1 UML13EA::CompositeState.contains_many 'substate', UML13EA::StateVertex, 'container', :lowerBound => 1 UML13EA::ModelElement.contains_many 'taggedValue', UML13EA::TaggedValue, 'modelElement' UML13EA::StructuralFeature.contains_one_uni 'multiplicity', UML13EA::Multiplicity UML13EA::StructuralFeature.has_one 'type', UML13EA::Classifier, :lowerBound => 1 UML13EA::Transition.has_one 'trigger', UML13EA::Event UML13EA::Transition.contains_one_uni 'effect', UML13EA::Action UML13EA::Transition.contains_one_uni 'guard', UML13EA::Guard UML13EA::NodeInstance.has_many 'resident', UML13EA::ComponentInstance UML13EA::Component.contains_many 'residentElement', UML13EA::ElementResidence, 'implementationLocation' UML13EA::Component.many_to_many 'deploymentLocation', UML13EA::Node, 'resident' UML13EA::Message.has_one 'action', UML13EA::Action, :lowerBound => 1 UML13EA::Message.has_one 'communicationConnection', UML13EA::AssociationRole UML13EA::Message.has_many 'predecessor', UML13EA::Message UML13EA::Message.has_one 'receiver', UML13EA::ClassifierRole, :lowerBound => 1 UML13EA::Message.has_one 'sender', UML13EA::ClassifierRole, :lowerBound => 1 UML13EA::Message.has_one 'activator', UML13EA::Message UML13EA::Interaction.contains_many 'message', UML13EA::Message, 'interaction', :lowerBound => 1 UML13EA::ModelElement.one_to_many 'elementResidence', UML13EA::ElementResidence, 'resident' UML13EA::ModelElement.contains_many_uni 'templateParameter', UML13EA::TemplateParameter UML13EA::ModelElement.one_to_many 'elementImport', UML13EA::ElementImport, 'modelElement' UML13EA::Enumeration.contains_many_uni 'literal', UML13EA::EnumerationLiteral, :lowerBound => 1 UML13EA::Reception.many_to_one 'signal', UML13EA::Signal, 'reception' UML13EA::Association.contains_many 'connection', UML13EA::AssociationEnd, 'association', :lowerBound => 2 UML13EA::Include.many_to_one 'base', UML13EA::UseCase, 'include' UML13EA::Include.has_one 'addition', UML13EA::UseCase, :lowerBound => 1 UML13EA::Classifier.many_to_many 'participant', UML13EA::AssociationEnd, 'specification' UML13EA::Classifier.one_to_many 'associationEnd', UML13EA::AssociationEnd, 'type' UML13EA::Stimulus.has_one 'dispatchAction', UML13EA::Action, :lowerBound => 1 UML13EA::Stimulus.has_one 'communicationLink', UML13EA::Link UML13EA::Stimulus.has_one 'receiver', UML13EA::Instance, :lowerBound => 1 UML13EA::Stimulus.has_one 'sender', UML13EA::Instance, :lowerBound => 1 UML13EA::Stimulus.has_many 'argument', UML13EA::Instance UML13EA::State.contains_one_uni 'doActivity', UML13EA::Action UML13EA::State.contains_many_uni 'internalTransition', UML13EA::Transition UML13EA::State.has_many 'deferrableEvent', UML13EA::Event UML13EA::State.contains_one_uni 'exit', UML13EA::Action UML13EA::State.contains_one_uni 'entry', UML13EA::Action UML13EA::Collaboration.has_one 'representedOperation', UML13EA::Operation UML13EA::Collaboration.has_one 'representedClassifier', UML13EA::Classifier UML13EA::Collaboration.has_many 'constrainingElement', UML13EA::ModelElement UML13EA::Collaboration.contains_many 'interaction', UML13EA::Interaction, 'context' UML13EA::CallAction.has_one 'operation', UML13EA::Operation, :lowerBound => 1 UML13EA::UseCase.has_many 'extensionPoint', UML13EA::ExtensionPoint UML13EA::ActivityModel.contains_many_uni 'partition', UML13EA::Partition UML13EA::Interaction.contains_many_uni 'link', UML13EA::Link UML13EA::LinkEnd.has_one 'associationEnd', UML13EA::AssociationEnd, :lowerBound => 1 UML13EA::LinkEnd.has_one 'participant', UML13EA::Instance, :lowerBound => 1 UML13EA::BehavioralFeature.many_to_many 'raisedSignal', UML13EA::Signal, 'context' UML13EA::BehavioralFeature.contains_many_uni 'parameter', UML13EA::Parameter UML13EA::SubmachineState.has_one 'submachine', UML13EA::StateMachine, :lowerBound => 1 UML13EA::Multiplicity.contains_many_uni 'range', UML13EA::MultiplicityRange, :lowerBound => 1 UML13EA::ObjectFlowState.has_one 'type', UML13EA::Classifier, :lowerBound => 1 UML13EA::ObjectFlowState.has_one 'available', UML13EA::Parameter, :lowerBound => 1 UML13EA::AttributeLink.has_one 'value', UML13EA::Instance, :lowerBound => 1 UML13EA::AttributeLink.has_one 'attribute', UML13EA::Attribute, :lowerBound => 1 UML13EA::TimeEvent.contains_one_uni 'when', UML13EA::TimeExpression UML13EA::Abstraction.contains_one_uni 'mapping', UML13EA::MappingExpression rgen-0.7.0/lib/ea_support/ea_support.rb0000644000004100000410000000332412352210062020131 0ustar www-datawww-datarequire 'ea_support/uml13_ea_metamodel' require 'ea_support/uml13_ea_metamodel_ext' require 'ea_support/uml13_to_uml13_ea' require 'ea_support/uml13_ea_to_uml13' require 'ea_support/id_store' require 'rgen/serializer/xmi11_serializer' require 'rgen/instantiator/xmi11_instantiator' require 'rgen/environment' module EASupport FIXMAP = { :tags => { "EAStub" => proc { |tag, attr| UML13EA::Class.new(:name => attr["name"]) if attr["UMLType"] == "Class" } } } INFO = XMI11Instantiator::INFO WARN = XMI11Instantiator::WARN ERROR = XMI11Instantiator::ERROR def self.instantiateUML13FromXMI11(envUML, fileName, options={}) envUMLEA = RGen::Environment.new xmiInst = XMI11Instantiator.new(envUMLEA, FIXMAP, options[:loglevel] || ERROR) xmiInst.add_metamodel("omg.org/UML1.3", UML13EA) File.open(fileName) do |f| xmiInst.instantiate(f.read) end trans = UML13EAToUML13.new(envUMLEA, envUML) trans.transform trans.cleanModel if options[:clean_model] end def self.serializeUML13ToXMI11(envUML, fileName, options={}) envUMLEA = RGen::Environment.new UML13EA.idStore = options[:keep_ids] ? IdStore.new(File.dirname(fileName)+"/"+File.basename(fileName)+".ids") : IdStore.new UML13ToUML13EA.new(envUML, envUMLEA).transform File.open(fileName, "w") do |f| xmiSer = RGen::Serializer::XMI11Serializer.new(f) xmiSer.setNamespace("UML","omg.org/UML1.3") xmiSer.serialize(envUMLEA.find(:class => UML13EA::Model).first, {:documentation => {:exporter => "Enterprise Architect", :exporterVersion => "2.5"}}) end UML13EA.idStore.store end endrgen-0.7.0/lib/transformers/0000755000004100000410000000000012352210062015765 5ustar www-datawww-datargen-0.7.0/lib/transformers/ecore_to_uml13.rb0000644000004100000410000000521612352210062021136 0ustar www-datawww-datarequire 'rgen/transformer' require 'rgen/ecore/ecore' require 'metamodels/uml13_metamodel' class ECoreToUML13 < RGen::Transformer include RGen::ECore def transform trans(:class => EPackage) trans(:class => EClass) trans(:class => EEnum) end transform EPackage, :to => UML13::Package do {:name => name, :namespace => trans(eSuperPackage) || model, :ownedElement => trans(eClassifiers.select{|c| c.is_a?(EClass)} + eSubpackages) } end transform EClass, :to => UML13::Class do {:name => name, :namespace => trans(ePackage), :feature => trans(eStructuralFeatures.select{|f| f.is_a?(EAttribute)} + eOperations), :associationEnd => trans(eStructuralFeatures.select{|f| f.is_a?(EReference)}), :generalization => eSuperTypes.collect { |st| @env_out.new(UML13::Generalization, :parent => trans(st), :namespace => trans(ePackage) || model) } } end transform EEnum, :to => UML13::Class do {:name => name, :namespace => trans(ePackage), :feature => trans(eLiterals) } end transform EEnumLiteral, :to => UML13::Attribute do {:name => name } end transform EAttribute, :to => UML13::Attribute do _typemap = {"String" => "string", "Boolean" => "boolean", "Integer" => "int", "Float" => "float"} {:name => name, :taggedValue => [@env_out.new(UML13::TaggedValue, :tag => "type", :value => _typemap[eType.instanceClassName] || eType.name)] } end transform EReference, :to => UML13::AssociationEnd do _otherAssocEnd = eOpposite ? trans(eOpposite) : @env_out.new(UML13::AssociationEnd, :type => trans(eType), :name => name, :multiplicity => createMultiplicity(@current_object), :aggregation => :none, :isNavigable => true) { :association => trans(@current_object).association || @env_out.new(UML13::Association, :connection => [_otherAssocEnd], :namespace => trans(eContainingClass.ePackage) || model), :name => eOpposite && eOpposite.name, :multiplicity => eOpposite && createMultiplicity(eOpposite), :aggregation => containment ? :composite : :none, :isNavigable => !eOpposite.nil? } end transform EOperation, :to => UML13::Operation do {:name => name} end def createMultiplicity(ref) @env_out.new(UML13::Multiplicity, :range => [ @env_out.new(UML13::MultiplicityRange, :lower => ref.lowerBound.to_s.sub("-1","*"), :upper => ref.upperBound.to_s.sub("-1","*"))]) end def model @model ||= @env_out.new(UML13::Model, :name => "Model") end end rgen-0.7.0/lib/transformers/uml13_to_ecore.rb0000644000004100000410000001070512352210062021135 0ustar www-datawww-datarequire 'metamodels/uml13_metamodel' require 'rgen/transformer' require 'rgen/ecore/ecore' require 'rgen/array_extensions' class UML13ToECore < RGen::Transformer include RGen::ECore # Options: # # :reference_filter: # a proc which receives an AssociationEnd or a Dependency and should return # true or false, depending on if a referece should be created for it or not # def initialize(*args) options = {} if args.last.is_a?(Hash) options = args.pop end @reference_filter = options[:reference_filter] || proc do |e| if e.is_a?(UML13::AssociationEnd) otherEnd = e.association.connection.find{|ae| ae != e} otherEnd.name && otherEnd.name.size > 0 else false end end super(*args) end def transform trans(:class => UML13::Class) end transform UML13::Model, :to => EPackage do trans(ownedClassOrPackage) { :name => name && name.strip } end transform UML13::Package, :to => EPackage do trans(ownedClassOrPackage) { :name => name && name.strip, :eSuperPackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil) } end method :ownedClassOrPackage do ownedElement.select{|e| e.is_a?(UML13::Package) || e.is_a?(UML13::Class)} end transform UML13::Class, :to => EClass do { :name => name && name.strip, :abstract => isAbstract, :ePackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil), :eStructuralFeatures => trans(feature.select{|f| f.is_a?(UML13::Attribute)} + associationEnd + clientDependency), :eOperations => trans(feature.select{|f| f.is_a?(UML13::Operation)}), :eSuperTypes => trans(generalization.parent + clientDependency.select{|d| d.stereotype && d.stereotype.name == "implements"}.supplier), :eAnnotations => createAnnotations(taggedValue) } end transform UML13::Interface, :to => EClass do { :name => name && name.strip, :abstract => isAbstract, :ePackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil), :eStructuralFeatures => trans(feature.select{|f| f.is_a?(UML13::Attribute)} + associationEnd), :eOperations => trans(feature.select{|f| f.is_a?(UML13::Operation)}), :eSuperTypes => trans(generalization.parent)} end transform UML13::Attribute, :to => EAttribute do { :name => name && name.strip, :eType => trans(getType), :lowerBound => (multiplicity && multiplicity.range.first.lower && multiplicity.range.first.lower.to_i) || 0, :upperBound => (multiplicity && multiplicity.range.first.upper && multiplicity.range.first.upper.gsub('*','-1').to_i) || 1, :eAnnotations => createAnnotations(taggedValue) } end transform UML13::DataType, :to => EDataType do { :name => name && name.strip, :ePackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil), :eAnnotations => createAnnotations(taggedValue) } end transform UML13::Operation, :to => EOperation do { :name => name && name.strip } end transform UML13::AssociationEnd, :to => EReference, :if => :isReference do otherEnd = association.connection.find{|ae| ae != @current_object} { :eType => trans(otherEnd.type), :name => otherEnd.name && otherEnd.name.strip, :eOpposite => trans(otherEnd), :lowerBound => (otherEnd.multiplicity && otherEnd.multiplicity.range.first.lower && otherEnd.multiplicity.range.first.lower.to_i) || 0, :upperBound => (otherEnd.multiplicity && otherEnd.multiplicity.range.first.upper && otherEnd.multiplicity.range.first.upper.gsub('*','-1').to_i) || 1, :containment => (aggregation == :composite), :eAnnotations => createAnnotations(association.taggedValue) } end transform UML13::Dependency, :to => EReference, :if => :isReference do { :eType => trans(supplier.first), :name => name, :lowerBound => 0, :upperBound => 1, :containment => false, :eAnnotations => createAnnotations(taggedValue) } end method :isReference do @reference_filter.call(@current_object) end def createAnnotations(taggedValues) if taggedValues.size > 0 [ EAnnotation.new(:details => trans(taggedValues)) ] else [] end end transform UML13::TaggedValue, :to => EStringToStringMapEntry do { :key => tag, :value => value} end end rgen-0.7.0/lib/rgen/0000755000004100000410000000000012352210062014173 5ustar www-datawww-datargen-0.7.0/lib/rgen/template_language.rb0000644000004100000410000002773512352210062020214 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 require 'rgen/template_language/directory_template_container' require 'rgen/template_language/template_container' module RGen # The RGen template language has been designed to build complex generators. # It is very similar to the EXPAND language of the Java based # OpenArchitectureWare framework. # # =Templates # # The basic idea is to allow "templates" not only being template files # but smaller parts. Those parts can be expanded from other parts very # much like Ruby methods are called from other methods. # Thus the term "template" refers to such a part within a "template file". # # Template files used by the RGen template language should have a # filename with the postfix ".tpl". Those files can reside within (nested) # template file directories. # # As an example a template directory could look like the following: # # templates/root.tpl # templates/dbaccess/dbaccess.tpl # templates/dbaccess/schema.tpl # templates/headers/generic_headers.tpl # templates/headers/specific/component.tpl # # A template is always called for a context object. The context object # serves as the receiver of methods called within the template. Details are given # below. # # # =Defining Templates # # One or more templates can be defined in a template file using the +define+ # keyword as in the following example: # # <% define 'GenerateDBAdapter', :for => DBDescription do |dbtype| %> # Content to be generated; use ERB syntax here # <% end %> # # The template definition takes three kinds of parameters: # 1. The name of the template within the template file as a String or Symbol # 2. An optional class object describing the class of context objects for which # this template is valid. # 3. An arbitrary number of template parameters # See RGen::TemplateLanguage::TemplateContainer for details about the syntax of +define+. # # Within a template, regular ERB syntax can be used. This is # * <% and %> are used to embed Ruby code # * <%= and %> are used to embed Ruby expressions with # the expression result being written to the template output # * <%# and %> are used for comments # All content not within these tags is written to the template output verbatim. # See below for details about output files and output formatting. # # All methods which are called from within the template are sent to the context # object. # # Experience shows that one easily forgets the +do+ at the end of the first # line of a template definition. This will result in an ERB parse error. # # # =Expanding Templates # # Templates are normally expanded from within other templates. The only # exception is the root template, which is expanded from the surrounding code. # # Template names can be specified in the following ways: # * Non qualified name: use the template with the given name in the current template file # * Relative qualified name: use the template within the template file specified by the relative path # * Absolute qualified name: use the template within the template file specified by the absolute path # # The +expand+ keyword is used to expand templates. # # Here are some examples: # # <% expand 'GenerateDBAdapter', dbtype, :for => dbDesc %> # # Non qualified. Must be called within the file where 'GenerateDBAdapter' is defined. # There is one template parameter passed in via variable +dbtype+. # The context object is provided in variable +dbDesc+. # # <% expand 'dbaccess::ExampleSQL' %> # # Qualified with filename. Must be called from a file in the same directory as 'dbaccess.tpl' # There are no parameters. The current context object will be used as the context # object for this template expansion. # # <% expand '../headers/generic_headers::CHeader', :foreach => modules %> # # Relatively qualified. Must be called from a location from which the file # 'generic_headers.tpl' is accessible via the relative path '../headers'. # The template is expanded for each module in +modules+ (which has to be an Array). # Each element of +modules+ will be the context object in turn. # # <% expand '/headers/generic_headers::CHeader', :foreach => modules %> # # Absolutely qualified: The same behaviour as before but with an absolute path from # the template directory root (which in this example is 'templates', see above) # # Sometimes it is neccessary to generate some text (e.g. a ',') in between the single # template expansion results from a :foreach expansion. This can be achieved by # using the :separator keyword: # # <% expand 'ColumnName', :foreach => column, :separator => ', ' %> # # Note that the separator may also contain newline characters (\n). See below for # details about formatting. # # # =Formatting # # For many generator tools a formatting postprocess (e.g. using a pretty printer) is # required in order to make the output readable. However, depending on the kind of # generated output, such a tool might not be available. # # The RGen template language has been design for generators which do not need a # postprocessing step. The basic idea is to eliminate all whitespace at the beginning # of template lines (the indentation that makes the _template_ readable) and output # newlines only after at least on character has been generated in the corresponding # line. This way there are no empty lines in the output and each line will start with # a non-whitspace character. # # Starting from this point one can add indentation and newlines as required by using # explicit formatting commands: # * <%nl%> (newline) starts a new line # * <%iinc%> (indentation increment) increases the current indentation # * <%idec%> (indentation decrement) decreases the current indentation # * <%nonl%> (no newline) ignore next newline # * <%nows%> (no whitespace) ignore next whitespace # # Indentation takes place for every new line in the output unless it is 0. # The initial indentation can be specified with a root +expand+ command by using # the :indent keyword. # # Here is an example: # # expand 'GenerateDBAdapter', dbtype, :for => dbDesc, :indent => 1 # # Initial indentation defaults to 0. Normally <%iinc%> and # <%idec%> are used to change the indentation. # The current indentation is kept for expansion of subtemplates. # # The string which is used to realize one indentation step can be set using # DirectoryTemplateContainer#indentString or with the template language +file+ command. # The default is " " (3 spaces), the indentation string given at a +file+ command # overwrites the container's default which in turn overwrites the overall default. # # Note that commands to ignore whitespace and newlines are still useful if output # generated from multiple template lines should show up in one single output line. # # Here is an example of a template generating a C program: # # #include # <%nl%> # int main() {<%iinc%> # printf("Hello World\n"); # return 0;<%idec> # } # # The result is: # # #include # # int main() { # printf("Hello World\n"); # return 0; # } # # Note that without the explicit formatting commands, the output generated from the # example above would not have any empty lines or whitespace in the beginning of lines. # This may seem like unneccessary extra work for the example above which could also # have been generated by passing the template to the output verbatimly. # However in most cases templates will contain more template specific indentation and # newlines which should be eliminated than formatting that should be visible in the # output. # # Here is a more realistic example for generating C function prototypes: # # <% define 'Prototype', :for => CFunction do %> # <%= getType.name %> <%= name %>(<%nows%> # <% expand 'Signature', :foreach => argument, :separator => ', ' %>); # <% end %> # # <% define 'Signature', :for => CFunctionArgument do %> # <%= getType.name %> <%= name%><%nows%> # <% end %> # # The result could look something like: # # void somefunc(int a, float b, int c); # int otherfunc(short x); # # In this example a separator is used to join the single arguments of the C functions. # Note that the template generating the argument type and name needs to contain # a <%nows%> if the result should consist of a single line. # # Here is one more example for generating C array initializations: # # <% define 'Array', :for => CArray do %> # <%= getType.name %> <%= name %>[<%= size %>] = {<%iinc%> # <% expand 'InitValue', :foreach => initvalue, :separator => ",\n" %><%nl%><%idec%> # }; # <% end %> # # <% define 'InitValue', :for => PrimitiveInitValue do %> # <%= value %><%nows%> # <% end %> # # The result could look something like: # # int myArray[3] = { # 1, # 2, # 3 # }; # # Note that in this example, the separator contains a newline. The current increment # will be applied to each single expansion result since it starts in a new line. # # # =Output Files # # Normally the generated content is to be written into one or more output files. # The RGen template language facilitates this by means of the +file+ keyword. # # When the +file+ keyword is used to define a block, all output generated # from template code within this block will be written to the specified file. # This includes output generated from template expansions. # Thus all output from templates expanded within this block is written to # the same file as long as those templates do not use the +file+ keyword to # define a new file context. # # Here is an example: # # <% file 'dbadapter/'+adapter.name+'.c' do %> # all content within this block will be written to the specified file # <% end %> # # Note that the filename itself can be calculated dynamically by an arbitrary # Ruby expression. # # The absolute position where the output file is created depends on the output # root directory passed to DirectoryTemplateContainer as described below. # # As a second argument, the +file+ command can take the indentation string which is # used to indent output lines (see Formatting). # # =Setting up the Generator # # Setting up the generator consists of 3 steps: # * Instantiate DirectoryTemplateContainer passing one or more metamodel(s) and the output # directory to the constructor. # * Load the templates into the template container # * Expand the root template to start generation # # Here is an example: # # module MyMM # # metaclasses are defined here, e.g. using RGen::MetamodelBuilder # end # # OUTPUT_DIR = File.dirname(__FILE__)+"/output" # TEMPLATES_DIR = File.dirname(__FILE__)+"/templates" # # tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new(MyMM, OUTPUT_DIR) # tc.load(TEMPLATES_DIR) # # testModel should hold an instance of the metamodel class expected by the root template # # the following line starts generation # tc.expand('root::Root', :for => testModel, :indent => 1) # # The metamodel is the Ruby module which contains the metaclasses. # This information is required for the template container in order to resolve the # metamodel classes used within the template file. # If several metamodels shall be used, an array of modules can be passed instead # of a single module. # # The output path is prepended to the relative paths provided to the +file+ # definitions in the template files. # # The template directory should contain template files as described above. # # Finally the generation process is started by calling +expand+ in the same way as it # is used from within templates. # # Also see the unit tests for more examples. # module TemplateLanguage end endrgen-0.7.0/lib/rgen/fragment/0000755000004100000410000000000012352210062015776 5ustar www-datawww-datargen-0.7.0/lib/rgen/fragment/fragmented_model.rb0000644000004100000410000001034512352210062021622 0ustar www-datawww-datarequire 'rgen/instantiator/reference_resolver' module RGen module Fragment # A FragmentedModel represents a model which consists of fragments (ModelFragment). # # The main purpose of this class is to resolve references across fragments and # to keep the references consistent while fragments are added or removed. # This way it also plays an important role in keeping the model fragments consistent # and thus ModelFragment objects should only be accessed via this interface. # Overall unresolved references after the resolution step are also maintained. # # A FragmentedModel can also keep an RGen::Environment object up to date while fragments # are added or removed. The environment must be registered with the constructor. # # Reference resolution is based on arbitrary identifiers. The identifiers must be # provided in the fragments' indices. The FragmentedModel takes care to maintain # the overall index. # class FragmentedModel attr_reader :fragments attr_reader :environment # Creates a fragmented model. Options: # # :env # environment which will be updated as model elements are added and removed # def initialize(options={}) @environment = options[:env] @fragments = [] @index = nil @fragment_change_listeners = [] @fragment_index = {} end # Adds a proc which is called when a fragment is added or removed # The proc receives the fragment and one of :added, :removed # def add_fragment_change_listener(listener) @fragment_change_listeners << listener end def remove_fragment_change_listener(listener) @fragment_change_listeners.delete(listener) end # Add a fragment. # def add_fragment(fragment) invalidate_cache @fragments << fragment fragment.elements.each{|e| @environment << e} if @environment @fragment_change_listeners.each{|l| l.call(fragment, :added)} end # Removes the fragment. The fragment will be unresolved using unresolve_fragment. # def remove_fragment(fragment) raise "fragment not part of model" unless @fragments.include?(fragment) invalidate_cache @fragments.delete(fragment) @fragment_index.delete(fragment) unresolve_fragment(fragment) fragment.elements.each{|e| @environment.delete(e)} if @environment @fragment_change_listeners.each{|l| l.call(fragment, :removed)} end # Resolve references between fragments. # It is assumed that references within fragments have already been resolved. # This method can be called several times. It will update the overall unresolved references. # # Options: # # :fragment_provider: # Only if a +fragment_provider+ is given, the resolve step can be reverted later on # by a call to unresolve_fragment. The fragment provider is a proc which receives a model # element and must return the fragment in which the element is contained. # # :use_target_type: # reference resolver uses the expected target type to narrow the set of possible targets # def resolve(options={}) local_index = index @fragments.each do |f| f.resolve_external(local_index, options) end end # Remove all references between this fragment and all other fragments. # The references will be replaced with unresolved references (MMProxy objects). # def unresolve_fragment(fragment) fragment.unresolve_external @fragments.each do |f| if f != fragment f.unresolve_external_fragment(fragment) end end end # Returns the overall unresolved references. # def unresolved_refs @fragments.collect{|f| f.unresolved_refs}.flatten end # Returns the overall index. # This is a Hash mapping identifiers to model elements accessible via the identifier. # def index fragments.each do |f| if !@fragment_index[f] || (@fragment_index[f].object_id != f.index.object_id) @fragment_index[f] = f.index invalidate_cache end end return @index if @index @index = {} fragments.each do |f| f.index.each do |i| (@index[i[0]] ||= []) << i[1] end end @index end private def invalidate_cache @index = nil end end end end rgen-0.7.0/lib/rgen/fragment/model_fragment.rb0000644000004100000410000002331012352210062021305 0ustar www-datawww-datarequire 'rgen/instantiator/reference_resolver' module RGen module Fragment # A model fragment is a list of root model elements associated with a location (e.g. a file). # It also stores a list of unresolved references as well as a list of unresolved references # which have been resolved. Using the latter, a fragment can undo reference resolution. # # Optionally, an arbitrary data object may be associated with the fragment. The data object # will also be stored in the cache. # # If an element within the fragment changes this must be indicated to the fragment by calling # +mark_changed+. # # Note: the fragment knows how to resolve references (+resolve_local+, +resolve_external+). # However considering a fragment a data structure, this functionality might be removed in the # future. Instead the fragment should be told about each resolution taking place. Use # method +mark_resolved+ for this purpose. # class ModelFragment attr_reader :root_elements attr_accessor :location, :fragment_ref, :data # A FragmentRef serves as a single target object for elements which need to reference the # fragment they are contained in. The FragmentRef references the fragment it is contained in. # The FragmentRef is separate from the fragment itself to allow storing it in a marshal dump # independently of the fragment. # class FragmentRef attr_accessor :fragment end # A ResolvedReference wraps an unresolved reference after it has been resolved. # It also holds the target element to which it has been resolved, i.e. with which the proxy # object has been replaced. # class ResolvedReference attr_reader :uref, :target def initialize(uref, target) @uref, @target = uref, target end end # Create a model fragment # # :data # data object associated with this fragment # # :identifier_provider # identifier provider to be used when resolving references # it must be a proc which receives a model element and must return # that element's identifier or nil if the element has no identifier # def initialize(location, options={}) @location = location @fragment_ref = FragmentRef.new @fragment_ref.fragment = self @data = options[:data] @resolved_refs = nil @changed = false @identifier_provider = options[:identifier_provider] end # Set the root elements, normally done by an instantiator. # # For optimization reasons the instantiator of the fragment may provide data explicitly which # is normally derived by the fragment itself. In this case it is essential that this # data is consistent with the fragment. # def set_root_elements(root_elements, options={}) @root_elements = root_elements @elements = options[:elements] @index = options[:index] @unresolved_refs = options[:unresolved_refs] @resolved_refs = nil # new unresolved refs, reset removed_urefs @removed_urefs = nil @changed = false end # Must be called when any of the elements in this fragment has been changed # def mark_changed @changed = true @elements = nil @index = nil @unresolved_refs = nil # unresolved refs will be recalculated, no need to keep removed_urefs @removed_urefs = nil @resolved_refs = :dirty end # Can be used to reset the change status to unchanged. # def mark_unchanged @changed = false end # Indicates whether the fragment has been changed or not # def changed? @changed end # Returns all elements within this fragment # def elements return @elements if @elements @elements = [] @root_elements.each do |e| @elements << e @elements.concat(e.eAllContents) end @elements end # Returns the index of the element contained in this fragment. # def index build_index unless @index @index end # Returns all unresolved references within this fragment, i.e. references to MMProxy objects # def unresolved_refs @unresolved_refs ||= collect_unresolved_refs if @removed_urefs @unresolved_refs -= @removed_urefs @removed_urefs = nil end @unresolved_refs end # Builds the index of all elements within this fragment having an identifier # the index is an array of 2-element arrays holding the identifier and the element # def build_index raise "cannot build index without an identifier provider" unless @identifier_provider @index = elements.collect { |e| ident = @identifier_provider.call(e, nil) ident && !ident.empty? ? [ident, e] : nil }.compact end # Resolves local references (within this fragment) as far as possible # # Options: # # :use_target_type: # reference resolver uses the expected target type to narrow the set of possible targets # def resolve_local(options={}) resolver = RGen::Instantiator::ReferenceResolver.new index.each do |i| resolver.add_identifier(i[0], i[1]) end @unresolved_refs = resolver.resolve(unresolved_refs, :use_target_type => options[:use_target_type]) end # Resolves references to external fragments using the external_index provided. # The external index must be a Hash mapping identifiers uniquely to model elements. # # Options: # # :fragment_provider: # If a +fragment_provider+ is given, the resolve step can be reverted later on # by a call to unresolve_external or unresolve_external_fragment. The fragment provider # is a proc which receives a model element and must return the fragment in which it is # contained. # # :use_target_type: # reference resolver uses the expected target type to narrow the set of possible targets # # def resolve_external(external_index, options) fragment_provider = options[:fragment_provider] resolver = RGen::Instantiator::ReferenceResolver.new( :identifier_resolver => proc {|ident| external_index[ident] }) if fragment_provider @resolved_refs = {} if @resolved_refs.nil? || @resolved_refs == :dirty on_resolve = proc { |ur, target| target_fragment = fragment_provider.call(target) target_fragment ||= :unknown raise "can not resolve local reference in resolve_external, call resolve_local first" \ if target_fragment == self @resolved_refs[target_fragment] ||= [] @resolved_refs[target_fragment] << ResolvedReference.new(ur, target) } @unresolved_refs = resolver.resolve(unresolved_refs, :on_resolve => on_resolve, :use_target_type => options[:use_target_type]) else @unresolved_refs = resolver.resolve(unresolved_refs, :use_target_type => options[:use_target_type]) end end # Marks a particular unresolved reference +uref+ as resolved to +target+ in +target_fragment+. # def mark_resolved(uref, target_fragment, target) @resolved_refs = {} if @resolved_refs.nil? || @resolved_refs == :dirty target_fragment ||= :unknown if target_fragment != self @resolved_refs[target_fragment] ||= [] @resolved_refs[target_fragment] << ResolvedReference.new(uref, target) end @removed_urefs ||= [] @removed_urefs << uref end # Unresolve outgoing references to all external fragments, i.e. references which used to # be represented by an unresolved reference from within this fragment. # Note, that there may be more references to external fragments due to references which # were represented by unresolved references from within other fragments. # def unresolve_external return if @resolved_refs.nil? raise "can not unresolve, missing fragment information" if @resolved_refs == :dirty || @resolved_refs[:unknown] rrefs = @resolved_refs.values.flatten @resolved_refs = {} unresolve_refs(rrefs) end # Like unresolve_external but only unresolve references to external fragment +fragment+ # def unresolve_external_fragment(fragment) return if @resolved_refs.nil? raise "can not unresolve, missing fragment information" if @resolved_refs == :dirty || @resolved_refs[:unknown] rrefs = @resolved_refs[fragment] @resolved_refs.delete(fragment) unresolve_refs(rrefs) if rrefs end private # Turns resolved references +rrefs+ back into unresolved references # def unresolve_refs(rrefs) # make sure any removed_urefs have been removed, # otherwise they will be removed later even if this method actually re-added them unresolved_refs rrefs.each do |rr| ur = rr.uref refs = ur.element.getGeneric(ur.feature_name) if refs.is_a?(Array) index = refs.index(rr.target) ur.element.removeGeneric(ur.feature_name, rr.target) ur.element.addGeneric(ur.feature_name, ur.proxy, index) else ur.element.setGeneric(ur.feature_name, ur.proxy) end @unresolved_refs << ur end end def collect_unresolved_refs unresolved_refs = [] elements.each do |e| each_reference_target(e) do |r, t| if t.is_a?(RGen::MetamodelBuilder::MMProxy) unresolved_refs << RGen::Instantiator::ReferenceResolver::UnresolvedReference.new(e, r.name, t) end end end unresolved_refs end def each_reference_target(element) non_containment_references(element.class).each do |r| element.getGenericAsArray(r.name).each do |t| yield(r, t) end end end def non_containment_references(clazz) @@non_containment_references_cache ||= {} @@non_containment_references_cache[clazz] ||= clazz.ecore.eAllReferences.select{|r| !r.containment} end end end end rgen-0.7.0/lib/rgen/fragment/dump_file_cache.rb0000644000004100000410000000355512352210062021422 0ustar www-datawww-datamodule RGen module Fragment # Caches model fragments in Ruby dump files. # # Dump files are created per each fragment file. # # The main goal is to support fast loading and joining of fragments. Therefore the cache # stores additional information which makes the joining process faster (adding to # environment, resolving references) # class DumpFileCache # +cache_map+ must be an object responding to +load_data+ and +store_data+ # for loading or storing data associated with a file; # this can be an instance of Util::FileCacheMap def initialize(cache_map) @cache_map = cache_map end # Note that the fragment must not be connected to other fragments by resolved references # unresolve the fragment if necessary def store(fragment) fref = fragment.fragment_ref # temporarily remove the reference to the fragment to avoid dumping the fragment fref.fragment = nil @cache_map.store_data(fragment.location, Marshal.dump({ :root_elements => fragment.root_elements, :elements => fragment.elements, :index => fragment.index, :unresolved_refs => fragment.unresolved_refs, :fragment_ref => fref, :data => fragment.data })) fref.fragment = fragment end def load(fragment) dump = @cache_map.load_data(fragment.location) return :invalid if dump == :invalid header = Marshal.load(dump) fragment.set_root_elements(header[:root_elements], :elements => header[:elements], :index => header[:index], :unresolved_refs => header[:unresolved_refs]) fragment.data = header[:data] if header[:fragment_ref] fragment.fragment_ref = header[:fragment_ref] fragment.fragment_ref.fragment = fragment else raise "no fragment_ref in fragment loaded from cache" end end end end end rgen-0.7.0/lib/rgen/metamodel_builder.rb0000644000004100000410000001712512352210062020203 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 require 'rgen/metamodel_builder/constant_order_helper' require 'rgen/metamodel_builder/builder_runtime' require 'rgen/metamodel_builder/builder_extensions' require 'rgen/metamodel_builder/module_extension' require 'rgen/metamodel_builder/data_types' require 'rgen/metamodel_builder/mm_multiple' require 'rgen/ecore/ecore_interface' module RGen # MetamodelBuilder can be used to create a metamodel, i.e. Ruby classes which # act as metamodel elements. # # To create a new metamodel element, create a Ruby class which inherits from # MetamodelBuilder::MMBase # # class Person < RGen::MetamodelBuilder::MMBase # end # # This way a couple of class methods are made available to the new class. # These methods can be used to: # * add attributes to the class # * add associations with other classes # # Here is an example: # # class Person < RGen::MetamodelBuilder::MMBase # has_attr 'name', String # has_attr 'age', Integer # end # # class House < RGen::MetamodelBuilder::MMBase # has_attr 'address' # String is default # end # # Person.many_to_many 'homes', House, 'inhabitants' # # See BuilderExtensions for details about the available class methods. # # =Attributes # # The example above creates two classes 'Person' and 'House'. Person has the attributes # 'name' and 'age', House has the attribute 'address'. The attributes can be # accessed on instances of the classes in the following way: # # p = Person.new # p.name = "MyName" # p.age = 22 # p.name # => "MyName" # p.age # => 22 # # Note that the class Person takes care of the type of its attributes. As # declared above, a 'name' can only be a String, an 'age' must be an Integer. # So the following would return an exception: # # p.name = :myName # => exception: can not put a Symbol where a String is expected # # If the type of an attribute should be left undefined, use Object as type. # # =Associations # # As well as attributes show up as instance methods, associations bring their own # accessor methods. For the Person-to-House association this would be: # # h1 = House.new # h1.address = "Street1" # h2 = House.new # h2.address = "Street2" # p.addHomes(h1) # p.addHomes(h2) # p.removeHomes(h1) # p.homes # => [ h2 ] # # The Person-to-House association is _bidirectional_. This means that with the # addition of a House to a Person, the Person is also added to the House. Thus: # # h1.inhabitants # => [] # h2.inhabitants # => [ p ] # # Note that the association is defined between two specific classes, instances of # different classes can not be added. Thus, the following would result in an # exception: # # p.addHomes(:justASymbol) # => exception: can not put a Symbol where a House is expected # # =ECore Metamodel description # # The class methods described above are used to create a Ruby representation of the metamodel # we have in mind in a very simple and easy way. We don't have to care about all the details # of a metamodel at this point (e.g. multiplicities, changeability, etc). # # At the same time however, an instance of the ECore metametamodel (i.e. a ECore based # description of our metamodel) is provided for all the Ruby classes and modules we create. # Since we did not provide the nitty-gritty details of the metamodel, defaults are used to # fully complete the ECore metamodel description. # # In order to access the ECore metamodel description, just call the +ecore+ method on a # Ruby class or module object belonging to your metamodel. # # Here is the example continued from above: # # Person.ecore.eAttributes.name # => ["name", "age"] # h2pRef = House.ecore.eReferences.first # h2pRef.eType # => Person # h2pRef.eOpposite.eType # => House # h2pRef.lowerBound # => 0 # h2pRef.upperBound # => -1 # h2pRef.many # => true # h2pRef.containment # => false # # Note that the use of array_extensions.rb is assumed here to make model navigation convenient. # # The following metamodel builder methods are supported, see individual method description # for details: # # Attributes: # * BuilderExtensions#has_attr # # Unidirectional references: # * BuilderExtensions#has_one # * BuilderExtensions#has_many # * BuilderExtensions#contains_one_uni # * BuilderExtensions#contains_many_uni # # Bidirectional references: # * BuilderExtensions#one_to_one # * BuilderExtensions#one_to_many # * BuilderExtensions#many_to_one # * BuilderExtensions#many_to_many # * BuilderExtensions#contains_one # * BuilderExtensions#contains_many # # Every builder command can optionally take a specification of further ECore properties. # Additional properties for Attributes and References are (with defaults in brackets): # * :ordered (true), # * :unique (true), # * :changeable (true), # * :volatile (false), # * :transient (false), # * :unsettable (false), # * :derived (false), # * :lowerBound (0), # * :resolveProxies (true) references only, # # Using these additional properties, the above example can be refined as follows: # # class Person < RGen::MetamodelBuilder::MMBase # has_attr 'name', String, :lowerBound => 1 # has_attr 'yearOfBirth', Integer, # has_attr 'age', Integer, :derived => true # def age_derived # Time.now.year - yearOfBirth # end # end # # Person.many_to_many 'homes', House, 'inhabitants', :upperBound => 5 # # Person.ecore.eReferences.find{|r| r.name == 'homes'}.upperBound # => 5 # # This way we state that there must be a name for each person, we introduce a new attribute # 'yearOfBirth' and make 'age' a derived attribute. We also say that a person can # have at most 5 houses in our metamodel. # # ==Derived attributes and references # # If the attribute 'derived' of an attribute or reference is set to true, a method +attributeName_derived+ # has to be provided. This method is called whenever the original attribute is accessed. The # original attribute can not be written if it is derived. # # module MetamodelBuilder # Use this class as a start for new metamodel elements (i.e. Ruby classes) # by inheriting for it. # # See MetamodelBuilder for an example. class MMBase include BuilderRuntime include DataTypes extend BuilderExtensions extend ModuleExtension extend RGen::ECore::ECoreInterface def initialize(arg=nil) raise StandardError.new("Class #{self.class} is abstract") if self.class._abstract_class arg.each_pair { |k,v| setGeneric(k, v) } if arg.is_a?(Hash) end # Object#inspect causes problems on most models def inspect self.class.name end def self.method_added(m) raise "Do not add methods to model classes directly, add them to the ClassModule instead" end end # Instances of MMGeneric can be used as values of any attribute are reference class MMGeneric # empty implementation so we don't have to check if a value is a MMGeneriv before setting the container def _set_container(container, containing_feature_name) end end # MMProxy objects can be used instead of real target elements in case references should be resolved later on class MMProxy < MMGeneric # The +targetIdentifer+ is an object identifying the element the proxy represents attr_accessor :targetIdentifier # +data+ is optional additional information to be associated with the proxy attr_accessor :data def initialize(ident=nil, data=nil) @targetIdentifier = ident @data = data end end end end rgen-0.7.0/lib/rgen/model_builder.rb0000644000004100000410000000174612352210062017336 0ustar www-datawww-datarequire 'rgen/model_builder/builder_context' require 'rgen/util/method_delegation' #require 'ruby-prof' module RGen module ModelBuilder def self.build(package, env=nil, builderMethodsModule=nil, &block) resolver = ReferenceResolver.new bc = BuilderContext.new(package, builderMethodsModule, resolver, env) contextModule = eval("Module.nesting", block.binding).first Util::MethodDelegation.registerDelegate(bc, contextModule, "const_missing") BuilderContext.currentBuilderContext = bc begin #RubyProf.start bc.instance_eval(&block) #prof = RubyProf.stop #File.open("profile_flat.txt","w+") do |f| # RubyProf::FlatPrinter.new(prof).print(f, 0) # end ensure BuilderContext.currentBuilderContext = nil end Util::MethodDelegation.unregisterDelegate(bc, contextModule, "const_missing") #puts "Resolving..." resolver.resolve(bc.toplevelElements) bc.toplevelElements end end end rgen-0.7.0/lib/rgen/template_language/0000755000004100000410000000000012352210062017651 5ustar www-datawww-datargen-0.7.0/lib/rgen/template_language/template_container.rb0000644000004100000410000001654512352210062024066 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 require 'erb' require 'fileutils' require 'rgen/template_language/output_handler' require 'rgen/template_language/template_helper' module RGen module TemplateLanguage class TemplateContainer include TemplateHelper def initialize(metamodels, output_path, parent, filename) @templates = {} @parent = parent @filename = filename @indent = 0 @output_path = output_path @metamodels = metamodels @metamodels = [ @metamodels ] unless @metamodels.is_a?(Array) end def load File.open(@filename,"rb") do |f| begin @@metamodels = @metamodels fileContent = f.read _detectNewLinePattern(fileContent) ERB.new(fileContent,nil,nil,'@output').result(binding) rescue Exception => e processAndRaise(e) end end end def expand(template, *all_args) args, params = _splitArgsAndOptions(all_args) if params.has_key?(:foreach) raise StandardError.new("expand :foreach argument is not enumerable") \ unless params[:foreach].is_a?(Enumerable) _expand_foreach(template, args, params) else _expand(template, args, params) end end def evaluate(template, *all_args) args, params = _splitArgsAndOptions(all_args) raise StandardError.new(":foreach can not be used with evaluate") if params[:foreach] _expand(template, args, params.merge({:_evalOnly => true})) end def this @context end def method_missing(name, *args) @context.send(name, *args) end def self.const_missing(name) super unless @@metamodels @@metamodels.each do |mm| return mm.const_get(name) rescue NameError end super end private def nonl @output.ignoreNextNL end def nows @output.ignoreNextWS end def nl _direct_concat(@newLinePattern) end def ws _direct_concat(" ") end def iinc @indent += 1 @output.indent = @indent end def idec @indent -= 1 if @indent > 0 @output.indent = @indent end TemplateDesc = Struct.new(:block, :local) def define(template, params={}, &block) _define(template, params, &block) end def define_local(template, params={}, &block) _define(template, params.merge({:local => true}), &block) end def file(name, indentString=nil) old_output, @output = @output, OutputHandler.new(@indent, indentString || @parent.indentString) begin yield rescue Exception => e processAndRaise(e) end path = "" path += @output_path+"/" if @output_path dirname = File.dirname(path+name) FileUtils.makedirs(dirname) unless File.exist?(dirname) File.open(path+name,"wb") { |f| f.write(@output) } @output = old_output end # private private def _define(template, params={}, &block) @templates[template] ||= {} cls = params[:for] || Object @templates[template][cls] = TemplateDesc.new(block, params[:local]) end def _expand_foreach(template, args, params) sep = params[:separator] params[:foreach].each_with_index {|e,i| _direct_concat(sep.to_s) if sep && i > 0 output = _expand(template, args, params.merge({:for => e})) } end LOCAL_TEMPLATE_REGEX = /^:*(\w+)$/ def _expand(template, args, params) raise StandardError.new("expand :for argument evaluates to nil") if params.has_key?(:for) && params[:for].nil? context = params[:for] old_indent = @indent @indent = params[:indent] || @indent noIndentNextLine = params[:_noIndentNextLine] || (@output.is_a?(OutputHandler) && @output.noIndentNextLine) || (@output.to_s.size > 0 && @output.to_s[-1] != "\n"[0]) caller = params[:_caller] || self old_context, @context = @context, context if context local_output = nil if template =~ LOCAL_TEMPLATE_REGEX tplname = $1 raise StandardError.new("Template not found: #{$1}") unless @templates[tplname] old_output, @output = @output, OutputHandler.new(@indent, @parent.indentString) @output.noIndentNextLine = noIndentNextLine _call_template(tplname, @context, args, caller == self) old_output.noIndentNextLine = false if old_output.is_a?(OutputHandler) && !old_output.noIndentNextLine local_output, @output = @output, old_output else local_output = @parent.expand(template, *(args.dup << {:for => @context, :indent => @indent, :_noIndentNextLine => noIndentNextLine, :_evalOnly => true, :_caller => caller})) end _direct_concat(local_output) unless params[:_evalOnly] @context = old_context if old_context @indent = old_indent local_output.to_s end def processAndRaise(e, tpl=nil) bt = e.backtrace.dup e.backtrace.each_with_index do |t,i| if t =~ /\(erb\):(\d+):/ bt[i] = "#{@filename}:#{$1}" bt[i] += ":in '#{tpl}'" if tpl break end end raise e, e.to_s, bt end def _call_template(tpl, context, args, localCall) found = false @templates[tpl].each_pair do |key, value| if context.is_a?(key) templateDesc = @templates[tpl][key] proc = templateDesc.block arity = proc.arity arity = 0 if arity == -1 # if no args are given raise StandardError.new("Wrong number of arguments calling template #{tpl}: #{args.size} for #{arity} "+ "(Beware: Hashes as last arguments are taken as options and are ignored)") \ if arity != args.size raise StandardError.new("Template can only be called locally: #{tpl}") \ if templateDesc.local && !localCall begin @@metamodels = @metamodels proc.call(*args) rescue Exception => e processAndRaise(e, tpl) end found = true end end raise StandardError.new("Template class not matching: #{tpl} for #{context.class.name}") unless found end def _direct_concat(s) if @output.is_a? OutputHandler @output.direct_concat(s) else @output << s end end def _detectNewLinePattern(text) tests = 0 rnOccurances = 0 text.scan(/(\r?)\n/) do |groups| tests += 1 rnOccurances += 1 if groups[0] == "\r" break if tests >= 10 end if rnOccurances > (tests / 2) @newLinePattern = "\r\n" else @newLinePattern = "\n" end end end end end rgen-0.7.0/lib/rgen/template_language/output_handler.rb0000644000004100000410000000443412352210062023240 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 module RGen module TemplateLanguage class OutputHandler attr_writer :indent attr_accessor :noIndentNextLine def initialize(indent=0, indentString=" ", mode=:explicit) self.mode = mode @indent = indent @indentString = indentString @state = :wait_for_nonws @output = "" end # ERB will call this method for every string s which is part of the # template file in between %> and <%. If s contains a newline, it will # call this method for every part of s which is terminated by a \n # def concat(s) return @output.concat(s) if s.is_a? OutputHandler #puts [object_id, noIndentNextLine, @state, @output.to_s, s].inspect s = s.to_str.gsub(/^[\t ]*\r?\n/,'') if @ignoreNextNL s = s.to_str.gsub(/^\s+/,'') if @ignoreNextWS @ignoreNextNL = @ignoreNextWS = false if s =~ /\S/ if @mode == :direct @output.concat(s) elsif @mode == :explicit while s.size > 0 if @state == :wait_for_nl if s =~ /\A([^\r\n]*\r?\n)(.*)/m rest = $2 @output.concat($1.gsub(/[\t ]+(?=\r|\n)/,'')) s = rest || "" @state = :wait_for_nonws else @output.concat(s) s = "" end elsif @state == :wait_for_nonws if s =~ /\A\s*(\S+.*)/m s = $1 || "" if !@noIndentNextLine && !(@output.to_s.size > 0 && @output.to_s[-1] != "\n"[0]) @output.concat(@indentString * @indent) else @noIndentNextLine = false end @state = :wait_for_nl else s = "" end end end end end alias << concat def to_str @output end alias to_s to_str def direct_concat(s) @output.concat(s) end def ignoreNextNL @ignoreNextNL = true end def ignoreNextWS @ignoreNextWS = true end def mode=(m) raise StandardError.new("Unknown mode: #{m}") unless [:direct, :explicit].include?(m) @mode = m end end end endrgen-0.7.0/lib/rgen/template_language/template_helper.rb0000644000004100000410000000052312352210062023350 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 module RGen module TemplateLanguage module TemplateHelper private def _splitArgsAndOptions(all) if all[-1] and all[-1].is_a? Hash args = all[0..-2] || [] options = all[-1] else args = all options = {} end return args, options end end end endrgen-0.7.0/lib/rgen/template_language/directory_template_container.rb0000644000004100000410000000416112352210062026141 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 require 'rgen/template_language/template_container' require 'rgen/template_language/template_helper' module RGen module TemplateLanguage class DirectoryTemplateContainer include TemplateHelper def initialize(metamodel=nil, output_path=nil, parent=nil) @containers = {} @directoryContainers = {} @parent = parent @metamodel = metamodel @output_path = output_path end def load(dir) Dir.foreach(dir) { |f| qf = dir+"/"+f if !File.directory?(qf) && f =~ /^(.*)\.tpl$/ (@containers[$1] = TemplateContainer.new(@metamodel, @output_path, self,qf)).load elsif File.directory?(qf) && f != "." && f != ".." (@directoryContainers[f] = DirectoryTemplateContainer.new(@metamodel, @output_path, self)).load(qf) end } end def expand(template, *all_args) if template =~ /^\// if @parent # pass to parent @parent.expand(template, *all_args) else # this is root _expand(template, *all_args) end elsif template =~ /^\.\.\/(.*)/ if @parent # pass to parent @parent.expand($1, *all_args) else raise "No parent directory for root" end else _expand(template, *all_args) end end # Set indentation string. # Every generated line will be prependend with n times this string at an indentation level of n. # Defaults to " " (3 spaces) def indentString=(str) @indentString = str end def indentString @indentString || (@parent && @parent.indentString) || " " end private def _expand(template, *all_args) if template =~ /^\/?(\w+)::(\w.*)/ raise "Template not found: #{$1}" unless @containers[$1] @containers[$1].expand($2, *all_args) elsif template =~ /^\/?(\w+)\/(\w.*)/ raise "Template not found: #{$1}" unless @directoryContainers[$1] @directoryContainers[$1].expand($2, *all_args) else raise "Invalid template name: #{template}" end end end end endrgen-0.7.0/lib/rgen/ecore/0000755000004100000410000000000012352210062015270 5ustar www-datawww-datargen-0.7.0/lib/rgen/ecore/ecore_interface.rb0000644000004100000410000000240312352210062020731 0ustar www-datawww-datamodule RGen module ECore # Mixin to provide access to the ECore model describing a Ruby class or module # built using MetamodelBuilder. # The module should be used to +extend+ a class or module, i.e. to make its # methods class methods. # module ECoreInterface # This method will lazily build to ECore model element belonging to the calling # class or module using RubyToECore. # Alternatively, the ECore model element can be provided up front. This is used # when the Ruby metamodel classes and modules are created from ECore. # def ecore if defined?(@ecore) @ecore else unless defined?(@@transformer) require 'rgen/ecore/ruby_to_ecore' @@transformer = RubyToECore.new end @@transformer.trans(self) end end # This method can be used to clear the ecore cache after the metamodel classes # or modules have been changed; the ecore model will be recreated on next access # to the +ecore+ method # Beware, the ecore cache is global, i.e. for all metamodels. # def self.clear_ecore_cache require 'rgen/ecore/ruby_to_ecore' @@transformer = RubyToECore.new end def _set_ecore_internal(ecore) # :nodoc: @ecore = ecore end end end end rgen-0.7.0/lib/rgen/ecore/ecore.rb0000644000004100000410000002061012352210062016711 0ustar www-datawww-datarequire 'rgen/metamodel_builder' module RGen extend RGen::MetamodelBuilder::ModuleExtension # This is the ECore metamodel described using the RGen::MetamodelBuilder language. # # Known differences to the Java/EMF implementation are: # * Attributes can not be "many" # module ECore extend RGen::MetamodelBuilder::ModuleExtension class EObject < RGen::MetamodelBuilder::MMBase end class EModelElement < RGen::MetamodelBuilder::MMBase end class EAnnotation < RGen::MetamodelBuilder::MMMultiple(EModelElement, EObject) has_attr 'source', String end class ENamedElement < EModelElement has_attr 'name', String end class ETypedElement < ENamedElement has_attr 'lowerBound', Integer, :defaultValueLiteral => "0" has_attr 'ordered', Boolean, :defaultValueLiteral => "true" has_attr 'unique', Boolean, :defaultValueLiteral => "true" has_attr 'upperBound', Integer, :defaultValueLiteral => "1" has_attr 'many', Boolean, :derived=>true has_attr 'required', Boolean, :derived=>true module ClassModule def many_derived upperBound > 1 || upperBound == -1 end def required_derived lowerBound > 0 end end end class EStructuralFeature < ETypedElement has_attr 'changeable', Boolean, :defaultValueLiteral => "true" has_attr 'defaultValue', Object, :derived=>true has_attr 'defaultValueLiteral', String has_attr 'derived', Boolean, :defaultValueLiteral => "false" has_attr 'transient', Boolean, :defaultValueLiteral => "false" has_attr 'unsettable', Boolean, :defaultValueLiteral => "false" has_attr 'volatile', Boolean, :defaultValueLiteral => "false" module ClassModule def defaultValue_derived return nil if defaultValueLiteral.nil? case eType when EInt, ELong defaultValueLiteral.to_i when EFloat defaultValueLiteral.to_f when EEnum defaultValueLiteral.to_sym when EBoolean defaultValueLiteral == "true" when EString defaultValueLiteral else raise "Unhandled type" end end end end class EAttribute < EStructuralFeature has_attr 'iD', Boolean, :defaultValueLiteral => "false" end class EClassifier < ENamedElement has_attr 'defaultValue', Object, :derived=>true has_attr 'instanceClass', Object, :derived=>true has_attr 'instanceClassName', String module ClassModule def instanceClass_derived map = {"java.lang.string" => "String", "boolean" => "RGen::MetamodelBuilder::DataTypes::Boolean", "int" => "Integer", "long" => "RGen::MetamodelBuilder::DataTypes::Long"} icn = instanceClassName icn = "NilClass" if icn.nil? icn = map[icn.downcase] if map[icn.downcase] eval(icn) end end end class EDataType < EClassifier has_attr 'serializable', Boolean end class EGenericType < EDataType has_one 'eClassifier', EDataType end class ETypeArgument < EModelElement has_one 'eClassifier', EDataType end class EEnum < EDataType end class EEnumLiteral < ENamedElement # instance may point to a "singleton object" (e.g. a Symbol) representing the literal # has_attr 'instance', Object, :eType=>:EEnumerator, :transient=>true has_attr 'literal', String has_attr 'value', Integer end # TODO: check if required class EFactory < EModelElement end class EOperation < ETypedElement end class EPackage < ENamedElement has_attr 'nsPrefix', String has_attr 'nsURI', String end class EParameter < ETypedElement end class EReference < EStructuralFeature has_attr 'container', Boolean, :derived=>true has_attr 'containment', Boolean, :defaultValueLiteral => "false" has_attr 'resolveProxies', Boolean, :defaultValueLiteral => "true" end class EStringToStringMapEntry < RGen::MetamodelBuilder::MMBase has_attr 'key', String has_attr 'value', String end class EClass < EClassifier has_attr 'abstract', Boolean has_attr 'interface', Boolean has_one 'eIDAttribute', ECore::EAttribute, :derived=>true, :resolveProxies=>false has_many 'eAllAttributes', ECore::EAttribute, :derived=>true has_many 'eAllContainments', ECore::EReference, :derived=>true has_many 'eAllOperations', ECore::EOperation, :derived=>true has_many 'eAllReferences', ECore::EReference, :derived=>true has_many 'eAllStructuralFeatures', ECore::EStructuralFeature, :derived=>true has_many 'eAllSuperTypes', ECore::EClass, :derived=>true has_many 'eAttributes', ECore::EAttribute, :derived=>true has_many 'eReferences', ECore::EReference, :derived=>true module ClassModule def eAllAttributes_derived eAttributes + eSuperTypes.eAllAttributes end def eAllContainments_derived eReferences.select{|r| r.containment} + eSuperTypes.eAllContainments end def eAllReferences_derived eReferences + eSuperTypes.eAllReferences end def eAllStructuralFeatures_derived eStructuralFeatures + eSuperTypes.eAllStructuralFeatures end def eAllSuperTypes_derived eSuperTypes + eSuperTypes.eAllSuperTypes end def eAttributes_derived eStructuralFeatures.select{|f| f.is_a?(EAttribute)} end def eReferences_derived eStructuralFeatures.select{|f| f.is_a?(EReference)} end end end # predefined datatypes EString = EDataType.new(:name => "EString", :instanceClassName => "String") EInt = EDataType.new(:name => "EInt", :instanceClassName => "Integer") ELong = EDataType.new(:name => "ELong", :instanceClassName => "Long") EBoolean = EDataType.new(:name => "EBoolean", :instanceClassName => "Boolean") EFloat = EDataType.new(:name => "EFloat", :instanceClassName => "Float") ERubyObject = EDataType.new(:name => "ERubyObject", :instanceClassName => "Object") EJavaObject = EDataType.new(:name => "EJavaObject") ERubyClass = EDataType.new(:name => "ERubyClass", :instanceClassName => "Class") EJavaClass = EDataType.new(:name => "EJavaClass") end ECore::EModelElement.contains_many 'eAnnotations', ECore::EAnnotation, 'eModelElement', :resolveProxies=>false ECore::EAnnotation.contains_many_uni 'details', ECore::EStringToStringMapEntry, :resolveProxies=>false ECore::EAnnotation.contains_many_uni 'contents', ECore::EObject, :resolveProxies=>false ECore::EAnnotation.has_many 'references', ECore::EObject ECore::EPackage.contains_many 'eClassifiers', ECore::EClassifier, 'ePackage' ECore::EPackage.contains_many 'eSubpackages', ECore::EPackage, 'eSuperPackage' ECore::ETypedElement.has_one 'eType', ECore::EClassifier ECore::EClass.contains_many 'eOperations', ECore::EOperation, 'eContainingClass', :resolveProxies=>false ECore::EClass.contains_many 'eStructuralFeatures', ECore::EStructuralFeature, 'eContainingClass', :resolveProxies=>false ECore::EClass.has_many 'eSuperTypes', ECore::EClass ECore::EEnum.contains_many 'eLiterals', ECore::EEnumLiteral, 'eEnum', :resolveProxies=>false ECore::EFactory.one_to_one 'ePackage', ECore::EPackage, 'eFactoryInstance', :lowerBound=>1, :transient=>true, :resolveProxies=>false ECore::EOperation.contains_many 'eParameters', ECore::EParameter, 'eOperation', :resolveProxies=>false ECore::EOperation.has_many 'eExceptions', ECore::EClassifier ECore::EReference.has_one 'eOpposite', ECore::EReference ECore::EAttribute.has_one 'eAttributeType', ECore::EDataType, :lowerBound=>1, :derived=>true ECore::EReference.has_one 'eReferenceType', ECore::EClass, :lowerBound=>1, :derived=>true ECore::EParameter.contains_one 'eGenericType', ECore::EGenericType, 'eParameter' ECore::EGenericType.contains_many 'eTypeArguments', ECore::ETypeArgument, 'eGenericType' end rgen-0.7.0/lib/rgen/ecore/ecore_ext.rb0000644000004100000410000000266712352210062017605 0ustar www-datawww-datarequire 'rgen/array_extensions' require 'rgen/ecore/ecore' module RGen module ECore # make super type reference bidirectional EClass.many_to_many 'eSuperTypes', ECore::EClass, 'eSubTypes' module EModelElement::ClassModule def annotationValue(source, tag) detail = eAnnotations.select{ |a| a.source == source }.details.find{ |d| d.key == tag } detail && detail.value end end module EPackage::ClassModule def qualifiedName if eSuperPackage eSuperPackage.qualifiedName+"::"+name else name end end def eAllClassifiers eClassifiers + eSubpackages.eAllClassifiers end def eAllSubpackages eSubpackages + eSubpackages.eAllSubpackages end def eClasses eClassifiers.select{|c| c.is_a?(ECore::EClass)} end def eAllClasses eClasses + eSubpackages.eAllClasses end def eDataTypes eClassifiers.select{|c| c.is_a?(ECore::EDataType)} end def eAllDataTypes eDataTypes + eSubpackages.eAllDataTypes end end module EClass::ClassModule def qualifiedName if ePackage ePackage.qualifiedName+"::"+name else name end end def eAllSubTypes eSubTypes + eSubTypes.eAllSubTypes end end end end rgen-0.7.0/lib/rgen/ecore/ecore_to_ruby.rb0000644000004100000410000001006012352210062020452 0ustar www-datawww-datarequire 'rgen/ecore/ecore' module RGen module ECore class ECoreToRuby def initialize @modules = {} @classifiers = {} @features_added = {} @in_create_module = false end def create_module(epackage) return @modules[epackage] if @modules[epackage] top = (@in_create_module == false) @in_create_module = true m = Module.new do extend RGen::MetamodelBuilder::ModuleExtension end @modules[epackage] = m epackage.eSubpackages.each{|p| create_module(p)} m._set_ecore_internal(epackage) create_module(epackage.eSuperPackage).const_set(epackage.name, m) if epackage.eSuperPackage # create classes only after all modules have been created # otherwise classes may be created multiple times if top epackage.eAllClassifiers.each do |c| if c.is_a?(RGen::ECore::EClass) create_class(c) elsif c.is_a?(RGen::ECore::EEnum) create_enum(c) end end @in_create_module = false end m end def create_class(eclass) return @classifiers[eclass] if @classifiers[eclass] c = Class.new(super_class(eclass)) do abstract if eclass.abstract class << self attr_accessor :_ecore_to_ruby end end class << eclass attr_accessor :instanceClass def instanceClassName instanceClass.to_s end end eclass.instanceClass = c c::ClassModule.module_eval do alias _method_missing method_missing def method_missing(m, *args) if self.class._ecore_to_ruby.add_features(self.class.ecore) send(m, *args) else _method_missing(m, *args) end end alias _respond_to respond_to? def respond_to?(m, include_all=false) self.class._ecore_to_ruby.add_features(self.class.ecore) _respond_to(m) end end @classifiers[eclass] = c c._set_ecore_internal(eclass) c._ecore_to_ruby = self create_module(eclass.ePackage).const_set(eclass.name, c) c end def create_enum(eenum) return @classifiers[eenum] if @classifiers[eenum] e = RGen::MetamodelBuilder::DataTypes::Enum.new(eenum.eLiterals.collect{|l| l.name.to_sym}) @classifiers[eenum] = e create_module(eenum.ePackage).const_set(eenum.name, e) e end class FeatureWrapper def initialize(efeature, classifiers) @efeature = efeature @classifiers = classifiers end def value(prop) return false if prop == :containment && @efeature.is_a?(RGen::ECore::EAttribute) @efeature.send(prop) end def many? @efeature.many end def reference? @efeature.is_a?(RGen::ECore::EReference) end def opposite @efeature.eOpposite end def impl_type etype = @efeature.eType if etype.is_a?(RGen::ECore::EClass) || etype.is_a?(RGen::ECore::EEnum) @classifiers[etype] else ic = etype.instanceClass if ic ic else raise "unknown type: #{etype.name}" end end end end def add_features(eclass) return false if @features_added[eclass] c = @classifiers[eclass] eclass.eStructuralFeatures.each do |f| w1 = FeatureWrapper.new(f, @classifiers) w2 = FeatureWrapper.new(f.eOpposite, @classifiers) if f.is_a?(RGen::ECore::EReference) && f.eOpposite c.module_eval do if w1.many? _build_many_methods(w1, w2) else _build_one_methods(w1, w2) end end end @features_added[eclass] = true eclass.eSuperTypes.each do |t| add_features(t) end true end def super_class(eclass) super_types = eclass.eSuperTypes case super_types.size when 0 RGen::MetamodelBuilder::MMBase when 1 create_class(super_types.first) else RGen::MetamodelBuilder::MMMultiple(*super_types.collect{|t| create_class(t)}) end end end end end rgen-0.7.0/lib/rgen/ecore/ecore_builder_methods.rb0000644000004100000410000000545212352210062022151 0ustar www-datawww-datamodule RGen module ECore module ECoreBuilderMethods def eAttr(name, type, argHash={}, &block) eAttribute(name, {:eType => type}.merge(argHash), &block) end def eRef(name, type, argHash={}, &block) eReference(name, {:eType => type}.merge(argHash), &block) end # create bidirectional reference at once def eBiRef(name, type, oppositeName, argHash={}) raise BuilderError.new("eOpposite attribute not allowed for bidirectional references") \ if argHash[:eOpposite] || argHash[:opposite_eOpposite] eReference(name, {:eType => type}.merge(argHash.reject{|k,v| k.to_s =~ /^opposite_/})) do eReference oppositeName, {:eContainingClass => type, :eType => _context(2), :as => :eOpposite, :eOpposite => _context(1)}. merge(Hash[*(argHash.select{|k,v| k.to_s =~ /^opposite_/}. collect{|p| [p[0].to_s.sub(/^opposite_/,"").to_sym, p[1]]}.flatten)]) end end # reference shortcuts alias references_1 eRef alias references_one eRef def references_N(name, type, argHash={}) eRef(name, type, {:upperBound => -1}.merge(argHash)) end alias references_many references_N def references_1to1(name, type, oppositeName, argHash={}) eBiRef(name, type, oppositeName, {:upperBound => 1, :opposite_upperBound => 1}.merge(argHash)) end alias references_one_to_one references_1to1 def references_1toN(name, type, oppositeName, argHash={}) eBiRef(name, type, oppositeName, {:upperBound => -1, :opposite_upperBound => 1}.merge(argHash)) end alias references_one_to_many references_1toN def references_Nto1(name, type, oppositeName, argHash={}) eBiRef(name, type, oppositeName, {:upperBound => 1, :opposite_upperBound => -1}.merge(argHash)) end alias references_many_to_one references_Nto1 def references_MtoN(name, type, oppositeName, argHash={}) eBiRef(name, type, oppositeName, {:upperBound => -1, :opposite_upperBound => -1}.merge(argHash)) end alias references_many_to_many references_MtoN # containment reference shortcuts def contains_1(name, type, argHash={}) references_1(name, type, {:containment => true}.merge(argHash)) end alias contains_one contains_1 def contains_N(name, type, argHash={}) references_N(name, type, {:containment => true}.merge(argHash)) end alias contains_many contains_N def contains_1to1(name, type, oppositeName, argHash={}) references_1to1(name, type, oppositeName, {:containment => true}.merge(argHash)) end alias contains_one_to_one contains_1to1 def contains_1toN(name, type, oppositeName, argHash={}) references_1toN(name, type, oppositeName, {:containment => true}.merge(argHash)) end alias contains_one_to_many contains_1toN end end endrgen-0.7.0/lib/rgen/ecore/ruby_to_ecore.rb0000644000004100000410000000613212352210062020457 0ustar www-datawww-datarequire 'rgen/transformer' require 'rgen/ecore/ecore' module RGen module ECore # This transformer creates an ECore model from Ruby classes built # by RGen::MetamodelBuilder. # class RubyToECore < Transformer transform Class, :to => EClass, :if => :convert? do { :name => name.gsub(/.*::(\w+)$/,'\1'), :abstract => _abstract_class, :interface => false, :eStructuralFeatures => trans(_metamodel_description), :ePackage => trans(name =~ /(.*)::\w+$/ ? eval($1) : nil), :eSuperTypes => trans(superclasses), :instanceClassName => name, :eAnnotations => trans(_annotations) } end method :superclasses do if superclass.respond_to?(:multiple_superclasses) && superclass.multiple_superclasses superclass.multiple_superclasses else [ superclass ] end end transform Module, :to => EPackage, :if => :convert? do @enumParentModule ||= {} _constants = _constantOrder + (constants - _constantOrder) _constants.select {|c| const_get(c).is_a?(MetamodelBuilder::DataTypes::Enum)}. each {|c| @enumParentModule[const_get(c)] = @current_object} { :name => name.gsub(/.*::(\w+)$/,'\1'), :eClassifiers => trans(_constants.collect{|c| const_get(c)}.select{|c| c.is_a?(Class) || (c.is_a?(MetamodelBuilder::DataTypes::Enum) && c != MetamodelBuilder::DataTypes::Boolean) }), :eSuperPackage => trans(name =~ /(.*)::\w+$/ ? eval($1) : nil), :eSubpackages => trans(_constants.collect{|c| const_get(c)}.select{|c| c.is_a?(Module) && !c.is_a?(Class)}), :eAnnotations => trans(_annotations) } end method :convert? do @current_object.respond_to?(:ecore) && @current_object != RGen::MetamodelBuilder::MMBase end transform MetamodelBuilder::Intermediate::Attribute, :to => EAttribute do Hash[*MetamodelBuilder::Intermediate::Attribute.properties.collect{|p| [p, value(p)]}.flatten].merge({ :eType => (etype == :EEnumerable ? trans(impl_type) : RGen::ECore.const_get(etype)), :eAnnotations => trans(annotations) }) end transform MetamodelBuilder::Intermediate::Reference, :to => EReference do Hash[*MetamodelBuilder::Intermediate::Reference.properties.collect{|p| [p, value(p)]}.flatten].merge({ :eType => trans(impl_type), :eOpposite => trans(opposite), :eAnnotations => trans(annotations) }) end transform MetamodelBuilder::Intermediate::Annotation, :to => EAnnotation do { :source => source, :details => details.keys.collect do |k| e = RGen::ECore::EStringToStringMapEntry.new e.key = k e.value = details[k] e end } end transform MetamodelBuilder::DataTypes::Enum, :to => EEnum do { :name => name, :instanceClassName => @enumParentModule && @enumParentModule[@current_object] && @enumParentModule[@current_object].name+"::"+name, :eLiterals => literals.collect do |l| lit = RGen::ECore::EEnumLiteral.new lit.name = l.to_s lit end } end end end end rgen-0.7.0/lib/rgen/metamodel_builder/0000755000004100000410000000000012352210062017650 5ustar www-datawww-datargen-0.7.0/lib/rgen/metamodel_builder/builder_runtime.rb0000644000004100000410000001100112352210062023357 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 require 'rgen/util/name_helper' module RGen module MetamodelBuilder # This module is mixed into MetamodelBuilder::MMBase. # The methods provided by this module are used by the methods generated # by the class methods of MetamodelBuilder::BuilderExtensions module BuilderRuntime include Util::NameHelper def is_a?(c) return super unless c.const_defined?(:ClassModule) kind_of?(c::ClassModule) end def addGeneric(role, value, index=-1) send("add#{firstToUpper(role.to_s)}",value, index) end def removeGeneric(role, value) send("remove#{firstToUpper(role.to_s)}",value) end def setGeneric(role, value) send("set#{firstToUpper(role.to_s)}",value) end def hasManyMethods(role) respond_to?("add#{firstToUpper(role.to_s)}") end def setOrAddGeneric(role, value) if hasManyMethods(role) addGeneric(role, value) else setGeneric(role, value) end end def setNilOrRemoveGeneric(role, value) if hasManyMethods(role) removeGeneric(role, value) else setGeneric(role, nil) end end def setNilOrRemoveAllGeneric(role) if hasManyMethods(role) setGeneric(role, []) else setGeneric(role, nil) end end def getGeneric(role) send("get#{firstToUpper(role.to_s)}") end def getGenericAsArray(role) result = getGeneric(role) result = [result].compact unless result.is_a?(Array) result end def eIsSet(role) eval("defined? @#{role}") != nil end def eUnset(role) if respond_to?("add#{firstToUpper(role.to_s)}") setGeneric(role, []) else setGeneric(role, nil) end remove_instance_variable("@#{role}") end def eContainer @_container end def eContainingFeature @_containing_feature_name end # returns the contained elements in no particular order def eContents if @_contained_elements @_contained_elements.dup else [] end end # if a block is given, calls the block on every contained element in depth first order. # if the block returns :prune, recursion will stop at this point. # # if no block is given builds and returns a list of all contained elements. # def eAllContents(&block) if block if @_contained_elements @_contained_elements.each do |e| res = block.call(e) e.eAllContents(&block) if res != :prune end end nil else result = [] if @_contained_elements @_contained_elements.each do |e| result << e result.concat(e.eAllContents) end end result end end def disconnectContainer eContainer.setNilOrRemoveGeneric(eContainingFeature, self) if eContainer end def _set_container(container, containing_feature_name) # if a new container is set, make sure to disconnect from the old one. # note that _set_container will never be called for the container and the role # which are currently set because the accessor methods in BuilderExtensions # block setting/adding a value which is already present. # (it may be called for the same container with a different role, a different container # with the same role and a different container with a different role, though) # this ensures, that disconnecting for the current container doesn't break # a new connection which has just been set up in the accessor methods. disconnectContainer if container @_container._remove_contained_element(self) if @_container container._add_contained_element(self) if container @_container = container @_containing_feature_name = containing_feature_name end def _add_contained_element(element) @_contained_elements ||= [] @_contained_elements << element end def _remove_contained_element(element) @_contained_elements.delete(element) if @_contained_elements end def _assignmentTypeError(target, value, expected) text = "" if target targetId = target.class.name targetId += "(" + target.name + ")" if target.respond_to?(:name) and target.name text += "In #{targetId} : " end valueId = value.class.name valueId += "(" + value.name + ")" if value.respond_to?(:name) and value.name valueId += "(:" + value.to_s + ")" if value.is_a?(Symbol) text += "Can not use a #{valueId} where a #{expected} is expected" StandardError.new(text) end end end end rgen-0.7.0/lib/rgen/metamodel_builder/intermediate/0000755000004100000410000000000012352210062022322 5ustar www-datawww-datargen-0.7.0/lib/rgen/metamodel_builder/intermediate/feature.rb0000644000004100000410000000671012352210062024306 0ustar www-datawww-datarequire 'rgen/metamodel_builder/data_types' module RGen module MetamodelBuilder module Intermediate class Feature attr_reader :etype, :impl_type def value(prop) @props[prop] end def annotations @annotations ||= [] end def many? value(:upperBound) > 1 || value(:upperBound) == -1 end def reference? is_a?(Reference) end protected def check(props) @props.keys.each do |p| kind = props[p] raise StandardError.new("invalid property #{p}") unless kind raise StandardError.new("property '#{p}' not set") if value(p).nil? && kind == :required end end end class Attribute < Feature Properties = { :name => :required, :ordered => :required, :unique => :required, :changeable => :required, :volatile => :required, :transient => :required, :unsettable => :required, :derived => :required, :lowerBound => :required, :upperBound => :required, :defaultValueLiteral => :optional } Defaults = { :ordered => true, :unique => true, :changeable => true, :volatile => false, :transient => false, :unsettable => false, :derived => false, :lowerBound => 0 } Types = { String => :EString, Integer => :EInt, RGen::MetamodelBuilder::DataTypes::Long => :ELong, Float => :EFloat, RGen::MetamodelBuilder::DataTypes::Boolean => :EBoolean, Object => :ERubyObject, Class => :ERubyClass } def self.default_value(prop) Defaults[prop] end def self.properties Properties.keys.sort{|a,b| a.to_s <=> b.to_s} end def initialize(type, props) @props = Defaults.merge(props) type ||= String @etype = Types[type] if @etype @impl_type = type elsif type.is_a?(RGen::MetamodelBuilder::DataTypes::Enum) @etype = :EEnumerable @impl_type = type else raise ArgumentError.new("invalid type '#{type}'") end if @props[:derived] @props[:changeable] = false @props[:volatile] = true @props[:transient] = true end check(Properties) end end class Reference < Feature attr_accessor :opposite Properties = { :name => :required, :ordered => :required, :unique => :required, :changeable => :required, :volatile => :required, :transient => :required, :unsettable => :required, :derived => :required, :lowerBound => :required, :upperBound => :required, :resolveProxies => :required, :containment => :required } Defaults = { :ordered => true, :unique => true, :changeable => true, :volatile => false, :transient => false, :unsettable => false, :derived => false, :lowerBound => 0, :resolveProxies => true } def self.default_value(prop) Defaults[prop] end def self.properties Properties.keys.sort{|a,b| a.to_s <=> b.to_s} end def initialize(type, props) @props = Defaults.merge(props) if type.respond_to?(:_metamodel_description) @etype = nil @impl_type = type else raise ArgumentError.new("'#{type}' (#{type.class}) is not a MMBase in reference #{props[:name]}") end if @props[:derived] @props[:changeable] = false @props[:volatile] = true @props[:transient] = true end check(Properties) end end end end end rgen-0.7.0/lib/rgen/metamodel_builder/intermediate/annotation.rb0000644000004100000410000000127012352210062025021 0ustar www-datawww-datamodule RGen module MetamodelBuilder module Intermediate class Annotation attr_reader :details, :source def initialize(hash) if hash[:source] || hash[:details] restKeys = hash.keys - [:source, :details] raise "Hash key #{restKeys.first} not allowed." unless restKeys.empty? raise "Details not provided, key :details is missing" unless hash[:details] raise "Details must be provided as a hash" unless hash[:details].is_a?(Hash) @details = hash[:details] @source = hash[:source] else raise "Details must be provided as a hash" unless hash.is_a?(Hash) @details = hash end end end end end end rgen-0.7.0/lib/rgen/metamodel_builder/module_extension.rb0000644000004100000410000000146612352210062023565 0ustar www-datawww-datarequire 'rgen/ecore/ecore_interface' require 'rgen/metamodel_builder/intermediate/annotation' module RGen module MetamodelBuilder # This module is used to extend modules which should be # part of RGen metamodels module ModuleExtension include RGen::ECore::ECoreInterface def annotation(hash) _annotations << Intermediate::Annotation.new(hash) end def _annotations @_annotations ||= [] end def _constantOrder @_constantOrder ||= [] end def final_method(m) @final_methods ||= [] @final_methods << m end def method_added(m) raise "Method #{m} can not be redefined" if @final_methods && @final_methods.include?(m) end def self.extended(m) MetamodelBuilder::ConstantOrderHelper.moduleCreated(m) end end end end rgen-0.7.0/lib/rgen/metamodel_builder/data_types.rb0000644000004100000410000000444212352210062022336 0ustar www-datawww-datamodule RGen module MetamodelBuilder module DataTypes # An enum object is used to describe possible attribute values within a # MetamodelBuilder attribute definition. An attribute defined this way can only # take the values specified when creating the Enum object. # Literal values can only be symbols or true or false. # Optionally a name may be specified for the enum object. # # Examples: # # Enum.new(:name => "AnimalEnum", :literals => [:cat, :dog]) # Enum.new(:literals => [:cat, :dog]) # Enum.new([:cat, :dog]) # class Enum attr_reader :name, :literals # Creates a new named enum type object consisting of the elements passed as arguments. def initialize(params) MetamodelBuilder::ConstantOrderHelper.enumCreated(self) if params.is_a?(Array) @literals = params @name = "anonymous" elsif params.is_a?(Hash) raise StandardError.new("Hash entry :literals is missing") unless params[:literals] @literals = params[:literals] @name = params[:name] || "anonymous" else raise StandardError.new("Pass an Array or a Hash") end end # This method can be used to check if an object can be used as value for # variables having this enum object as type. def validLiteral?(l) literals.include?(l) end def literals_as_strings literals.collect do |l| if l.is_a?(Symbol) if l.to_s =~ /^\d|\W/ ":'"+l.to_s+"'" else ":"+l.to_s end elsif l.is_a?(TrueClass) || l.is_a?(FalseClass) l.to_s else raise StandardError.new("Literal values can only be symbols or true/false") end end end def to_s # :nodoc: name end end # Boolean is a predefined enum object having Ruby's true and false singletons # as possible values. Boolean = Enum.new(:name => "Boolean", :literals => [true, false]) # Long represents a 64-bit Integer # This constant is merely a marker for keeping this information in the Ruby version of the metamodel, # values of this type will always be instances of Integer or Bignum; # Setting it to a string value ensures that it responds to "to_s" which is used in the metamodel generator Long = "Long" end end end rgen-0.7.0/lib/rgen/metamodel_builder/constant_order_helper.rb0000644000004100000410000000664112352210062024567 0ustar www-datawww-datamodule RGen module MetamodelBuilder # The purpose of the ConstantOrderHelper is to capture the definition order of RGen metamodel builder # classes, modules and enums. The problem is that Ruby doesn't seem to track the order of # constants being created in a module. However the order is important because it defines the order # of eClassifiers and eSubpackages in a EPackage. # # It would be helpful here if Ruby provided a +const_added+ callback, but this is not the case up to now. # # The idea for capturing is that all events of creating a RGen class, module or enum are reported to the # ConstantOrderHelper singleton. # For classes and modules it tries to add their names to the parent's +_constantOrder+ array. # The parent module is derived from the class's or module's name. However, the new name is only added # if the respective parent module has a new constant (which is not yet in +_constantOrder+) which # points to the new class or module. # For enums it is a bit more complicated, because at the time the enum is created, the parent # module does not yet contain the constant to which the enum is assigned. Therefor, the enum is remembered # and it is tried to be stored on the next event (class, module or enum) within the module which was # created last (which was last extended with ModuleExtension). If it can not be found in that module, # all parent modules of the last module are searched. This way it should also be correctly entered in # case it was defined outside of the last created module. # Note that an enum is not stored to the constant order array unless another event occurs. That's why # it is possible that one enum is missing at the enum. This needs to be taken care of by the ECore transformer. # # This way of capturing should be sufficient for the regular use cases of the RGen metamodel builder language. # However, it is possible to write code which messes this up, see unit tests for details. # In the worst case, the new classes, modules or enums will just not be found in a parent module and thus be ignored. # ConstantOrderHelper = Class.new do def initialize @currentModule = nil @pendingEnum = nil end def classCreated(c) handlePendingEnum cont = containerModule(c) name = (c.name || "").split("::").last return unless cont.respond_to?(:_constantOrder) && !cont._constantOrder.include?(name) cont._constantOrder << name end def moduleCreated(m) handlePendingEnum cont = containerModule(m) name = (m.name || "").split("::").last return unless cont.respond_to?(:_constantOrder) && !cont._constantOrder.include?(name) cont._constantOrder << name @currentModule = m end def enumCreated(e) handlePendingEnum @pendingEnum = e end private def containerModule(m) containerName = (m.name || "").split("::")[0..-2].join("::") containerName.empty? ? nil : eval(containerName, TOPLEVEL_BINDING) end def handlePendingEnum return unless @pendingEnum m = @currentModule while m if m.respond_to?(:_constantOrder) newConstants = m.constants - m._constantOrder const = newConstants.find{|c| m.const_get(c).object_id == @pendingEnum.object_id} if const m._constantOrder << const.to_s break end end m = containerModule(m) end @pendingEnum = nil end end.new end end rgen-0.7.0/lib/rgen/metamodel_builder/mm_multiple.rb0000644000004100000410000000065012352210062022522 0ustar www-datawww-data module RGen module MetamodelBuilder def self.MMMultiple(*superclasses) c = Class.new(MMBase) class << c attr_reader :multiple_superclasses end c.instance_variable_set(:@multiple_superclasses, superclasses) superclasses.collect{|sc| sc.ancestors}.flatten. reject{|m| m.is_a?(Class)}.each do |arg| c.instance_eval do include arg end end return c end end endrgen-0.7.0/lib/rgen/metamodel_builder/builder_extensions.rb0000644000004100000410000005356612352210062024121 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 require 'erb' require 'rgen/metamodel_builder/intermediate/feature' module RGen module MetamodelBuilder # This module provides methods which can be used to setup a metamodel element. # The module is used to +extend+ MetamodelBuilder::MMBase, i.e. add the module's # methods as class methods. # # MetamodelBuilder::MMBase should be used as a start for new metamodel elements. # See MetamodelBuilder for an example. # module BuilderExtensions include Util::NameHelper class FeatureBlockEvaluator def self.eval(block, props1, props2=nil) return unless block e = self.new(props1, props2) e.instance_eval(&block) end def initialize(props1, props2) @props1, @props2 = props1, props2 end def annotation(hash) @props1.annotations << Intermediate::Annotation.new(hash) end def opposite_annotation(hash) raise "No opposite available" unless @props2 @props2.annotations << Intermediate::Annotation.new(hash) end end # Add an attribute which can hold a single value. # 'role' specifies the name which is used to access the attribute. # 'target_class' specifies the type of objects which can be held by this attribute. # If no target class is given, String will be default. # # This class method adds the following instance methods, where 'role' is to be # replaced by the given role name: # class#role # getter # class#role=(value) # setter def has_attr(role, target_class=nil, raw_props={}, &block) props = Intermediate::Attribute.new(target_class, _ownProps(raw_props).merge({ :name=>role, :upperBound=>1})) raise "No opposite available" unless _oppositeProps(raw_props).empty? FeatureBlockEvaluator.eval(block, props) _build_internal(props) end # Add an attribute which can hold multiple values. # 'role' specifies the name which is used to access the attribute. # 'target_class' specifies the type of objects which can be held by this attribute. # If no target class is given, String will be default. # # This class method adds the following instance methods, where 'role' is to be # replaced by the given role name: # class#addRole(value, index=-1) # class#removeRole(value) # class#role # getter, returns an array # class#role= # setter, sets multiple values at once # Note that the first letter of the role name is turned into an uppercase # for the add and remove methods. def has_many_attr(role, target_class=nil, raw_props={}, &block) props = Intermediate::Attribute.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({ :name=>role}))) raise "No opposite available" unless _oppositeProps(raw_props).empty? FeatureBlockEvaluator.eval(block, props) _build_internal(props) end # Add a single unidirectional association. # 'role' specifies the name which is used to access the association. # 'target_class' specifies the type of objects which can be held by this association. # # This class method adds the following instance methods, where 'role' is to be # replaced by the given role name: # class#role # getter # class#role=(value) # setter # def has_one(role, target_class=nil, raw_props={}, &block) props = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({ :name=>role, :upperBound=>1, :containment=>false})) raise "No opposite available" unless _oppositeProps(raw_props).empty? FeatureBlockEvaluator.eval(block, props) _build_internal(props) end # Add an unidirectional _many_ association. # 'role' specifies the name which is used to access the attribute. # 'target_class' is optional and can be used to fix the type of objects which # can be referenced by this association. # # This class method adds the following instance methods, where 'role' is to be # replaced by the given role name: # class#addRole(value, index=-1) # class#removeRole(value) # class#role # getter, returns an array # Note that the first letter of the role name is turned into an uppercase # for the add and remove methods. # def has_many(role, target_class=nil, raw_props={}, &block) props = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({ :name=>role, :containment=>false}))) raise "No opposite available" unless _oppositeProps(raw_props).empty? FeatureBlockEvaluator.eval(block, props) _build_internal(props) end def contains_one_uni(role, target_class=nil, raw_props={}, &block) props = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({ :name=>role, :upperBound=>1, :containment=>true})) raise "No opposite available" unless _oppositeProps(raw_props).empty? FeatureBlockEvaluator.eval(block, props) _build_internal(props) end def contains_many_uni(role, target_class=nil, raw_props={}, &block) props = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({ :name=>role, :containment=>true}))) raise "No opposite available" unless _oppositeProps(raw_props).empty? FeatureBlockEvaluator.eval(block, props) _build_internal(props) end # Add a bidirectional one-to-many association between two classes. # The class this method is called on is refered to as _own_class_ in # the following. # # Instances of own_class can use 'own_role' to access _many_ associated instances # of type 'target_class'. Instances of 'target_class' can use 'target_role' to # access _one_ associated instance of own_class. # # This class method adds the following instance methods where 'ownRole' and # 'targetRole' are to be replaced by the given role names: # own_class#addOwnRole(value, index=-1) # own_class#removeOwnRole(value) # own_class#ownRole # target_class#targetRole # target_class#targetRole=(value) # Note that the first letter of the role name is turned into an uppercase # for the add and remove methods. # # When an element is added/set on either side, this element also receives the element # is is added to as a new element. # def one_to_many(target_role, target_class, own_role, raw_props={}, &block) props1 = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({ :name=>target_role, :containment=>false}))) props2 = Intermediate::Reference.new(self, _oppositeProps(raw_props).merge({ :name=>own_role, :upperBound=>1, :containment=>false})) FeatureBlockEvaluator.eval(block, props1, props2) _build_internal(props1, props2) end def contains_many(target_role, target_class, own_role, raw_props={}, &block) props1 = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({ :name=>target_role, :containment=>true}))) props2 = Intermediate::Reference.new(self, _oppositeProps(raw_props).merge({ :name=>own_role, :upperBound=>1, :containment=>false})) FeatureBlockEvaluator.eval(block, props1, props2) _build_internal(props1, props2) end # This is the inverse of one_to_many provided for convenience. def many_to_one(target_role, target_class, own_role, raw_props={}, &block) props1 = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({ :name=>target_role, :upperBound=>1, :containment=>false})) props2 = Intermediate::Reference.new(self, _setManyUpperBound(_oppositeProps(raw_props).merge({ :name=>own_role, :containment=>false}))) FeatureBlockEvaluator.eval(block, props1, props2) _build_internal(props1, props2) end # Add a bidirectional many-to-many association between two classes. # The class this method is called on is refered to as _own_class_ in # the following. # # Instances of own_class can use 'own_role' to access _many_ associated instances # of type 'target_class'. Instances of 'target_class' can use 'target_role' to # access _many_ associated instances of own_class. # # This class method adds the following instance methods where 'ownRole' and # 'targetRole' are to be replaced by the given role names: # own_class#addOwnRole(value, index=-1) # own_class#removeOwnRole(value) # own_class#ownRole # target_class#addTargetRole # target_class#removeTargetRole=(value) # target_class#targetRole # Note that the first letter of the role name is turned into an uppercase # for the add and remove methods. # # When an element is added on either side, this element also receives the element # is is added to as a new element. # def many_to_many(target_role, target_class, own_role, raw_props={}, &block) props1 = Intermediate::Reference.new(target_class, _setManyUpperBound(_ownProps(raw_props).merge({ :name=>target_role, :containment=>false}))) props2 = Intermediate::Reference.new(self, _setManyUpperBound(_oppositeProps(raw_props).merge({ :name=>own_role, :containment=>false}))) FeatureBlockEvaluator.eval(block, props1, props2) _build_internal(props1, props2) end # Add a bidirectional one-to-one association between two classes. # The class this method is called on is refered to as _own_class_ in # the following. # # Instances of own_class can use 'own_role' to access _one_ associated instance # of type 'target_class'. Instances of 'target_class' can use 'target_role' to # access _one_ associated instance of own_class. # # This class method adds the following instance methods where 'ownRole' and # 'targetRole' are to be replaced by the given role names: # own_class#ownRole # own_class#ownRole=(value) # target_class#targetRole # target_class#targetRole=(value) # # When an element is set on either side, this element also receives the element # is is added to as the new element. # def one_to_one(target_role, target_class, own_role, raw_props={}, &block) props1 = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({ :name=>target_role, :upperBound=>1, :containment=>false})) props2 = Intermediate::Reference.new(self, _oppositeProps(raw_props).merge({ :name=>own_role, :upperBound=>1, :containment=>false})) FeatureBlockEvaluator.eval(block, props1, props2) _build_internal(props1, props2) end def contains_one(target_role, target_class, own_role, raw_props={}, &block) props1 = Intermediate::Reference.new(target_class, _ownProps(raw_props).merge({ :name=>target_role, :upperBound=>1, :containment=>true})) props2 = Intermediate::Reference.new(self, _oppositeProps(raw_props).merge({ :name=>own_role, :upperBound=>1, :containment=>false})) FeatureBlockEvaluator.eval(block, props1, props2) _build_internal(props1, props2) end def _metamodel_description # :nodoc: @metamodel_description ||= [] end def _add_metamodel_description(desc) # :nodoc @metamodel_description ||= [] @metamodelDescriptionByName ||= {} @metamodel_description.delete(@metamodelDescriptionByName[desc.value(:name)]) @metamodel_description << desc @metamodelDescriptionByName[desc.value(:name)] = desc end def abstract @abstract = true end def _abstract_class @abstract || false end def inherited(c) c.send(:include, c.const_set(:ClassModule, Module.new)) MetamodelBuilder::ConstantOrderHelper.classCreated(c) end protected # Central builder method # def _build_internal(props1, props2=nil) _add_metamodel_description(props1) if props1.many? _build_many_methods(props1, props2) else _build_one_methods(props1, props2) end if props2 # this is a bidirectional reference props1.opposite, props2.opposite = props2, props1 other_class = props1.impl_type other_class._add_metamodel_description(props2) raise "Internal error: second description must be a reference description" \ unless props2.reference? if props2.many? other_class._build_many_methods(props2, props1) else other_class._build_one_methods(props2, props1) end end end # To-One association methods # def _build_one_methods(props, other_props=nil) name = props.value(:name) other_role = other_props && other_props.value(:name) if props.value(:derived) build_derived_method(name, props, :one) else @@one_read_builder ||= ERB.new <<-CODE def get<%= firstToUpper(name) %> <% if !props.reference? && props.value(:defaultValueLiteral) %> <% defVal = props.value(:defaultValueLiteral) %> <% check_default_value_literal(defVal, props) %> <% defVal = '"'+defVal+'"' if props.impl_type == String %> <% defVal = ':'+defVal if props.impl_type.is_a?(DataTypes::Enum) && props.impl_type != DataTypes::Boolean %> (defined? @<%= name %>) ? @<%= name %> : <%= defVal %> <% else %> @<%= name %> <% end %> end <% if name != "class" %> alias <%= name %> get<%= firstToUpper(name) %> <% end %> CODE self::ClassModule.module_eval(@@one_read_builder.result(binding)) end if props.value(:changeable) @@one_write_builder ||= ERB.new <<-CODE def set<%= firstToUpper(name) %>(val) return if (defined? @<%= name %>) && val == @<%= name %> <%= type_check_code("val", props) %> oldval = @<%= name %> @<%= name %> = val <% if other_role %> oldval._unregister<%= firstToUpper(other_role) %>(self) unless oldval.nil? || oldval.is_a?(MMGeneric) val._register<%= firstToUpper(other_role) %>(self) unless val.nil? || val.is_a?(MMGeneric) <% end %> <% if props.reference? && props.value(:containment) %> val._set_container(self, :<%= name %>) unless val.nil? oldval._set_container(nil, nil) unless oldval.nil? <% end %> end alias <%= name %>= set<%= firstToUpper(name) %> def _register<%= firstToUpper(name) %>(val) <% if other_role %> @<%= name %>._unregister<%= firstToUpper(other_role) %>(self) unless @<%= name %>.nil? || @<%= name %>.is_a?(MMGeneric) <% end %> <% if props.reference? && props.value(:containment) %> @<%= name %>._set_container(nil, nil) unless @<%= name %>.nil? val._set_container(self, :<%= name %>) unless val.nil? <% end %> @<%= name %> = val end def _unregister<%= firstToUpper(name) %>(val) <% if props.reference? && props.value(:containment) %> @<%= name %>._set_container(nil, nil) unless @<%= name %>.nil? <% end %> @<%= name %> = nil end CODE self::ClassModule.module_eval(@@one_write_builder.result(binding)) end end # To-Many association methods # def _build_many_methods(props, other_props=nil) name = props.value(:name) other_role = other_props && other_props.value(:name) if props.value(:derived) build_derived_method(name, props, :many) else @@many_read_builder ||= ERB.new <<-CODE def get<%= firstToUpper(name) %> ( @<%= name %> ? @<%= name %>.dup : [] ) end <% if name != "class" %> alias <%= name %> get<%= firstToUpper(name) %> <% end %> CODE self::ClassModule.module_eval(@@many_read_builder.result(binding)) end if props.value(:changeable) @@many_write_builder ||= ERB.new <<-CODE def add<%= firstToUpper(name) %>(val, index=-1) @<%= name %> = [] unless @<%= name %> return if val.nil? || (@<%= name %>.any?{|e| e.object_id == val.object_id} && (val.is_a?(MMBase) || val.is_a?(MMGeneric))) <%= type_check_code("val", props) %> @<%= name %>.insert(index, val) <% if other_role %> val._register<%= firstToUpper(other_role) %>(self) unless val.is_a?(MMGeneric) <% end %> <% if props.reference? && props.value(:containment) %> val._set_container(self, :<%= name %>) <% end %> end def remove<%= firstToUpper(name) %>(val) @<%= name %> = [] unless @<%= name %> @<%= name %>.each_with_index do |e,i| if e.object_id == val.object_id @<%= name %>.delete_at(i) <% if props.reference? && props.value(:containment) %> val._set_container(nil, nil) <% end %> <% if other_role %> val._unregister<%= firstToUpper(other_role) %>(self) unless val.is_a?(MMGeneric) <% end %> return end end end def set<%= firstToUpper(name) %>(val) return if val.nil? raise _assignmentTypeError(self, val, Enumerable) unless val.is_a? Enumerable get<%= firstToUpper(name) %>.each {|e| remove<%= firstToUpper(name) %>(e) } val.each {|v| add<%= firstToUpper(name) %>(v) } end alias <%= name %>= set<%= firstToUpper(name) %> def _register<%= firstToUpper(name) %>(val) @<%= name %> = [] unless @<%= name %> @<%= name %>.push val <% if props.reference? && props.value(:containment) %> val._set_container(self, :<%= name %>) <% end %> end def _unregister<%= firstToUpper(name) %>(val) @<%= name %>.delete val <% if props.reference? && props.value(:containment) %> val._set_container(nil, nil) <% end %> end CODE self::ClassModule.module_eval(@@many_write_builder.result(binding)) end end private def build_derived_method(name, props, kind) raise "Implement method #{name}_derived instead of method #{name}" \ if (public_instance_methods+protected_instance_methods+private_instance_methods).include?(name) @@derived_builder ||= ERB.new <<-CODE def get<%= firstToUpper(name) %> raise "Derived feature requires public implementation of method <%= name %>_derived" \ unless respond_to?(:<%= name+"_derived" %>) val = <%= name %>_derived <% if kind == :many %> raise _assignmentTypeError(self,val,Enumerable) unless val && val.is_a?(Enumerable) val.each do |v| <%= type_check_code("v", props) %> end <% else %> <%= type_check_code("val", props) %> <% end %> val end <% if name != "class" %> alias <%= name %> get<%= firstToUpper(name) %> <% end %> #TODO final_method :<%= name %> CODE self::ClassModule.module_eval(@@derived_builder.result(binding)) end def check_default_value_literal(literal, props) return if literal.nil? || props.impl_type == String if props.impl_type == Integer || props.impl_type == RGen::MetamodelBuilder::DataTypes::Long unless literal =~ /^\d+$/ raise StandardError.new("Property #{props.value(:name)} can not take value #{literal}, expected an Integer") end elsif props.impl_type == Float unless literal =~ /^\d+\.\d+$/ raise StandardError.new("Property #{props.value(:name)} can not take value #{literal}, expected a Float") end elsif props.impl_type == RGen::MetamodelBuilder::DataTypes::Boolean unless ["true", "false"].include?(literal) raise StandardError.new("Property #{props.value(:name)} can not take value #{literal}, expected true or false") end elsif props.impl_type.is_a?(RGen::MetamodelBuilder::DataTypes::Enum) unless props.impl_type.literals.include?(literal.to_sym) raise StandardError.new("Property #{props.value(:name)} can not take value #{literal}, expected one of #{props.impl_type.literals_as_strings.join(', ')}") end else raise StandardError.new("Unkown type "+props.impl_type.to_s) end end def type_check_code(varname, props) code = "" if props.impl_type == RGen::MetamodelBuilder::DataTypes::Long code << "unless #{varname}.nil? || #{varname}.is_a?(Integer) || #{varname}.is_a?(MMGeneric)" code << "\n" expected = "Integer" elsif props.impl_type.is_a?(Class) code << "unless #{varname}.nil? || #{varname}.is_a?(#{props.impl_type}) || #{varname}.is_a?(MMGeneric)" code << " || #{varname}.is_a?(BigDecimal)" if props.impl_type == Float && defined?(BigDecimal) code << "\n" expected = props.impl_type.to_s elsif props.impl_type.is_a?(RGen::MetamodelBuilder::DataTypes::Enum) code << "unless #{varname}.nil? || [#{props.impl_type.literals_as_strings.join(',')}].include?(#{varname}) || #{varname}.is_a?(MMGeneric)\n" expected = "["+props.impl_type.literals_as_strings.join(',')+"]" else raise StandardError.new("Unkown type "+props.impl_type.to_s) end code << "raise _assignmentTypeError(self,#{varname},\"#{expected}\")\n" code << "end" code end def _ownProps(props) Hash[*(props.select{|k,v| !(k.to_s =~ /^opposite_/)}.flatten)] end def _oppositeProps(props) r = {} props.each_pair do |k,v| if k.to_s =~ /^opposite_(.*)$/ r[$1.to_sym] = v end end r end def _setManyUpperBound(props) props[:upperBound] = -1 unless props[:upperBound].is_a?(Integer) && props[:upperBound] > 1 props end end end end rgen-0.7.0/lib/rgen/environment.rb0000644000004100000410000000563212352210062017072 0ustar www-datawww-datamodule RGen # An Environment is used to hold model elements. # class Environment def initialize @elements = {} @subClasses = {} @subClassesUpdated = {} @deleted = {} @deletedClasses = {} end # Add a model element. Returns the environment so << can be chained. # def <<(el) clazz = el.class @elements[clazz] ||= [] @elements[clazz] << el updateSubClasses(clazz) self end # Removes model element from environment. def delete(el) @deleted[el] = true @deletedClasses[el.class] = true end # Iterates each element # def each(&b) removeDeleted @elements.values.flatten.each(&b) end # Return the elements of the environment as an array # def elements removeDeleted @elements.values.flatten end # This method can be used to instantiate a class and automatically put it into # the environment. The new instance is returned. # def new(clazz, *args) obj = clazz.new(*args) self << obj obj end # Finds and returns model elements in the environment. # # The search description argument must be a hash specifying attribute/value pairs. # Only model elements are returned which respond to the specified attribute methods # and return the specified values as result of these attribute methods. # # As a special hash key :class can be used to look for model elements of a specific # class. In this case an array of possible classes can optionally be given. # def find(desc) removeDeleted result = [] classes = desc[:class] if desc[:class] and desc[:class].is_a?(Array) classes = [ desc[:class] ] if !classes and desc[:class] if classes hashKeys = classesWithSubClasses(classes) else hashKeys = @elements.keys end hashKeys.each do |clazz| next unless @elements[clazz] @elements[clazz].each do |e| failed = false desc.each_pair { |k,v| failed = true if k != :class and ( !e.respond_to?(k) or e.send(k) != v ) } result << e unless failed end end result end private def removeDeleted @deletedClasses.keys.each do |c| @elements[c].reject!{|e| @deleted[e]} end @deletedClasses.clear @deleted.clear end def updateSubClasses(clazz) return if @subClassesUpdated[clazz] if clazz.respond_to?( :ecore ) superClasses = clazz.ecore.eAllSuperTypes.collect{|c| c.instanceClass} else superClasses = superclasses(clazz) end superClasses.each do |c| next if c == Object @subClasses[c] ||= [] @subClasses[c] << clazz end @subClassesUpdated[clazz] = true end def classesWithSubClasses(classes) result = classes classes.each do |c| result += @subClasses[c] if @subClasses[c] end result.uniq end def superclasses(clazz) if clazz == Object [] else superclasses(clazz.superclass) << clazz.superclass end end end endrgen-0.7.0/lib/rgen/util/0000755000004100000410000000000012352210062015150 5ustar www-datawww-datargen-0.7.0/lib/rgen/util/name_helper.rb0000644000004100000410000000124412352210062017755 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 module RGen module Util module NameHelper def normalize(name) name.gsub(/\W/,'_') end def className(object) object.class.name =~ /::(\w+)$/; $1 end def firstToUpper(str) str[0..0].upcase + ( str[1..-1] || "" ) end def firstToLower(str) str[0..0].downcase + ( str[1..-1] || "" ) end def saneClassName(str) firstToUpper(normalize(str)).sub(/^Class$/, 'Clazz') end def saneMethodName(str) firstToLower(normalize(str)).sub(/^class$/, 'clazz') end def camelize(str) str.split(/[\W_]/).collect{|s| firstToUpper(s.downcase)}.join end end end end rgen-0.7.0/lib/rgen/util/auto_class_creator.rb0000644000004100000410000000176212352210062021357 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 require 'rgen/metamodel_builder' module RGen module Util class Base extend MetamodelBuilder def initialize(env=nil) env << self if env end end class AutoCreatedClass < Base def method_missing(m,*args) return super unless self.class.parent.accEnabled if m.to_s =~ /(.*)=$/ self.class.has_one($1) send(m,args[0]) elsif args.size == 0 self.class.has_many(m) send(m) end end end # will be "extended" to the auto created class module ParentAccess def parent=(p) @parent = p end def parent @parent end end module AutoClassCreator attr_reader :accEnabled def const_missing(className) return super unless @accEnabled module_eval("class "+className.to_s+" < RGen::AutoCreatedClass; end") c = const_get(className) c.extend(ParentAccess) c.parent = self c end def enableACC @accEnabled = true end def disableACC @accEnabled = false end end end end rgen-0.7.0/lib/rgen/util/file_change_detector.rb0000644000004100000410000000455512352210062021623 0ustar www-datawww-datarequire 'digest' module RGen module Util # The FileChangeDetector detects changes in a set of files. # Changes are detected between successive calls to check_files with a give set of files. # Changes include files being added, removed or having changed their content. # class FileChangeDetector FileInfo = Struct.new(:timestamp, :digest) # Create a FileChangeDetector, options include: # # :file_added # a proc which is called when a file is added, receives the filename # # :file_removed # a proc which is called when a file is removed, receives the filename # # :file_changed # a proc which is called when a file is changed, receives the filename # def initialize(options={}) @file_added = options[:file_added] @file_removed = options[:file_removed] @file_changed = options[:file_changed] @file_info = {} end # Checks if any of the files has changed compared to the last call of check_files. # When called for the first time on a new object, all files will be reported as being added. # def check_files(files) files_before = @file_info.keys used_files = {} files.each do |file| begin if @file_info[file] if @file_info[file].timestamp != File.mtime(file) @file_info[file].timestamp = File.mtime(file) digest = calc_digest(file) if @file_info[file].digest != digest @file_info[file].digest = digest @file_changed && @file_changed.call(file) end end else @file_info[file] = FileInfo.new @file_info[file].timestamp = File.mtime(file) @file_info[file].digest = calc_digest(file) @file_added && @file_added.call(file) end used_files[file] = true # protect against missing files rescue Errno::ENOENT # used_files is not set and @file_info will be removed below # notification hook hasn't been called yet since it comes after file accesses end end files_before.each do |file| if !used_files[file] @file_info.delete(file) @file_removed && @file_removed.call(file) end end end private def calc_digest(file) sha1 = Digest::SHA1.new sha1.file(file) sha1.hexdigest end end end end rgen-0.7.0/lib/rgen/util/model_comparator_base.rb0000644000004100000410000000663212352210062022025 0ustar www-datawww-datarequire 'andand' module RGen module Util class ModelComparatorBase CompareSpec = Struct.new(:identifier, :recurse, :filter, :ignore_features, :display_name, :sort) INDENT = " " class << self attr_reader :compareSpecs def compare_spec(clazz, hash) @compareSpecs ||= {} raise "Compare spec already defined for #{clazz}" if @compareSpecs[clazz] spec = CompareSpec.new hash.each_pair do |k,v| spec.send("#{k}=",v) end @compareSpecs[clazz] = spec end end # compares two sets of elements def compare(as, bs, recursive=true) result = [] aById = as.select{|e| useElement?(e)}.inject({}){|r, e| r[elementIdentifier(e)] = e; r} bById = bs.select{|e| useElement?(e)}.inject({}){|r, e| r[elementIdentifier(e)] = e; r} onlyA = sortElements((aById.keys - bById.keys).collect{|id| aById[id]}) onlyB = sortElements((bById.keys - aById.keys).collect{|id| bById[id]}) aAndB = sortElementPairs((aById.keys & bById.keys).collect{|id| [aById[id], bById[id]]}) onlyA.each do |e| result << "- #{elementDisplayName(e)}" end onlyB.each do |e| result << "+ #{elementDisplayName(e)}" end if recursive aAndB.each do |ab| a, b = *ab r = compareElements(a, b) if r.size > 0 result << "#{elementDisplayName(a)}" result += r.collect{|l| INDENT+l} end end end result end def sortElementPairs(pairs) pairs.sort do |x,y| a, b = x[0], y[0] r = a.class.name <=> b.class.name r = compareSpec(a).sort.call(a,b) if r == 0 && compareSpec(a) && compareSpec(a).sort r end end def sortElements(elements) elements.sort do |a,b| r = a.class.name <=> b.class.name r = compareSpec(a).sort.call(a,b) if r == 0 && compareSpec(a) && compareSpec(a).sort r end end def elementDisplayName(e) if compareSpec(e) && compareSpec(e).display_name compareSpec(e).display_name.call(e) else elementIdentifier(e) end end def compareElements(a, b) result = [] if a.class != b.class result << "Class: #{a.class} -> #{b.class}" else a.class.ecore.eAllStructuralFeatures.reject{|f| f.derived || compareSpec(a).andand.ignore_features.andand.include?(f.name.to_sym)}.each do |f| va, vb = a.getGeneric(f.name), b.getGeneric(f.name) if f.is_a?(RGen::ECore::EAttribute) r = compareValues(f.name, va, vb) result << r if r else va, vb = [va].compact, [vb].compact unless f.many r = compare(va, vb, f.containment || compareSpec(a).andand.recurse.andand.include?(f.name.to_sym)) if r.size > 0 result << "[#{f.name}]" result += r.collect{|l| INDENT+l} end end end end result end def compareValues(name, val1, val2) result = nil result = "[#{name}] #{val1} -> #{val2}" if val1 != val2 result end def elementIdentifier(element) cs = compareSpec(element) if cs && cs.identifier if cs.identifier.is_a?(Proc) cs.identifier.call(element) else cs.identifier end else if element.respond_to?(:name) element.name else element.object_id end end end def useElement?(element) cs = compareSpec(element) !(cs && cs.filter) || cs.filter.call(element) end def compareSpec(element) @compareSpec ||= {} return @compareSpec[element.class] if @compareSpec[element.class] return nil unless self.class.compareSpecs key = self.class.compareSpecs.keys.find{|k| element.is_a?(k)} @compareSpec[element.class] = self.class.compareSpecs[key] end end end end rgen-0.7.0/lib/rgen/util/model_dumper.rb0000644000004100000410000000104712352210062020153 0ustar www-datawww-datamodule RGen module Util module ModelDumper def dump(obj=nil) obj ||= self if obj.is_a?(Array) obj.collect {|o| dump(o)}.join("\n\n") elsif obj.class.respond_to?(:ecore) ([obj.to_s] + obj.class.ecore.eAllStructuralFeatures.select{|f| !f.many}.collect { |a| " #{a} => #{obj.getGeneric(a.name)}" } + obj.class.ecore.eAllStructuralFeatures.select{|f| f.many}.collect { |a| " #{a} => [ #{obj.getGeneric(a.name).join(', ')} ]" }).join("\n") else obj.to_s end end end end end rgen-0.7.0/lib/rgen/util/file_cache_map.rb0000644000004100000410000000705612352210062020404 0ustar www-datawww-datarequire 'digest' require 'fileutils' module RGen module Util # Implements a cache for storing and loading data associated with arbitrary files. # The data is stored in cache files within a subfolder of the folder where # the associated files exists. # The cache files are protected with a checksum and loaded data will be # invalid in case either the associated file are the cache file has changed. # class FileCacheMap # optional program version info to be associated with the cache files # if the program version changes, cached data will also be invalid attr_accessor :version_info # +cache_dir+ is the name of the subfolder where cache files are created # +postfix+ is an extension appended to the original file name for # creating the name of the cache file def initialize(cache_dir, postfix) @postfix = postfix @cache_dir = cache_dir end # load data associated with file +key_path+ # returns :invalid in case either the associated file or the cache file has changed # # options: # :invalidation_reasons: # an array which will receive symbols indicating why the cache is invalid: # :no_cachefile, :cachefile_corrupted, :keyfile_changed # def load_data(key_path, options={}) reasons = options[:invalidation_reasons] || [] cf = cache_file(key_path) result = nil begin File.open(cf, "rb") do |f| header = f.read(41) if !header reasons << :cachefile_corrupted return :invalid end checksum = header[0..39] data = f.read if calc_sha1(data) == checksum if calc_sha1_keydata(key_path) == data[0..39] result = data[41..-1] else reasons << :keyfile_changed result = :invalid end else reasons << :cachefile_corrupted result = :invalid end end rescue Errno::ENOENT reasons << :no_cachefile result = :invalid end result end # store data +value_data+ associated with file +key_path+ def store_data(key_path, value_data) data = calc_sha1_keydata(key_path) + "\n" + value_data data = calc_sha1(data) + "\n" + data cf = cache_file(key_path) FileUtils.mkdir(File.dirname(cf)) rescue Errno::EEXIST File.open(cf, "wb") do |f| f.write(data) end end # remove cache files which are not associated with any file in +key_paths+ # will only remove files within +root_path+ def clean_unused(root_path, key_paths) raise "key paths must be within root path" unless key_paths.all?{|p| p.index(root_path) == 0} used_files = key_paths.collect{|p| cache_file(p)} files = Dir[root_path+"/**/"+@cache_dir+"/*"+@postfix] files.each do |f| FileUtils.rm(f) unless used_files.include?(f) end end private def cache_file(path) File.dirname(path) + "/"+@cache_dir+"/" + File.basename(path) + @postfix end def calc_sha1(data) sha1 = Digest::SHA1.new sha1.update(data) sha1.hexdigest end def keyData(path) File.read(path)+@version_info.to_s end # this method is much faster than calling +keyData+ and putting the result in +calc_sha1+ # reason is probably that there are not so many big strings being created def calc_sha1_keydata(path) begin sha1 = Digest::SHA1.new sha1.file(path) sha1.update(@version_info.to_s) sha1.hexdigest rescue Errno::ENOENT "" end end end end end rgen-0.7.0/lib/rgen/util/model_comparator.rb0000644000004100000410000000400112352210062021017 0ustar www-datawww-datarequire 'rgen/ecore/ecore' module RGen module Util module ModelComparator # This method compares to models regarding equality # For this the identity of a model element is defined based on identity # of all attributes and referenced elements. # Arrays are sorted before comparison if possible (if <=> is provided). # def modelEqual?(a, b, featureIgnoreList=[]) @modelEqual_visited = {} _modelEqual_internal(a, b, featureIgnoreList, []) end def _modelEqual_internal(a, b, featureIgnoreList, path) return true if @modelEqual_visited[[a,b]] @modelEqual_visited[[a,b]] = true return true if a.nil? && b.nil? unless a.class == b.class puts "#{path.inspect}\n Classes differ: #{a} vs. #{b}" return false end if a.is_a?(Array) unless a.size == b.size puts "#{path.inspect}\n Array size differs: #{a.size} vs. #{b.size}" return false end begin # in Ruby 1.9 every object has the <=> operator but the default one returns # nil and thus sorting won't work (ArgumentError) as = a.sort rescue ArgumentError, NoMethodError as = a end begin bs = b.sort rescue ArgumentError, NoMethodError bs = b end a.each_index do |i| return false unless _modelEqual_internal(as[i], bs[i], featureIgnoreList, path+[i]) end else a.class.ecore.eAllStructuralFeatures.reject{|f| f.derived}.each do |feat| next if featureIgnoreList.include?(feat.name) if feat.eType.is_a?(RGen::ECore::EDataType) unless a.getGeneric(feat.name) == b.getGeneric(feat.name) puts "#{path.inspect}\n Value '#{feat.name}' differs: #{a.getGeneric(feat.name)} vs. #{b.getGeneric(feat.name)}" return false end else return false unless _modelEqual_internal(a.getGeneric(feat.name), b.getGeneric(feat.name), featureIgnoreList, path+["#{a.respond_to?(:name) && a.name}:#{feat.name}"]) end end end return true end end end end rgen-0.7.0/lib/rgen/util/cached_glob.rb0000644000004100000410000000344312352210062017713 0ustar www-datawww-datamodule RGen module Util # WARNING: the mechanism of taking timestamps of directories in order to find out if the # content has changed doesn't work reliably across all kinds of filesystems # class CachedGlob def initialize(dir_glob, file_glob) @dir_glob = dir_glob @file_glob = file_glob @root_dirs = [] @dirs = {} @files = {} @timestamps = {} end # returns all files contained in directories matched by +dir_glob+ which match +file_glob+. # +file_glob+ must be relative to +dir_glob+. # dir_glob "*/a" with file_glob "**/*.txt" is basically equivalent with Dir.glob("*/a/**/*.txt") # the idea is that the file glob will only be re-eavluated when the content of one of the # directories matched by dir_glob has changed. # this will only be faster than a normal Dir.glob if the number of dirs matched by dir_glob is # relatively large and changes in files affect only a few of them at a time. def glob root_dirs = Dir.glob(@dir_glob) (@root_dirs - root_dirs).each do |d| remove_root_dir(d) end (@root_dirs & root_dirs).each do |d| update_root_dir(d) if dir_changed?(d) end (root_dirs - @root_dirs).each do |d| update_root_dir(d) end @root_dirs = root_dirs @root_dirs.sort.collect{|d| @files[d]}.flatten end private def dir_changed?(dir) @dirs[dir].any?{|d| File.mtime(d) != @timestamps[dir][d]} end def update_root_dir(dir) @dirs[dir] = Dir.glob(dir+"/**/") @files[dir] = Dir.glob(dir+"/"+@file_glob) @timestamps[dir] = {} @dirs[dir].each do |d| @timestamps[dir][d] = File.mtime(d) end end def remove_root_dir(dir) @dirs.delete(dir) @files.delete(dir) @timestamps.delete(dir) end end end end rgen-0.7.0/lib/rgen/util/method_delegation.rb0000644000004100000410000000537612352210062021163 0ustar www-datawww-datamodule RGen module Util module MethodDelegation class << self def registerDelegate(delegate, object, method) method = method.to_sym createDelegateStore(object) if object._methodDelegates[method] object._methodDelegates[method] << delegate else object._methodDelegates[method] = [delegate] createDelegatingMethod(object, method) end end def unregisterDelegate(delegate, object, method) method = method.to_sym return unless object.respond_to?(:_methodDelegates) return unless object._methodDelegates[method] object._methodDelegates[method].delete(delegate) if object._methodDelegates[method].empty? object._methodDelegates[method] = nil removeDelegatingMethod(object, method) removeDelegateStore(object) end end private def createDelegateStore(object) return if object.respond_to?(:_methodDelegates) class << object def _methodDelegates @_methodDelegates ||= {} end end end def removeDelegateStore(object) return unless object.respond_to?(:_methodDelegates) class << object remove_method(:_methodDelegates) end end def createDelegatingMethod(object, method) if hasMethod(object, method) object.instance_eval <<-END class << self alias #{aliasMethodName(method)} #{method} end END end # define the delegating method object.instance_eval <<-END class << self def #{method}(*args, &block) @_methodDelegates[:#{method}].each do |d| catch(:continue) do return d.#{method}_delegated(self, *args, &block) end end # if aliased method does not exist, we want an exception #{aliasMethodName(method)}(*args, &block) end end END end def removeDelegatingMethod(object, method) if hasMethod(object, aliasMethodName(method)) # there is an aliased original, restore it object.instance_eval <<-END class << self alias #{method} #{aliasMethodName(method)} remove_method(:#{aliasMethodName(method)}) end END else # just delete the delegating method object.instance_eval <<-END class << self remove_method(:#{method}) end END end end def hasMethod(object, method) # in Ruby 1.9, #methods returns symbols if object.methods.first.is_a?(Symbol) method = method.to_sym else method = method.to_s end object.methods.include?(method) end def aliasMethodName(method) "#{method}_delegate_original" end end end end end rgen-0.7.0/lib/rgen/util/pattern_matcher.rb0000644000004100000410000002341012352210062020655 0ustar www-datawww-datamodule RGen module Util # A PatternMatcher can be used to find, insert and remove patterns on a given model. # # A pattern is specified by means of a block passed to the add_pattern method. # The block must take an Environment as first parameter and at least one model element # as connection point as further parameter. The pattern matches if it can be found # in a given environment and connected to the given connection point elements. # class PatternMatcher Match = Struct.new(:root, :elements, :bound_values) attr_accessor :debug def initialize @patterns = {} @insert_mode = false @debug = false end def add_pattern(name, &block) raise "a pattern needs at least 2 block parameters: " + "an RGen environment and a model element as connection point" \ unless block.arity >= 2 @patterns[name] = block end def find_pattern(env, name, *connection_points) match = find_pattern_internal(env, name, *connection_points) end def insert_pattern(env, name, *connection_points) @insert_mode = true root = evaluate_pattern(name, env, connection_points) @insert_mode = false root end def remove_pattern(env, name, *connection_points) match = find_pattern_internal(env, name, *connection_points) if match match.elements.each do |e| disconnect_element(e) env.delete(e) end match else nil end end def lazy(&block) if @insert_mode block.call else Lazy.new(&block) end end class Lazy < RGen::MetamodelBuilder::MMGeneric def initialize(&block) @block = block end def _eval @block.call end end private class Proxy < RGen::MetamodelBuilder::MMProxy attr_reader :_target def initialize(target) @_target = target end def method_missing(m, *args) result = @_target.send(m, *args) if result.is_a?(Array) result.collect do |e| if e.is_a?(RGen::MetamodelBuilder::MMBase) Proxy.new(e) else e end end else if result.is_a?(RGen::MetamodelBuilder::MMBase) Proxy.new(result) else result end end end end class Bindable < RGen::MetamodelBuilder::MMGeneric # by being an Enumerable, Bindables can be used for many-features as well include Enumerable def initialize @bound = false @value = nil @many = false end def _bound? @bound end def _many? @many end def _bind(value) @value = value @bound = true end def _value @value end def to_s @value.to_s end # pretend this is an enumerable which contains itself, so the bindable can be # inserted into many-features, when this is done the bindable is marked as a many-bindable def each @many = true yield(self) end def method_missing(m, *args) raise "bindable not bound" unless _bound? @value.send(m, *args) end end TempEnv = RGen::Environment.new class << TempEnv def <<(el); end end def find_pattern_internal(env, name, *connection_points) proxied_args = connection_points.collect{|a| a.is_a?(RGen::MetamodelBuilder::MMBase) ? Proxy.new(a) : a } bindables = create_bindables(name, connection_points) pattern_root = evaluate_pattern(name, TempEnv, proxied_args+bindables) candidates = candidates_via_connection_points(pattern_root, connection_points) candidates ||= env.find(:class => pattern_root.class) candidates.each do |e| # create new bindables for every try, otherwise they can could be bound to old values bindables = create_bindables(name, connection_points) pattern_root = evaluate_pattern(name, TempEnv, proxied_args+bindables) matched = match(pattern_root, e) return Match.new(e, matched, bindables.collect{|b| b._value}) if matched end nil end def create_bindables(pattern_name, connection_points) (1..(num_pattern_variables(pattern_name) - connection_points.size)).collect{|i| Bindable.new} end def candidates_via_connection_points(pattern_root, connection_points) @candidates_via_connection_points_refs ||= {} refs = (@candidates_via_connection_points_refs[pattern_root.class] ||= pattern_root.class.ecore.eAllReferences.reject{|r| r.derived || r.many || !r.eOpposite}) candidates = nil refs.each do |r| t = pattern_root.getGeneric(r.name) cp = t.is_a?(Proxy) && connection_points.find{|cp| cp.object_id == t._target.object_id} if cp elements = cp.getGenericAsArray(r.eOpposite.name) candidates = elements if candidates.nil? || elements.size < candidates.size end end candidates end def match(pat_element, test_element) visited = {} check_later = [] return false unless match_internal(pat_element, test_element, visited, check_later) while cl = check_later.shift pv, tv = cl.lazy._eval, cl.value if cl.feature.is_a?(RGen::ECore::EAttribute) unless pv == tv match_failed(cl.feature, "wrong attribute value (lazy): #{pv} vs. #{tv}") return false end else if pv.is_a?(Proxy) unless pv._target.object_id == tv.object_id match_failed(f, "wrong target object") return false end else unless (pv.nil? && tv.nil?) || (!pv.nil? && !tv.nil? && match_internal(pv, tv, visited, check_later)) return false end end end end visited.keys end CheckLater = Struct.new(:feature, :lazy, :value) def match_internal(pat_element, test_element, visited, check_later) return true if visited[test_element] visited[test_element] = true unless pat_element.class == test_element.class match_failed(nil, "wrong class: #{pat_element.class} vs #{test_element.class}") return false end all_structural_features(pat_element).each do |f| pat_values = pat_element.getGeneric(f.name) # nil values must be kept to support size check with Bindables pat_values = [ pat_values ] unless pat_values.is_a?(Array) test_values = test_element.getGeneric(f.name) test_values = [ test_values] unless test_values.is_a?(Array) if pat_values.size == 1 && pat_values.first.is_a?(Bindable) && pat_values.first._many? unless match_many_bindable(pat_values.first, test_values) return false end else unless pat_values.size == test_values.size match_failed(f, "wrong size #{pat_values.size} vs. #{test_values.size}") return false end pat_values.each_with_index do |pv,i| tv = test_values[i] if pv.is_a?(Lazy) check_later << CheckLater.new(f, pv, tv) elsif pv.is_a?(Bindable) if pv._bound? unless pv._value == tv match_failed(f, "value does not match bound value #{pv._value.class}:#{pv._value.object_id} vs. #{tv.class}:#{tv.object_id}") return false end else pv._bind(tv) end else if f.is_a?(RGen::ECore::EAttribute) unless pv == tv match_failed(f, "wrong attribute value") return false end else if pv.is_a?(Proxy) unless pv._target.object_id == tv.object_id match_failed(f, "wrong target object") return false end else unless both_nil_or_match(pv, tv, visited, check_later) return false end end end end end end end true end def match_many_bindable(bindable, test_values) if bindable._bound? bindable._value.each_with_index do |pv,i| tv = test_values[i] if f.is_a?(RGen::ECore::EAttribute) unless pv == tv match_failed(f, "wrong attribute value") return false end else unless both_nil_or_match(pv, tv, visited, check_later) return false end end end else bindable._bind(test_values.dup) end true end def both_nil_or_match(pv, tv, visited, check_later) (pv.nil? && tv.nil?) || (!pv.nil? && !tv.nil? && match_internal(pv, tv, visited, check_later)) end def match_failed(f, msg) puts "match failed #{f&&f.eContainingClass.name}##{f&&f.name}: #{msg}" if @debug end def num_pattern_variables(name) prok = @patterns[name] prok.arity - 1 end def evaluate_pattern(name, env, connection_points) prok = @patterns[name] raise "unknown pattern #{name}" unless prok raise "wrong number of arguments, expected #{prok.arity-1} connection points)" \ unless connection_points.size == prok.arity-1 prok.call(env, *connection_points) end def disconnect_element(element) return if element.nil? all_structural_features(element).each do |f| if f.many element.setGeneric(f.name, []) else element.setGeneric(f.name, nil) end end end def all_structural_features(element) @all_structural_features ||= {} return @all_structural_features[element.class] if @all_structural_features[element.class] @all_structural_features[element.class] = element.class.ecore.eAllStructuralFeatures.reject{|f| f.derived} end end end end rgen-0.7.0/lib/rgen/serializer/0000755000004100000410000000000012352210062016344 5ustar www-datawww-datargen-0.7.0/lib/rgen/serializer/qualified_name_provider.rb0000644000004100000410000000265612352210062023557 0ustar www-datawww-datamodule RGen module Serializer # simple identifier calculation based on qualified names. # as a prerequisit, elements must have a local name stored in single attribute +attribute_name+. # there may be classes without the name attribute though and there may be elements without a # local name. in both cases the element will have the same qualified name as its container. # class QualifiedNameProvider def initialize(options={}) @qualified_name_cache = {} @attribute_name = options[:attribute_name] || "name" @separator = options[:separator] || "/" @leading_separator = options.has_key?(:leading_separator) ? options[:leading_separator] : true end def identifier(element) if element.is_a?(RGen::MetamodelBuilder::MMProxy) element.targetIdentifier else qualified_name(element) end end def qualified_name(element) return @qualified_name_cache[element] if @qualified_name_cache[element] local_ident = ((element.respond_to?(@attribute_name) && element.getGeneric(@attribute_name)) || "").strip parent = element.eContainer if parent if local_ident.size > 0 result = qualified_name(parent) + @separator + local_ident else result = qualified_name(parent) end else result = (@leading_separator ? @separator : "") + local_ident end @qualified_name_cache[element] = result end end end end rgen-0.7.0/lib/rgen/serializer/opposite_reference_filter.rb0000644000004100000410000000112312352210062024113 0ustar www-datawww-datamodule RGen module Serializer # Filters refereences with an eOpposite: # 1. containment references are always preferred # 2. at a 1-to-n reference the 1-reference is always preferred # 3. otherwise the reference with the name in string sort order before the opposite's name is prefereed # OppositeReferenceFilter = proc do |features| features.reject{|f| f.is_a?(RGen::ECore::EReference) && !f.containment && f.eOpposite && (f.eOpposite.containment || (f.many && !f.eOpposite.many) || (!(!f.many && f.eOpposite.many) && (f.name < f.eOpposite.name)))} end end end rgen-0.7.0/lib/rgen/serializer/json_serializer.rb0000644000004100000410000000720312352210062022075 0ustar www-datawww-datamodule RGen module Serializer class JsonSerializer def initialize(writer, opts={}) @writer = writer @elementIdentifiers = {} @identAttrName = opts[:identAttrName] || "name" @separator = opts[:separator] || "/" @leadingSeparator = opts.has_key?(:leadingSeparator) ? opts[:leadingSeparator] : true @featureFilter = opts[:featureFilter] @identifierProvider = opts[:identifierProvider] end def elementIdentifier(element) ident = @identifierProvider && @identifierProvider.call(element) ident || (element.is_a?(RGen::MetamodelBuilder::MMProxy) && element.targetIdentifier) || qualifiedElementName(element) end # simple identifier calculation based on qualified names # prerequisits: # * containment relations must be bidirectionsl # * local name stored in single attribute +@identAttrName+ for all classes # def qualifiedElementName(element) return @elementIdentifiers[element] if @elementIdentifiers[element] localIdent = ((element.respond_to?(@identAttrName) && element.getGeneric(@identAttrName)) || "").strip parentRef = element.class.ecore.eAllReferences.select{|r| r.eOpposite && r.eOpposite.containment}.first parent = parentRef && element.getGeneric(parentRef.name) if parent if localIdent.size > 0 parentIdent = qualifiedElementName(parent) result = parentIdent + @separator + localIdent else result = qualifiedElementName(parent) end else result = (@leadingSeparator ? @separator : "") + localIdent end @elementIdentifiers[element] = result end def serialize(elements) if elements.is_a?(Array) write("[ ") elements.each_with_index do |e, i| serializeElement(e) write(",\n") unless i == elements.size-1 end write("]") else serializeElement(elements) end end def serializeElement(element, indent="") write(indent + "{ \"_class\": \""+element.class.ecore.name+"\"") element.class.ecore.eAllStructuralFeatures.each do |f| next if f.derived value = element.getGeneric(f.name) unless value == [] || value.nil? || (f.is_a?(RGen::ECore::EReference) && f.eOpposite && f.eOpposite.containment) || (@featureFilter && !@featureFilter.call(f)) write(", ") writeFeature(f, value, indent) end end write(" }") end def writeFeature(feat, value, indent) write("\""+feat.name+"\": ") if feat.is_a?(RGen::ECore::EAttribute) if value.is_a?(Array) write("[ "+value.collect{|v| attributeValue(v, feat)}.join(", ")+" ]") else write(attributeValue(value, feat)) end elsif !feat.containment if value.is_a?(Array) write("[ "+value.collect{|v| "\""+elementIdentifier(v)+"\""}.join(", ")+" ]") else write("\""+elementIdentifier(value)+"\"") end else if value.is_a?(Array) write("[ \n") value.each_with_index do |v, i| serializeElement(v, indent+" ") write(",\n") unless i == value.size-1 end write("]") else write("\n") serializeElement(value, indent+" ") end end end def attributeValue(value, a) if a.eType == RGen::ECore::EString || a.eType.is_a?(RGen::ECore::EEnum) "\""+value.to_s.gsub('\\','\\\\\\\\').gsub('"','\\"').gsub("\n","\\n").gsub("\r","\\r"). gsub("\t","\\t").gsub("\f","\\f").gsub("\b","\\b")+"\"" else value.to_s end end private def write(s) @writer.write(s) end end end end rgen-0.7.0/lib/rgen/serializer/xmi20_serializer.rb0000644000004100000410000000442312352210062022064 0ustar www-datawww-datarequire 'rgen/serializer/xml_serializer' module RGen module Serializer class XMI20Serializer < XMLSerializer def serialize(rootElement) @referenceStrings = {} buildReferenceStrings(rootElement, "#/") addBuiltinReferenceStrings attrs = attributeValues(rootElement) attrs << ['xmi:version', "2.0"] attrs << ['xmlns:xmi', "http://www.omg.org/XMI"] attrs << ['xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance"] attrs << ['xmlns:ecore', "http://www.eclipse.org/emf/2002/Ecore" ] tag = "ecore:"+rootElement.class.ecore.name startTag(tag, attrs) writeComposites(rootElement) endTag(tag) end def writeComposites(element) eachReferencedElement(element, containmentReferences(element)) do |r,te| attrs = attributeValues(te) attrs << ['xsi:type', "ecore:"+te.class.ecore.name] tag = r.name startTag(tag, attrs) writeComposites(te) endTag(tag) end end def attributeValues(element) result = [] eAllAttributes(element).select{|a| !a.derived}.each do |a| val = element.getGeneric(a.name) result << [a.name, val] unless val.nil? || val == "" end eAllReferences(element).select{|r| !r.containment && !(r.eOpposite && r.eOpposite.containment) && !r.derived}.each do |r| targetElements = element.getGenericAsArray(r.name) val = targetElements.collect{|te| @referenceStrings[te]}.compact.join(' ') result << [r.name, val] unless val.nil? || val == "" end result end def buildReferenceStrings(element, string) @referenceStrings[element] = string eachReferencedElement(element, containmentReferences(element)) do |r,te| buildReferenceStrings(te, string+"/"+te.name) if te.respond_to?(:name) end end def addBuiltinReferenceStrings pre = "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore" @referenceStrings[RGen::ECore::EString] = pre+"#//EString" @referenceStrings[RGen::ECore::EInt] = pre+"#//EInt" @referenceStrings[RGen::ECore::ELong] = pre+"#//ELong" @referenceStrings[RGen::ECore::EFloat] = pre+"#//EFloat" @referenceStrings[RGen::ECore::EBoolean] = pre+"#//EBoolean" @referenceStrings[RGen::ECore::EJavaObject] = pre+"#//EJavaObject" @referenceStrings[RGen::ECore::EJavaClass] = pre+"#//EJavaClass" end end end end rgen-0.7.0/lib/rgen/serializer/xml_serializer.rb0000644000004100000410000000434512352210062021730 0ustar www-datawww-datamodule RGen module Serializer class XMLSerializer INDENT_SPACE = 2 def initialize(file) @indent = 0 @lastStartTag = nil @textContent = false @file = file end def serialize(rootElement) raise "Abstract class, overwrite method in subclass!" end def startTag(tag, attributes={}) @textContent = false handleLastStartTag(false, true) if attributes.is_a?(Hash) attrString = attributes.keys.collect{|k| "#{k}=\"#{attributes[k]}\""}.join(" ") else attrString = attributes.collect{|pair| "#{pair[0]}=\"#{pair[1]}\""}.join(" ") end @lastStartTag = " "*@indent*INDENT_SPACE + "<#{tag} "+attrString @indent += 1 end def endTag(tag) @indent -= 1 unless handleLastStartTag(true, true) output " "*@indent*INDENT_SPACE unless @textContent output "\n" end @textContent = false end def writeText(text) handleLastStartTag(false, false) output "#{text}" @textContent = true end protected def eAllReferences(element) @eAllReferences ||= {} @eAllReferences[element.class] ||= element.class.ecore.eAllReferences end def eAllAttributes(element) @eAllAttributes ||= {} @eAllAttributes[element.class] ||= element.class.ecore.eAllAttributes end def eAllStructuralFeatures(element) @eAllStructuralFeatures ||= {} @eAllStructuralFeatures[element.class] ||= element.class.ecore.eAllStructuralFeatures end def eachReferencedElement(element, refs, &block) refs.each do |r| targetElements = element.getGeneric(r.name) targetElements = [targetElements] unless targetElements.is_a?(Array) targetElements.each do |te| yield(r,te) end end end def containmentReferences(element) @containmentReferences ||= {} @containmentReferences[element.class] ||= eAllReferences(element).select{|r| r.containment} end private def handleLastStartTag(close, newline) return false unless @lastStartTag output @lastStartTag output close ? "/>" : ">" output "\n" if newline @lastStartTag = nil true end def output(text) @file.write(text) end end end end rgen-0.7.0/lib/rgen/serializer/xmi11_serializer.rb0000644000004100000410000000574312352210062022072 0ustar www-datawww-datarequire 'rgen/serializer/xml_serializer' module RGen module Serializer class XMI11Serializer < XMLSerializer def initialize(file) super @namespacePrefix = "" @contentLevelElements = [] end def setNamespace(shortcut, url) @namespaceShortcut = shortcut @namespaceUrl = url @namespacePrefix = shortcut+":" end def serialize(rootElement, headerInfo=nil) attrs = [] attrs << ['xmi.version', "1.1"] attrs << ['xmlns:'+@namespaceShortcut, @namespaceUrl] if @namespaceUrl attrs << ['timestamp', Time.now.to_s] startTag("XMI", attrs) if headerInfo startTag("XMI.header") writeHeaderInfo(headerInfo) endTag("XMI.header") end startTag("XMI.content") @contentLevelElements = [] writeElement(rootElement) # write remaining toplevel elements, each of which could have # more toplevel elements as childs while @contentLevelElements.size > 0 writeElement(@contentLevelElements.shift) end endTag("XMI.content") endTag("XMI") end def writeHeaderInfo(hash) hash.each_pair do |k,v| tag = "XMI." + k.to_s startTag(tag) if v.is_a?(Hash) writeHeaderInfo(v) else writeText(v.to_s) end endTag(tag) end end def writeElement(element) tag = @namespacePrefix + element.class.ecore.name attrs = attributeValues(element) startTag(tag, attrs) containmentReferences(element).each do |r| roletag = @namespacePrefix + r.eContainingClass.name + "." + r.name targets = element.getGeneric(r.name) targets = [ targets ] unless targets.is_a?(Array) targets.compact! next if targets.empty? startTag(roletag) targets.each do |t| if xmiLevel(t) == :content @contentLevelElements << t else writeElement(t) end end endTag(roletag) end endTag(tag) end def attributeValues(element) result = [["xmi.id", xmiId(element)]] eAllAttributes(element).select{|a| !a.derived}.each do |a| val = element.getGeneric(a.name) result << [a.name, val] unless val.nil? || val == "" end eAllReferences(element).each do |r| next if r.derived next if r.containment next if r.eOpposite && r.eOpposite.containment && xmiLevel(element).nil? next if r.eOpposite && r.many && !r.eOpposite.many targetElements = element.getGenericAsArray(r.name) targetElements.compact! val = targetElements.collect{|te| xmiId(te)}.compact.join(' ') result << [r.name, val] unless val == "" end result end def xmiId(element) if element.respond_to?(:_xmi_id) && element._xmi_id element._xmi_id.to_s else element.object_id.to_s end end def xmiLevel(element) return nil unless element.respond_to?(:_xmi_level) element._xmi_level end end end end rgen-0.7.0/lib/rgen/model_builder/0000755000004100000410000000000012352210062017001 5ustar www-datawww-datargen-0.7.0/lib/rgen/model_builder/builder_context.rb0000644000004100000410000002551712352210062022532 0ustar www-datawww-datarequire 'rgen/ecore/ecore_ext' require 'rgen/model_builder/reference_resolver' module RGen module ModelBuilder class BuilderContext attr_reader :toplevelElements def initialize(package, extensionsModule, resolver, env=nil) package = package.ecore unless package.is_a?(RGen::ECore::EPackage) raise "First argument must be a metamodel package" \ unless package.is_a?(RGen::ECore::EPackage) @rootPackage, @env = package, env @commandResolver = CommandResolver.new(package, extensionsModule, self) @package = @rootPackage @resolver = resolver @contextStack = [] @toplevelElements = [] @helperNames = {} end def const_missing_delegated(delegator, const) ConstPathElement.new(const, self) end # in Ruby 1.9.0 and 1.9.1 #instance_eval looks up constants in the calling scope # that's why const_missing needs to be prepared in BuilderContext, too class << self def currentBuilderContext=(bc) @@currentBuilderContext = bc end def const_missing(name) if @@currentBuilderContext ConstPathElement.new(name, @@currentBuilderContext) else super end end end class CommandResolver def initialize(rootPackage, extensionsModule, builderContext) @extensionFactory = ExtensionContainerFactory.new(rootPackage, extensionsModule, builderContext) @packageResolver = PackageResolver.new(rootPackage, @extensionFactory) @resolveCommand = {} end def resolveCommand(cmd, parentPackage) return @resolveCommand[[parentPackage, cmd]] if @resolveCommand.has_key?([parentPackage, cmd]) package = @packageResolver.packageByCommand(parentPackage, cmd) result = nil if package extensionContainer = @extensionFactory.extensionContainer(package) if extensionContainer.respond_to?(cmd) result = extensionContainer else className = cmd.to_s[0..0].upcase + cmd.to_s[1..-1] result = package.eClasses.find{|c| c.name == className} end end @resolveCommand[[parentPackage, cmd]] = [package, result] end end def method_missing(m, *args, &block) package, classOrContainer = @commandResolver.resolveCommand(m, @package) return super if package.nil? return classOrContainer.send(m, *args, &block) if classOrContainer.is_a?(ExtensionContainerFactory::ExtensionContainer) eClass = classOrContainer nameArg, argHash = self.class.processArguments(args) internalName = nameArg || argHash[:name] argHash[:name] ||= nameArg if nameArg && self.class.hasNameAttribute(eClass) resolverJobs, asRole, helperName = self.class.filterArgHash(argHash, eClass) element = eClass.instanceClass.new(argHash) @resolver.setElementName(element, internalName) @env << element if @env contextElement = @contextStack.last if contextElement self.class.associateWithContextElement(element, contextElement, asRole) else @toplevelElements << element end resolverJobs.each do |job| job.receiver = element job.namespace = contextElement @resolver.addJob(job) end # process block if block @contextStack.push(element) @package, oldPackage = package, @package instance_eval(&block) @package = oldPackage @contextStack.pop end element end def _using(constPathElement, &block) @package, oldPackage = self.class.resolvePackage(@package, @rootPackage, constPathElement.constPath), @package instance_eval(&block) @package = oldPackage end def _context(depth=1) @contextStack[-depth] end class ExtensionContainerFactory class ExtensionContainer def initialize(builderContext) @builderContext = builderContext end def method_missing(m, *args, &block) @builderContext.send(m, *args, &block) end end def initialize(rootPackage, extensionsModule, builderContext) @rootPackage, @extensionsModule, @builderContext = rootPackage, extensionsModule, builderContext @extensionContainer = {} end def moduleForPackage(package) qName = package.qualifiedName rqName = @rootPackage.qualifiedName raise "Package #{qName} is not contained within #{rqName}" unless qName.index(rqName) == 0 path = qName.sub(rqName,'').split('::') path.shift if path.first == "" mod = @extensionsModule path.each do |p| if mod && mod.const_defined?(p) mod = mod.const_get(p) else mod = nil break end end mod end def extensionContainer(package) return @extensionContainer[package] if @extensionContainer[package] container = ExtensionContainer.new(@builderContext) extensionModule = moduleForPackage(package) container.extend(extensionModule) if extensionModule @extensionContainer[package] = container end end class PackageResolver def initialize(rootPackage, extensionFactory) @rootPackage = rootPackage @extensionFactory = extensionFactory @packageByCommand = {} end def packageByCommand(contextPackage, name) return @packageByCommand[[contextPackage, name]] if @packageByCommand.has_key?([contextPackage, name]) if @extensionFactory.extensionContainer(contextPackage).respond_to?(name) result = contextPackage else className = name.to_s[0..0].upcase + name.to_s[1..-1] eClass = contextPackage.eClasses.find{|c| c.name == className} if eClass result = contextPackage elsif contextPackage != @rootPackage result = packageByCommand(contextPackage.eSuperPackage, name) else result = nil end end @packageByCommand[[contextPackage, name]] = result end end class ConstPathElement < Module def initialize(name, builderContext, parent=nil) @name = name.to_s @builderContext = builderContext @parent = parent end def const_missing(const) ConstPathElement.new(const, @builderContext, self) end def method_missing(m, *args, &block) @builderContext._using(self) do send(m, *args, &block) end end def constPath if @parent @parent.constPath << @name else [@name] end end end # helper methods put in the class object to be out of the way of # method evaluation in the builder context class << self class PackageNotFoundException < Exception end def resolvePackage(contextPackage, rootPackage, path) begin return resolvePackageDownwards(contextPackage, path) rescue PackageNotFoundException if contextPackage.eSuperPackage && contextPackage != rootPackage return resolvePackage(contextPackage.eSuperPackage, rootPackage, path) else raise end end end def resolvePackageDownwards(contextPackage, path) first, *rest = path package = contextPackage.eSubpackages.find{|p| p.name == first} raise PackageNotFoundException.new("Could not resolve package: #{first} is not a subpackage of #{contextPackage.name}") unless package if rest.empty? package else resolvePackageDownwards(package, rest) end end def processArguments(args) unless (args.size == 2 && args.first.is_a?(String) && args.last.is_a?(Hash)) || (args.size == 1 && (args.first.is_a?(String) || args.first.is_a?(Hash))) || args.size == 0 raise "Provide a Hash to set feature values, " + "optionally the first argument may be a String specifying " + "the value of the \"name\" attribute." end if args.last.is_a?(Hash) argHash = args.last else argHash = {} end nameArg = args.first if args.first.is_a?(String) [nameArg, argHash] end def filterArgHash(argHash, eClass) resolverJobs = [] asRole, helperName = nil, nil refByName = {} eAllReferences(eClass).each {|r| refByName[r.name] = r} argHash.each_pair do |k,v| if k == :as asRole = v argHash.delete(k) elsif k == :name && !hasNameAttribute(eClass) helperName = v argHash.delete(k) elsif v.is_a?(String) ref = refByName[k.to_s]#eAllReferences(eClass).find{|r| r.name == k.to_s} if ref argHash.delete(k) resolverJobs << ReferenceResolver::ResolverJob.new(nil, ref, nil, v) end elsif v.is_a?(Array) ref = refByName[k.to_s] #eAllReferences(eClass).find{|r| r.name == k.to_s} ref && v.dup.each do |e| if e.is_a?(String) v.delete(e) resolverJobs << ReferenceResolver::ResolverJob.new(nil, ref, nil, e) end end end end [ resolverJobs, asRole, helperName ] end def hasNameAttribute(eClass) @hasNameAttribute ||= {} @hasNameAttribute[eClass] ||= eClass.eAllAttributes.any?{|a| a.name == "name"} end def eAllReferences(eClass) @eAllReferences ||= {} @eAllReferences[eClass] ||= eClass.eAllReferences end def containmentRefs(contextClass, eClass) @containmentRefs ||= {} @containmentRefs[[contextClass, eClass]] ||= eAllReferences(contextClass).select do |r| r.containment && (eClass.eAllSuperTypes << eClass).include?(r.eType) end end def associateWithContextElement(element, contextElement, asRole) return unless contextElement contextClass = contextElement.class.ecore if asRole asRoleRef = eAllReferences(contextClass).find{|r| r.name == asRole.to_s} raise "Context class #{contextClass.name} has no reference named #{asRole}" unless asRoleRef ref = asRoleRef else possibleContainmentRefs = containmentRefs(contextClass, element.class.ecore) if possibleContainmentRefs.size == 1 ref = possibleContainmentRefs.first elsif possibleContainmentRefs.size == 0 raise "Context class #{contextClass.name} can not contain a #{element.class.ecore.name}" else raise "Context class #{contextClass.name} has several containment references to a #{element.class.ecore.name}." + " Clearify using \":as => \"" end end if ref.many contextElement.addGeneric(ref.name, element) else contextElement.setGeneric(ref.name, element) end end end end end end rgen-0.7.0/lib/rgen/model_builder/model_serializer.rb0000644000004100000410000001730612352210062022666 0ustar www-datawww-datarequire 'rgen/array_extensions' require 'rgen/ecore/ecore_ext' module RGen module ModelBuilder class ModelSerializer def initialize(writable, rootPackage) @writable = writable @currentPackage = rootPackage @qualifiedElementName = {} @internalElementName = {} @relativeQualifiedElementName = {} end def serialize(elements) calcQualifiedElementNames(elements) unifyQualifiedElementNames elements = [elements] unless elements.is_a?(Enumerable) elements.each do |e| serializeElement(e) end end private def serializeElement(element, viaRef=nil, namePath=[], indent=0) className = element.class.ecore.name cmd = className[0..0].downcase+className[1..-1] args = ["\"#{@internalElementName[element]}\""] namePath = namePath + [@internalElementName[element]] childs = [] eAllStructuralFeatures(element).each do |f| next if f.derived if f.is_a?(RGen::ECore::EAttribute) next if f.name == "name" && element.name == @internalElementName[element] val = element.getGeneric(f.name) #puts f.defaultValue.inspect if f.name == "isRoot" args << ":#{f.name} => #{serializeAttribute(val)}" unless val == f.defaultValue || val.nil? elsif !f.containment next if f.eOpposite && f.eOpposite == viaRef val = element.getGeneric(f.name) refString = serializeReference(element, f, val) args << ":#{f.name} => #{refString}" if refString else cs = element.getGeneric(f.name) refString = nil if cs.is_a?(Array) cs.compact! rcs = cs.select{|c| serializeChild?(c, namePath)} childs << [f, rcs] unless rcs.empty? refString = serializeReference(element, f, cs-rcs) else if cs && serializeChild?(cs, namePath) childs << [f, [cs]] else refString = serializeReference(element, f, cs) end end args << ":#{f.name} => #{refString}" if refString end end args << ":as => :#{viaRef.name}" if viaRef && containmentRefs(viaRef.eContainingClass, element.class.ecore).size > 1 cmd = elementPackage(element)+"."+cmd if elementPackage(element).size > 0 @writable.write " " * indent + cmd + " " + args.join(", ") if childs.size > 0 @writable.write " do\n" oldPackage, @currentPackage = @currentPackage, element.class.ecore.ePackage childs.each do |pair| f, cs = pair cs.each {|c| serializeElement(c, f, namePath, indent+1) } end @currentPackage = oldPackage @writable.write " " * indent + "end\n" else @writable.write "\n" end end def serializeChild?(child, namePath) @qualifiedElementName[child][0..-2] == namePath end def serializeAttribute(value) if value.is_a?(String) "\"#{value.gsub("\"","\\\"")}\"" elsif value.is_a?(Symbol) ":#{value}" elsif value.nil? "nil" else value.to_s end end def serializeReference(element, ref, value) if value.is_a?(Array) value = value.compact value = value.select{|v| compareWithOppositeReference(ref, element, v) > 0} if ref.eOpposite qualNames = value.collect do |v| relativeQualifiedElementName(v, element).join(".") end !qualNames.empty? && ("[" + qualNames.collect { |v| "\"#{v}\"" }.join(", ") + "]") elsif value && (!ref.eOpposite || compareWithOppositeReference(ref, element, value) > 0) qualName = relativeQualifiedElementName(value, element).join(".") ("\"#{qualName}\"") end end # descide which part of a bidirectional reference get serialized def compareWithOppositeReference(ref, element, target) result = 0 # first try to make the reference from the many side to the one side result = -1 if ref.many && !ref.eOpposite.many result = 1 if !ref.many && ref.eOpposite.many return result if result != 0 # for 1:1 or many:many perfer, shorter references result = relativeQualifiedElementName(element, target).size <=> relativeQualifiedElementName(target, element).size return result if result != 0 # there just needs to be a descision, use class name or object_id result = element.class.name <=> target.class.name return result if result != 0 element.object_id <=> target.object_id end def elementPackage(element) @elementPackage ||= {} return @elementPackage[element] if @elementPackage[element] eNames = element.class.ecore.ePackage.qualifiedName.split("::") rNames = @currentPackage.qualifiedName.split("::") while eNames.first == rNames.first && !eNames.first.nil? eNames.shift rNames.shift end @elementPackage[element] = eNames.join("::") end def relativeQualifiedElementName(element, context) return @relativeQualifiedElementName[[element, context]] if @relativeQualifiedElementName[[element, context]] # elements which are not in the @qualifiedElementName Hash are not in the scope # of this serialization and will be ignored return [] if element.nil? || @qualifiedElementName[element].nil? return [] if context.nil? || @qualifiedElementName[context].nil? eNames = @qualifiedElementName[element].dup cNames = @qualifiedElementName[context].dup while eNames.first == cNames.first && eNames.size > 1 eNames.shift cNames.shift end @relativeQualifiedElementName[[element, context]] = eNames end def calcQualifiedElementNames(elements, prefix=[], takenNames=[]) elements = [elements] unless elements.is_a?(Array) elements.compact! elements.each do |element| qualifiedNamePath = prefix + [calcInternalElementName(element, takenNames)] @qualifiedElementName[element] ||= [] @qualifiedElementName[element] << qualifiedNamePath takenChildNames = [] eAllStructuralFeatures(element).each do |f| if f.is_a?(RGen::ECore::EReference) && f.containment childs = element.getGeneric(f.name) calcQualifiedElementNames(childs, qualifiedNamePath, takenChildNames) end end end end def unifyQualifiedElementNames @qualifiedElementName.keys.each do |k| @qualifiedElementName[k] = @qualifiedElementName[k].sort{|a,b| a.size <=> b.size}.first end end def calcInternalElementName(element, takenNames) return @internalElementName[element] if @internalElementName[element] name = if element.respond_to?(:name) && element.name && !element.name.empty? element.name else nextElementHelperName(element) end while takenNames.include?(name) name = nextElementHelperName(element) end takenNames << name @internalElementName[element] = name end def nextElementHelperName(element) eClass = element.class.ecore @nextElementNameId ||= {} @nextElementNameId[eClass] ||= 1 result = "_#{eClass.name}#{@nextElementNameId[eClass]}" @nextElementNameId[eClass] += 1 result end def eAllStructuralFeatures(element) @eAllStructuralFeatures ||= {} @eAllStructuralFeatures[element.class] ||= element.class.ecore.eAllStructuralFeatures end def eAllReferences(eClass) @eAllReferences ||= {} @eAllReferences[eClass] ||= eClass.eAllReferences end def containmentRefs(contextClass, eClass) @containmentRefs ||= {} @containmentRefs[[contextClass, eClass]] ||= eAllReferences(contextClass).select do |r| r.containment && (eClass.eAllSuperTypes << eClass).include?(r.eType) end end end end end rgen-0.7.0/lib/rgen/model_builder/reference_resolver.rb0000644000004100000410000001050312352210062023204 0ustar www-datawww-datarequire 'rgen/array_extensions' module RGen module ModelBuilder class ReferenceResolver ResolverJob = Struct.new(:receiver, :reference, :namespace, :string) class ResolverException < Exception end class ToplevelNamespace def initialize(ns) raise "Namespace must be an Enumerable" unless ns.is_a?(Enumerable) @ns = ns end def elements @ns end end def initialize @jobs = [] @elementName = {} end def addJob(job) @jobs << job end def setElementName(element, name) @elementName[element] = name end def resolve(ns=[]) @toplevelNamespace = ToplevelNamespace.new(ns) (@jobs || []).each_with_index do |job, i| target = resolveReference(job.namespace || @toplevelNamespace, job.string.split(".")) raise ResolverException.new("Can not resolve reference #{job.string}") unless target if job.reference.many job.receiver.addGeneric(job.reference.name, target) else job.receiver.setGeneric(job.reference.name, target) end end end private # TODO: if a reference can not be fully resolved, but a prefix can be found, # the exception reported is that its first path element can not be found on # toplevel def resolveReference(namespace, nameParts) element = resolveReferenceDownwards(namespace, nameParts) if element.nil? && parentNamespace(namespace) element = resolveReference(parentNamespace(namespace), nameParts) end element end def resolveReferenceDownwards(namespace, nameParts) firstPart, *restParts = nameParts element = namespaceElementByName(namespace, firstPart) return nil unless element if restParts.size > 0 resolveReferenceDownwards(element, restParts) else element end end def namespaceElementByName(namespace, name) @namespaceElementsByName ||= {} return @namespaceElementsByName[namespace][name] if @namespaceElementsByName[namespace] hash = {} namespaceElements(namespace).each do |e| raise ResolverException.new("Multiple elements named #{elementName(e)} found in #{nsToS(namespace)}") if hash[elementName(e)] hash[elementName(e)] = e if elementName(e) end @namespaceElementsByName[namespace] = hash hash[name] end def parentNamespace(namespace) if namespace.class.respond_to?(:ecore) parents = elementParents(namespace) raise ResolverException.new("Element #{nsToS(namespace)} has multiple parents") \ if parents.size > 1 parents.first || @toplevelNamespace else nil end end def namespaceElements(namespace) if namespace.is_a?(ToplevelNamespace) namespace.elements elsif namespace.class.respond_to?(:ecore) elementChildren(namespace) else raise ResolverException.new("Element #{nsToS(namespace)} can not be used as a namespace") end end def nsToS(namespace) if namespace.is_a?(ToplevelNamespace) "toplevel namespace" else result = namespace.class.name result += ":\"#{elementName(namespace)}\"" if elementName(namespace) result end end def elementName(element) @elementName[element] end def elementChildren(element) @elementChildren ||= {} return @elementChildren[element] if @elementChildren[element] children = containmentRefs(element).collect do |r| element.getGeneric(r.name) end.flatten.compact @elementChildren[element] = children end def elementParents(element) @elementParents ||= {} return @elementParents[element] if @elementParents[element] parents = parentRefs(element).collect do |r| element.getGeneric(r.name) end.flatten.compact @elementParents[element] = parents end def containmentRefs(element) @containmentRefs ||= {} @containmentRefs[element.class] ||= eAllReferences(element).select{|r| r.containment} end def parentRefs(element) @parentRefs ||= {} @parentRefs[element.class] ||= eAllReferences(element).select{|r| r.eOpposite && r.eOpposite.containment} end def eAllReferences(element) @eAllReferences ||= {} @eAllReferences[element.class] ||= element.class.ecore.eAllReferences end end end endrgen-0.7.0/lib/rgen/instantiator/0000755000004100000410000000000012352210062016712 5ustar www-datawww-datargen-0.7.0/lib/rgen/instantiator/ecore_xml_instantiator.rb0000644000004100000410000001212512352210062024014 0ustar www-datawww-datarequire 'rgen/ecore/ecore' require 'rgen/instantiator/abstract_xml_instantiator' require 'rgen/array_extensions' class ECoreXMLInstantiator < AbstractXMLInstantiator include RGen::ECore INFO = 0 WARN = 1 ERROR = 2 def initialize(env, loglevel=ERROR) @env = env @rolestack = [] @elementstack = [] @element_by_id = {} @loglevel = loglevel end def start_tag(prefix, tag, namespaces, attributes) eRef = nil if @elementstack.last eRef = eAllReferences(@elementstack.last).find{|r|r.name == tag} if eRef if attributes["xsi:type"] && attributes["xsi:type"] =~ /ecore:(\w+)/ class_name = $1 attributes.delete("xsi:type") else class_name = eRef.eType.name end else raise "Reference not found: #{tag} on #{@elementstack.last}" end else class_name = tag end eClass = RGen::ECore.ecore.eClassifiers.find{|c| c.name == class_name} if eClass obj = RGen::ECore.const_get(class_name).new if attributes["xmi:id"] @element_by_id[attributes["xmi:id"]] = obj attributes.delete("xmi:id") end if eRef if eRef.many @elementstack.last.addGeneric(eRef.name, obj) else @elementstack.last.setGeneric(eRef.name, obj) end end @env << obj @elementstack.push obj else log WARN, "Class not found: #{class_name}" @elementstack.push nil end attributes.each_pair do |attr, value| set_attribute_internal(attr, value) end end def end_tag(prefix, tag) @elementstack.pop end ResolverDescription = Struct.new(:object, :attribute, :value) def set_attribute(attr, value) # do nothing, already handled by start_tag/set_attribute_internal end def set_attribute_internal(attr, value) return unless @elementstack.last eFeat = eAllStructuralFeatures(@elementstack.last).find{|a| a.name == attr} if eFeat.is_a?(EReference) rd = ResolverDescription.new rd.object = @elementstack.last rd.attribute = attr rd.value = value @resolver_descs << rd elsif eFeat value = true if value == "true" && eFeat.eType == EBoolean value = false if value == "false" && eFeat.eType == EBoolean value = value.to_i if eFeat.eType == EInt || eFeat.eType == ELong @elementstack.last.setGeneric(attr, value) else log WARN, "Feature not found: #{attr} on #{@elementstack.last}" end end def instantiate(str) @resolver_descs = [] # puts "Instantiating ..." super(str, 1000) rootpackage = @env.find(:class => EPackage).first # puts "Resolving ..." @resolver_descs.each do |rd| refed = find_referenced(rootpackage, rd.value) feature = eAllStructuralFeatures(rd.object).find{|f| f.name == rd.attribute} raise StandardError.new("StructuralFeature not found: #{rd.attribute}") unless feature if feature.many rd.object.setGeneric(feature.name, refed) else rd.object.setGeneric(feature.name, refed.first) end end end def eAllReferences(element) @eAllReferences ||= {} @eAllReferences[element.class] ||= element.class.ecore.eAllReferences end def eAllAttributes(element) @eAllAttributes ||= {} @eAllAttributes[element.class] ||= element.class.ecore.eAllAttributes end def eAllStructuralFeatures(element) @eAllStructuralFeatures ||= {} @eAllStructuralFeatures[element.class] ||= element.class.ecore.eAllStructuralFeatures end def find_referenced(context, desc) desc.split(/\s+/).collect do |r| if r =~ /^#([^\/]+)$/ @element_by_id[$1] elsif r =~ /^#\/\d*\/([\w\/]+)/ find_in_context(context, $1.split('/')) elsif r =~ /#\/\/(\w+)$/ case $1 when "EString"; RGen::ECore::EString when "EInt"; RGen::ECore::EInt when "ELong"; RGen::ECore::ELong when "EBoolean"; RGen::ECore::EBoolean when "EFloat"; RGen::ECore::EFloat when "EJavaObject"; RGen::ECore::EJavaObject when "EJavaClass"; RGen::ECore::EJavaClass end end end.compact end def find_in_context(context, desc_elements) if context.is_a?(EPackage) r = (context.eClassifiers + context.eSubpackages).find{|c| c.name == desc_elements.first} elsif context.is_a?(EClass) r = context.eStructuralFeatures.find{|s| s.name == desc_elements.first} else raise StandardError.new("Don't know how to find #{desc_elements.join('/')} in context #{context}") end if r if desc_elements.size > 1 find_in_context(r, desc_elements[1..-1]) else r end else log WARN, "Can not follow path, element #{desc_elements.first} not found within #{context}(#{context.name})" end end def log(level, msg) puts %w(INFO WARN ERROR)[level] + ": " + msg if level >= @loglevel end end rgen-0.7.0/lib/rgen/instantiator/abstract_xml_instantiator.rb0000644000004100000410000000376012352210062024527 0ustar www-datawww-datarequire 'nokogiri' class AbstractXMLInstantiator class Visitor < Nokogiri::XML::SAX::Document def initialize(inst, gcSuspendCount) @instantiator = inst @gcSuspendCount = gcSuspendCount @namespaces = {} end def start_element_namespace(tag, attributes, prefix, uri, ns) controlGC ns.each{|n| @namespaces[n[0]] = n[1]} attrs = attributes.collect{|a| [a.prefix ? a.prefix+":"+a.localname : a.localname, a.value]} @instantiator.start_tag(prefix, tag, @namespaces, Hash[*(attrs.flatten)]) attrs.each { |pair| @instantiator.set_attribute(pair[0], pair[1]) } end def end_element_namespace(tag, prefix, uri) @instantiator.end_tag(prefix, tag) end def characters(str) @instantiator.text(str) end def controlGC return unless @gcSuspendCount > 0 @gcCounter ||= 0 @gcCounter += 1 if @gcCounter == @gcSuspendCount @gcCounter = 0 GC.enable ObjectSpace.garbage_collect GC.disable end end end # Parses str and calls start_tag, end_tag, set_attribute and text methods of a subclass. # # If gcSuspendCount is specified, the garbage collector will be disabled for that # number of start or end tags. After that period it will clean up and then be disabled again. # A value of about 1000 can significantly improve overall performance. # The memory usage normally does not increase. # Depending on the work done for every xml tag the value might have to be adjusted. # def instantiate(str, gcSuspendCount=0) gcDisabledBefore = GC.disable gcSuspendCount = 0 if gcDisabledBefore begin visitor = Visitor.new(self, gcSuspendCount) parser = Nokogiri::XML::SAX::Parser.new(visitor) parser.parse(str) do |ctx| @parserContext = ctx end ensure GC.enable unless gcDisabledBefore end end def text(str) end end rgen-0.7.0/lib/rgen/instantiator/qualified_name_resolver.rb0000644000004100000410000000554512352210062024134 0ustar www-datawww-datarequire 'rgen/instantiator/reference_resolver' module RGen module Instantiator # This is a resolver resolving element identifiers which are qualified names. class QualifiedNameResolver attr_reader :nameAttribute attr_reader :separator attr_reader :leadingSeparator def initialize(rootElements, options={}) @rootElements = rootElements @nameAttribute = options[:nameAttribute] || "name" @separator = options[:separator] || "/" @leadingSeparator = options.has_key?(:leadingSeparator) ? options[:leadingSeparator] : true @elementByQName = {} @visitedQName = {} @childReferences = {} @resolverDelegate = ReferenceResolver.new(:identifier_resolver => method(:resolveIdentifier)) end def resolveIdentifier(qualifiedName) return @elementByQName[qualifiedName] if @elementByQName.has_key?(qualifiedName) path = qualifiedName.split(separator).reject{|s| s == ""} if path.size > 1 parentQName = (leadingSeparator ? separator : "") + path[0..-2].join(separator) parents = resolveIdentifier(parentQName) parents = [parents].compact unless parents.is_a?(Array) children = parents.collect{|p| allNamedChildren(p)}.flatten elsif path.size == 1 parentQName = "" children = allRootNamedChildren else return @elementByQName[qualifiedName] = nil end # if the parent was already visited all matching elements are the hash if !@visitedQName[parentQName] children.each do |c| name = c.send(nameAttribute) if name qname = parentQName + ((parentQName != "" || leadingSeparator) ? separator : "") + name existing = @elementByQName[qname] if existing @elementByQName[qname] = [existing] unless existing.is_a?(Array) @elementByQName[qname] << c else @elementByQName[qname] = c end end end # all named children of praent have been checked and hashed @visitedQName[parentQName] = true end @elementByQName[qualifiedName] ||= nil end def resolveReferences(unresolvedReferences, problems=[]) @resolverDelegate.resolve(unresolvedReferences, :problems => problems) end private def allNamedChildren(element) childReferences(element.class).collect do |r| element.getGenericAsArray(r.name).collect do |c| if c.respond_to?(nameAttribute) c else allNamedChildren(c) end end end.flatten end def allRootNamedChildren @rootElements.collect do |e| if e.respond_to?(nameAttribute) e else allNamedChildren(e) end end.flatten end def childReferences(clazz) @childReferences[clazz] ||= clazz.ecore.eAllReferences.select{|r| r.containment} end end end end rgen-0.7.0/lib/rgen/instantiator/default_xml_instantiator.rb0000644000004100000410000000563012352210062024346 0ustar www-datawww-datarequire 'rgen/instantiator/nodebased_xml_instantiator' module RGen module Instantiator # A default XML instantiator. # Derive your own instantiator from this class or use it as is. # class DefaultXMLInstantiator < NodebasedXMLInstantiator include Util::NameHelper NamespaceDescriptor = Struct.new(:prefix, :target) class << self def map_tag_ns(from, to, prefix="") tag_ns_map[from] = NamespaceDescriptor.new(prefix, to) end def tag_ns_map # :nodoc: @tag_ns_map ||={} @tag_ns_map end end def initialize(env, default_module, create_mm=false) super(env) @default_module = default_module @create_mm = create_mm end def on_descent(node) obj = new_object(node) @env << obj unless obj.nil? node.object = obj node.attributes.each_pair { |k,v| set_attribute(node, k, v) } end def on_ascent(node) node.children.each { |c| assoc_p2c(node, c) } node.object.class.has_attr 'chardata', Object unless node.object.respond_to?(:chardata) set_attribute(node, "chardata", node.chardata) end def class_name(str) saneClassName(str) end def new_object(node) ns_desc = self.class.tag_ns_map[node.namespace] class_name = class_name(ns_desc.nil? ? node.qtag : ns_desc.prefix+node.tag) mod = (ns_desc && ns_desc.target) || @default_module build_on_error(NameError, :build_class, class_name, mod) do mod.const_get(class_name).new end end def build_class(name, mod) mod.const_set(name, Class.new(RGen::MetamodelBuilder::MMBase)) end def method_name(str) saneMethodName(str) end def assoc_p2c(parent, child) return unless parent.object && child.object method_name = method_name(className(child.object)) build_on_error(NoMethodError, :build_p2c_assoc, parent, child, method_name) do parent.object.addGeneric(method_name, child.object) child.object.setGeneric("parent", parent.object) end end def build_p2c_assoc(parent, child, method_name) parent.object.class.has_many(method_name, child.object.class) child.object.class.has_one("parent", RGen::MetamodelBuilder::MMBase) end def set_attribute(node, attr, value) return unless node.object build_on_error(NoMethodError, :build_attribute, node, attr, value) do node.object.setGeneric(method_name(attr), value) end end def build_attribute(node, attr, value) node.object.class.has_attr(method_name(attr)) end protected # Helper method for implementing classes. # This method yields the given block. # If the metamodel should be create automatically (see constructor) # rescues +error+ and calls +builder_method+ with +args+, then # yields the block again. def build_on_error(error, builder_method, *args) begin yield rescue error if @create_mm send(builder_method, *args) yield else raise end end end end end end rgen-0.7.0/lib/rgen/instantiator/json_instantiator.rb0000644000004100000410000001015412352210062023010 0ustar www-datawww-datarequire 'rgen/instantiator/qualified_name_resolver' require 'rgen/instantiator/json_parser' module RGen module Instantiator # JsonInstantiator is used to create RGen models from JSON. # # Each JSON object needs to have an attribute "_class" which is used to find # the metamodel class to instantiate. The value of "_class" should be the # the relative qualified class name within the root package as a string. # # If the option "short_class_names" is set to true, unqualified class names can be used. # In this case, metamodel classes are searched in the metamodel root package first. # If this search is not successful, all subpackages will be searched for the class name. # class JsonInstantiator # Model elements will be created in evironment +env+, # classes are looked for in metamodel package module +mm+, # +options+ include: # short_class_names: if true subpackages will be searched for unqualifed class names (default: true) # ignore_keys: an array of json object key names which are to be ignored (default: none) # # The options are also passed to the underlying QualifiedNameResolver. # def initialize(env, mm, options={}) @env = env @mm = mm @options = options @short_class_names = !@options.has_key?(:short_class_names) || @options[:short_class_names] @ignore_keys = @options[:ignore_keys] || [] @unresolvedReferences = [] @classes = {} @classes_flat = {} mm.ecore.eAllClasses.each do |c| @classes[c.instanceClass.name.sub(mm.name+"::","")] = c @classes_flat[c.name] = c end @parser = JsonParser.new(self) end # Creates the elements described by the json string +str+. # Returns an array of ReferenceResolver::UnresolvedReference # describing the references which could not be resolved # # Options: # :root_elements: if an array is provided, it will be filled with the root elements # def instantiate(str, options={}) root = @parser.parse(str) if options[:root_elements].is_a?(Array) options[:root_elements].clear root.each{|r| options[:root_elements] << r} end resolver = QualifiedNameResolver.new(root, @options) resolver.resolveReferences(@unresolvedReferences) end def createObject(hash) className = hash["_class"] # hashes without a _class key are returned as is return hash unless className if @classes[className] clazz = @classes[className].instanceClass elsif @short_class_names && @classes_flat[className] clazz = @classes_flat[className].instanceClass else raise "class not found: #{className}" end hash.delete("_class") @ignore_keys.each do |k| hash.delete(k) end urefs = [] hash.keys.each do |k| f = eFeature(k, clazz) hash[k] = [hash[k]] if f.many && !hash[k].is_a?(Array) if f.is_a?(RGen::ECore::EReference) && !f.containment if f.many idents = hash[k] hash[k] = idents.collect do |i| proxy = RGen::MetamodelBuilder::MMProxy.new(i) urefs << ReferenceResolver::UnresolvedReference.new(nil, k, proxy) proxy end else ident = hash[k] ident = ident.first if ident.is_a?(Array) proxy = RGen::MetamodelBuilder::MMProxy.new(ident) hash[k] = proxy urefs << ReferenceResolver::UnresolvedReference.new(nil, k, proxy) end elsif f.eType.is_a?(RGen::ECore::EEnum) hash[k] = hash[k].to_sym elsif f.eType.instanceClassName == "Float" hash[k] = hash[k].to_f end end obj = @env.new(clazz, hash) urefs.each do |r| r.element = obj @unresolvedReferences << r end obj end private def eFeature(name, clazz) @eFeature ||= {} @eFeature[clazz] ||= {} unless @eFeature[clazz][name] feature = clazz.ecore.eAllStructuralFeatures.find{|f| f.name == name} raise "feature '#{name}' not found in class '#{clazz}'" unless feature end @eFeature[clazz][name] ||= feature end end end end rgen-0.7.0/lib/rgen/instantiator/nodebased_xml_instantiator.rb0000644000004100000410000000676212352210062024655 0ustar www-datawww-datarequire 'rgen/metamodel_builder' require 'rgen/instantiator/abstract_instantiator' require 'nokogiri' module RGen module Instantiator class NodebasedXMLInstantiator < AbstractInstantiator class << self # The prune level is the number of parent/children associations which # is kept when the instantiator ascents the XML tree. # If the level is 2, information for the node's children and the childrens' # children will be available as an XMLNodeDescriptor object. # If the level is 0 no pruning will take place, i.e. the whole information # is kept until the end of the instantiation process. 0 is default. def set_prune_level(level) @prune_level = level end def prune_level # :nodoc: @prune_level ||= 0 end end class XMLNodeDescriptor attr_reader :namespace, :qtag, :prefix, :tag, :parent, :attributes, :chardata attr_accessor :object, :children def initialize(ns, qtag, prefix, tag, parent, children, attributes) @namespace, @qtag, @prefix, @tag, @parent, @children, @attributes = ns, qtag, prefix, tag, parent, children, attributes @parent.children << self if @parent @chardata = [] end end class Visitor < Nokogiri::XML::SAX::Document attr_reader :namespaces def initialize(inst) @instantiator = inst @namespaces = {} end def start_element_namespace(tag, attributes, prefix, uri, ns) ns.each{|n| @namespaces[n[0]] = n[1]} attrs = {} attributes.each{|a| attrs[a.prefix ? a.prefix+":"+a.localname : a.localname] = a.value} qname = prefix ? prefix+":"+tag : tag @instantiator.start_element(uri, qname, prefix, tag, attrs) end def end_element(name) @instantiator.end_element end def characters(str) @instantiator.on_chardata(str) end end def initialize(env) super @env = env @stack = [] end def instantiate_file(file) File.open(file) { |f| parse(f.read)} resolve end def instantiate(text) parse(text) resolve end def parse(src) @visitor = Visitor.new(self) parser = Nokogiri::XML::SAX::Parser.new(@visitor) parser.parse(src) @visitor = nil end def start_element(ns, qtag, prefix, tag, attributes) node = XMLNodeDescriptor.new(ns, qtag, prefix, tag, @stack[-1], [], attributes) @stack.push node on_descent(node) end def end_element node = @stack.pop on_ascent(node) prune_children(node, self.class.prune_level - 1) if self.class.prune_level > 0 end def on_chardata(str) node = @stack.last node.chardata << str end # This method is called when the XML parser goes down the tree. # An XMLNodeDescriptor +node+ describes the current node. # Implementing classes must overwrite this method. def on_descent(node) raise "Overwrite this method !" end # This method is called when the XML parser goes up the tree. # An XMLNodeDescriptor +node+ describes the current node. # Implementing classes must overwrite this method. def on_ascent(node) raise "Overwrite this method !" end def namespaces @visitor.namespaces if @visitor end private def prune_children(node, level) if level == 0 node.children = nil else node.children.each { |c| prune_children(c, level-1) } end end end end end rgen-0.7.0/lib/rgen/instantiator/json_parser.rb0000644000004100000410000001562512352210062021575 0ustar www-datawww-data# # DO NOT MODIFY!!!! # This file is automatically generated by racc 1.4.5 # from racc grammer file "json_parser.y". # require 'racc/parser' module RGen module Instantiator class JsonParser < Racc::Parser module_eval <<'..end json_parser.y modeval..id3d5fb611e2', 'json_parser.y', 38 ParserToken = Struct.new(:line, :file, :value) def initialize(instantiator) @instantiator = instantiator end def parse(str, file=nil) @q = [] line = 1 until str.empty? case str when /\A\n/ str = $' line +=1 when /\A\s+/ str = $' when /\A([-+]?\d+\.\d+)/ str = $' @q << [:FLOAT, ParserToken.new(line, file, $1)] when /\A([-+]?\d+)/ str = $' @q << [:INTEGER, ParserToken.new(line, file, $1)] when /\A"((?:[^"\\]|\\"|\\\\|\\[^"\\])*)"/ str = $' sval = $1 sval.gsub!('\\\\','\\') sval.gsub!('\\"','"') sval.gsub!('\\n',"\n") sval.gsub!('\\r',"\r") sval.gsub!('\\t',"\t") sval.gsub!('\\f',"\f") sval.gsub!('\\b',"\b") @q << [:STRING, ParserToken.new(line, file, sval)] when /\A(\{|\}|\[|\]|,|:|true|false)/ str = $' @q << [$1, ParserToken.new(line, file, $1)] else raise "parse error in line #{line} on "+str[0..20].inspect+"..." end end @q.push [false, ParserToken.new(line, file, '$end')] do_parse end def next_token r = @q.shift r end ..end json_parser.y modeval..id3d5fb611e2 ##### racc 1.4.5 generates ### racc_reduce_table = [ 0, 0, :racc_error, 1, 14, :_reduce_1, 3, 16, :_reduce_2, 2, 16, :_reduce_3, 1, 17, :_reduce_4, 3, 17, :_reduce_5, 3, 18, :_reduce_6, 2, 18, :_reduce_7, 1, 19, :_reduce_8, 3, 19, :_reduce_9, 3, 20, :_reduce_10, 1, 15, :_reduce_11, 1, 15, :_reduce_12, 1, 15, :_reduce_13, 1, 15, :_reduce_14, 1, 15, :_reduce_15, 1, 15, :_reduce_16, 1, 15, :_reduce_17 ] racc_reduce_n = 18 racc_shift_n = 29 racc_action_table = [ 3, 16, 17, 7, 22, 8, 21, 10, 11, 1, 2, 3, 12, 23, 7, 24, 8, 25, 10, 11, 1, 2, 3, 20, 15, 7, 17, 8, nil, 10, 11, 1, 2, 3, nil, nil, 7, nil, 8, nil, 10, 11, 1, 2 ] racc_action_check = [ 0, 7, 7, 0, 15, 0, 14, 0, 0, 0, 0, 3, 3, 17, 3, 18, 3, 19, 3, 3, 3, 3, 20, 13, 4, 20, 25, 20, nil, 20, 20, 20, 20, 23, nil, nil, 23, nil, 23, nil, 23, 23, 23, 23 ] racc_action_pointer = [ -2, nil, nil, 9, 24, nil, nil, -5, nil, nil, nil, nil, nil, 19, 3, 4, nil, 5, 9, 13, 20, nil, nil, 31, nil, 19, nil, nil, nil ] racc_action_default = [ -18, -16, -17, -18, -18, -1, -11, -18, -13, -12, -14, -15, -3, -4, -18, -18, -7, -18, -18, -8, -18, -2, 29, -18, -6, -18, -5, -10, -9 ] racc_goto_table = [ 5, 18, 4, 14, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 28, 26, nil, nil, 27 ] racc_goto_check = [ 2, 6, 1, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 6, 4, nil, nil, 2 ] racc_goto_pointer = [ nil, 2, 0, nil, 0, nil, -6, nil ] racc_goto_default = [ nil, nil, 13, 6, nil, 9, nil, 19 ] racc_token_table = { false => 0, Object.new => 1, "[" => 2, "]" => 3, "," => 4, "{" => 5, "}" => 6, :STRING => 7, ":" => 8, :INTEGER => 9, :FLOAT => 10, "true" => 11, "false" => 12 } racc_use_result_var = true racc_nt_base = 13 Racc_arg = [ racc_action_table, racc_action_check, racc_action_default, racc_action_pointer, racc_goto_table, racc_goto_check, racc_goto_default, racc_goto_pointer, racc_nt_base, racc_reduce_table, racc_token_table, racc_shift_n, racc_reduce_n, racc_use_result_var ] Racc_token_to_s_table = [ '$end', 'error', '"["', '"]"', '","', '"{"', '"}"', 'STRING', '":"', 'INTEGER', 'FLOAT', '"true"', '"false"', '$start', 'json', 'value', 'array', 'valueList', 'object', 'memberList', 'member'] Racc_debug_parser = false ##### racc system variables end ##### # reduce 0 omitted module_eval <<'.,.,', 'json_parser.y', 4 def _reduce_1( val, _values, result ) result = val[0] result end .,., module_eval <<'.,.,', 'json_parser.y', 6 def _reduce_2( val, _values, result ) result = val[1] result end .,., module_eval <<'.,.,', 'json_parser.y', 7 def _reduce_3( val, _values, result ) result = [] result end .,., module_eval <<'.,.,', 'json_parser.y', 9 def _reduce_4( val, _values, result ) result = [ val[0] ] result end .,., module_eval <<'.,.,', 'json_parser.y', 10 def _reduce_5( val, _values, result ) result = [ val[0] ] + val[2] result end .,., module_eval <<'.,.,', 'json_parser.y', 12 def _reduce_6( val, _values, result ) result = @instantiator.createObject(val[1]) result end .,., module_eval <<'.,.,', 'json_parser.y', 13 def _reduce_7( val, _values, result ) result = nil result end .,., module_eval <<'.,.,', 'json_parser.y', 15 def _reduce_8( val, _values, result ) result = val[0] result end .,., module_eval <<'.,.,', 'json_parser.y', 16 def _reduce_9( val, _values, result ) result = val[0].merge(val[2]) result end .,., module_eval <<'.,.,', 'json_parser.y', 18 def _reduce_10( val, _values, result ) result = {val[0].value => val[2]} result end .,., module_eval <<'.,.,', 'json_parser.y', 20 def _reduce_11( val, _values, result ) result = val[0] result end .,., module_eval <<'.,.,', 'json_parser.y', 21 def _reduce_12( val, _values, result ) result = val[0] result end .,., module_eval <<'.,.,', 'json_parser.y', 22 def _reduce_13( val, _values, result ) result = val[0].value result end .,., module_eval <<'.,.,', 'json_parser.y', 23 def _reduce_14( val, _values, result ) result = val[0].value.to_i result end .,., module_eval <<'.,.,', 'json_parser.y', 24 def _reduce_15( val, _values, result ) result = val[0].value.to_f result end .,., module_eval <<'.,.,', 'json_parser.y', 25 def _reduce_16( val, _values, result ) result = true result end .,., module_eval <<'.,.,', 'json_parser.y', 26 def _reduce_17( val, _values, result ) result = false result end .,., def _reduce_none( val, _values, result ) result end end # class JsonParser end end rgen-0.7.0/lib/rgen/instantiator/json_parser.y0000644000004100000410000000411312352210062021430 0ustar www-datawww-dataclass JsonParser rule json: value { result = val[0] } array: "[" valueList "]" { result = val[1] } | "[" "]" { result = [] } valueList: value { result = [ val[0] ] } | value "," valueList { result = [ val[0] ] + val[2] } object: "{" memberList "}" { result = @instantiator.createObject(val[1]) } | "{" "}" { result = nil } memberList: member { result = val[0] } | member "," memberList { result = val[0].merge(val[2]) } member: STRING ":" value { result = {val[0].value => val[2]} } value: array { result = val[0] } | object { result = val[0] } | STRING { result = val[0].value } | INTEGER { result = val[0].value.to_i } | FLOAT { result = val[0].value.to_f } | "true" { result = true } | "false" { result = false } end ---- header module RGen module Instantiator ---- inner ParserToken = Struct.new(:line, :file, :value) def initialize(instantiator) @instantiator = instantiator end def parse(str, file=nil) @q = [] line = 1 until str.empty? case str when /\A\n/ str = $' line +=1 when /\A\s+/ str = $' when /\A([-+]?\d+\.\d+)/ str = $' @q << [:FLOAT, ParserToken.new(line, file, $1)] when /\A([-+]?\d+)/ str = $' @q << [:INTEGER, ParserToken.new(line, file, $1)] when /\A"((?:[^"\\]|\\"|\\\\|\\[^"\\])*)"/ str = $' sval = $1 sval.gsub!('\\\\','\\') sval.gsub!('\\"','"') sval.gsub!('\\n',"\n") sval.gsub!('\\r',"\r") sval.gsub!('\\t',"\t") sval.gsub!('\\f',"\f") sval.gsub!('\\b',"\b") @q << [:STRING, ParserToken.new(line, file, sval)] when /\A(\{|\}|\[|\]|,|:|true|false)/ str = $' @q << [$1, ParserToken.new(line, file, $1)] else raise "parse error in line #{line} on "+str[0..20].inspect+"..." end end @q.push [false, ParserToken.new(line, file, '$end')] do_parse end def next_token r = @q.shift r end ---- footer end end rgen-0.7.0/lib/rgen/instantiator/reference_resolver.rb0000644000004100000410000001114412352210062023117 0ustar www-datawww-datarequire 'rgen/instantiator/resolution_helper' module RGen module Instantiator # The ReferenceResolver can be used to resolve unresolved references, i.e. instances # of class UnresolvedReference # # There are two ways how this can be used: # 1. the identifiers and associated model elements are added upfront using +add_identifier+ # 2. register an :identifier_resolver with the constructor, which will be invoked # for every unresolved identifier # class ReferenceResolver # Instances of this class represent information about not yet resolved references. # This consists of the +element+ and metamodel +feature_name+ which hold/is to hold the # reference and the +proxy+ object which is the placeholder for the reference. # If the reference could not be resolved because the target type does not match the # feature type, the flag +target_type_error+ will be set. # class UnresolvedReference attr_reader :feature_name, :proxy attr_accessor :element, :target_type_error def initialize(element, feature_name, proxy) @element = element @feature_name = feature_name @proxy = proxy end end # Create a reference resolver, options: # # :identifier_resolver: # a proc which is called with an identifier and which should return the associated element # in case the identifier is not uniq, the proc may return multiple values # default: lookup element in internal map # def initialize(options={}) @identifier_resolver = options[:identifier_resolver] @identifier_map = {} end # Add an +identifer+ / +element+ pair which will be used for looking up unresolved identifers def add_identifier(ident, element) map_entry = @identifier_map[ident] if map_entry if map_entry.is_a?(Array) map_entry << element else @identifier_map[ident] = [map_entry, element] end else @identifier_map[ident] = element end end # Tries to resolve the given +unresolved_refs+. If resolution is successful, the proxy object # will be removed, otherwise there will be an error description in the problems array. # In case the resolved target element's type is not valid for the given feature, the # +target_type_error+ flag will be set on the unresolved reference. # Returns an array of the references which are still unresolved. Options: # # :problems # an array to which problems will be appended # # :on_resolve # a proc which will be called for every sucessful resolution, receives the unresolved # reference as well as to new target element # # :use_target_type # use the expected target type to narrow the set of possible targets # (i.e. ignore targets with wrong type) # # :failed_resolutions # a Hash which will receive an entry for each failed resolution for which at least one # target element was found (wrong target type, or target not unique). # hash key is the uref, hash value is the target element or the Array of target elements # def resolve(unresolved_refs, options={}) problems = options[:problems] || [] still_unresolved_refs = [] failed_resolutions = options[:failed_resolutions] || {} unresolved_refs.each do |ur| if @identifier_resolver target = @identifier_resolver.call(ur.proxy.targetIdentifier) else target = @identifier_map[ur.proxy.targetIdentifier] end target = [target].compact unless target.is_a?(Array) if options[:use_target_type] feature = ur.element.class.ecore.eAllReferences.find{|r| r.name == ur.feature_name} target = target.select{|e| e.is_a?(feature.eType.instanceClass)} end if target.size == 1 status = ResolutionHelper.set_uref_target(ur, target[0]) if status == :success options[:on_resolve] && options[:on_resolve].call(ur, target[0]) elsif status == :type_error ur.target_type_error = true problems << type_error_message(target[0]) still_unresolved_refs << ur failed_resolutions[ur] = target[0] end elsif target.size > 1 problems << "identifier #{ur.proxy.targetIdentifier} not uniq" still_unresolved_refs << ur failed_resolutions[ur] = target else problems << "identifier #{ur.proxy.targetIdentifier} not found" still_unresolved_refs << ur end end still_unresolved_refs end private def type_error_message(target) "invalid target type #{target.class}" end end end end rgen-0.7.0/lib/rgen/instantiator/abstract_instantiator.rb0000644000004100000410000000327512352210062023650 0ustar www-datawww-datamodule RGen module Instantiator class AbstractInstantiator ResolverDescription = Struct.new(:from, :attribute, :block) # :nodoc: class << self attr_accessor :resolver_descs end def initialize(env) @env = env end # Specifies that +attribute+ should be resolved. If +:class+ is specified, # resolve +attribute+ only for objects of type class. # The block must return the value to which the attribute should be assigned. # The object for which the attribute is to be resolved will be accessible # in the current context within the block. # def self.resolve(attribute, desc=nil, &block) from = (desc.is_a?(Hash) && desc[:class]) self.resolver_descs ||= [] self.resolver_descs << ResolverDescription.new(from, attribute, block) end # Resolves +attribute+ to a model element which has attribute +:id+ set to the # value currently in attribute +:src+ # def self.resolve_by_id(attribute, desc) id_attr = (desc.is_a?(Hash) && desc[:id]) src_attr = (desc.is_a?(Hash) && desc[:src]) raise StandardError.new("No id attribute given.") unless id_attr resolve(attribute) do @env.find(id_attr => @current_object.send(src_attr)).first end end private def method_missing(m, *args) #:nodoc: if @current_object @current_object.send(m) else super end end def resolve self.class.resolver_descs ||= [] self.class.resolver_descs.each { |desc| @env.find(:class => desc.from).each { |e| old_object, @current_object = @current_object, e e.send("#{desc.attribute}=", instance_eval(&desc.block)) if e.respond_to?("#{desc.attribute}=") @current_object = old_object } } end end end endrgen-0.7.0/lib/rgen/instantiator/resolution_helper.rb0000644000004100000410000000207312352210062023003 0ustar www-datawww-datamodule RGen module Instantiator module ResolutionHelper # sets the target of an unresolved reference in the model # returns :type_error if the target is of wrong type, otherwise :success # def self.set_uref_target(uref, target) refs = uref.element.getGeneric(uref.feature_name) if refs.is_a?(Array) index = refs.index(uref.proxy) uref.element.removeGeneric(uref.feature_name, uref.proxy) begin uref.element.addGeneric(uref.feature_name, target, index) rescue StandardError => e if is_type_error?(e) uref.element.addGeneric(uref.feature_name, uref.proxy, index) return :type_error else raise end end else begin # this will replace the proxy uref.element.setGeneric(uref.feature_name, target) rescue StandardError => e if is_type_error?(e) return :type_error else raise end end end :success end def self.is_type_error?(e) e.message =~ /Can not use a .* where a .* is expected/ end end end end rgen-0.7.0/lib/rgen/instantiator/xmi11_instantiator.rb0000644000004100000410000001147712352210062023007 0ustar www-datawww-datarequire 'rgen/ecore/ecore' require 'rgen/instantiator/abstract_xml_instantiator' require 'rgen/array_extensions' class XMI11Instantiator < AbstractXMLInstantiator include RGen::ECore ResolverDescription = Struct.new(:object, :attribute, :value, :many) INFO = 0 WARN = 1 ERROR = 2 def initialize(env, fix_map={}, loglevel=ERROR) @env = env @fix_map = fix_map @loglevel = loglevel @rolestack = [] @elementstack = [] end def add_metamodel(ns, mod) @ns_module_map ||={} @ns_module_map[ns] = mod end def instantiate(str) @resolver_descs = [] @element_by_id = {} super(str, 1000) @resolver_descs.each do |rd| if rd.many newval = rd.value.split(" ").collect{|v| @element_by_id[v]} else newval = @element_by_id[rd.value] end log WARN, "Could not resolve reference #{rd.attribute} on #{rd.object}" unless newval begin rd.object.setGeneric(rd.attribute,newval) rescue Exception log WARN, "Could not set reference #{rd.attribute} on #{rd.object}" end end end def start_tag(prefix, tag, namespaces, attributes) if tag =~ /\w+\.(\w+)/ # XMI role role_name = map_feature_name($1) || $1 eRef = @elementstack.last && eAllReferences(@elementstack.last).find{|r|r.name == role_name} log WARN, "No reference found for #{role_name} on #{@elementstack.last}" unless eRef @rolestack.push eRef elsif attributes["xmi.idref"] # reference rd = ResolverDescription.new rd.object = @elementstack.last rd.attribute = @rolestack.last.name rd.value = attributes["xmi.idref"] rd.many = @rolestack.last.many @resolver_descs << rd @elementstack.push nil else # model element value = map_tag(tag, attributes) || tag if value.is_a?(String) mod = @ns_module_map[namespaces[prefix]] unless mod log WARN, "Ignoring tag #{tag}" return end value = mod.const_get(value).new end @env << value eRef = @rolestack.last if eRef && eRef.many @elementstack.last.addGeneric(eRef.name, value) elsif eRef @elementstack.last.setGeneric(eRef.name, value) end @elementstack.push value end end def end_tag(prefix, tag) if tag =~ /\w+\.(\w+)/ @rolestack.pop else @elementstack.pop end end def set_attribute(attr, value) return unless @elementstack.last if attr == "xmi.id" @element_by_id[value] = @elementstack.last else attr_name = map_feature_name(attr) || attr eFeat = eAllStructuralFeatures(@elementstack.last).find{|a| a.name == attr_name} unless eFeat log WARN, "No structural feature found for #{attr_name} on #{@elementstack.last}" return end if eFeat.is_a?(RGen::ECore::EReference) if map_feature_value(attr_name, value).is_a?(eFeat.eType.instanceClass) @elementstack.last.setGeneric(attr_name, map_feature_value(attr_name, value)) else rd = ResolverDescription.new rd.object = @elementstack.last rd.attribute = attr_name rd.value = value rd.many = eFeat.many @resolver_descs << rd end else value = map_feature_value(attr_name, value) || value value = true if value == "true" && eFeat.eType == EBoolean value = false if value == "false" && eFeat.eType == EBoolean value = value.to_i if eFeat.eType == EInt || eFeat.eType == ELong value = value.to_f if eFeat.eType == EFloat value = value.to_sym if eFeat.eType.is_a?(EEnum) @elementstack.last.setGeneric(attr_name, value) end end end private def map_tag(tag, attributes) tag_map = @fix_map[:tags] || {} value = tag_map[tag] if value.is_a?(Proc) value.call(tag, attributes) else value end end def map_feature_name(name) name_map = @fix_map[:feature_names] || {} name_map[name] end def map_feature_value(attr_name, value) value_map = @fix_map[:feature_values] || {} map = value_map[attr_name] if map.is_a?(Hash) map[value] elsif map.is_a?(Proc) map.call(value) end end def log(level, msg) puts %w(INFO WARN ERROR)[level] + ": " + msg if level >= @loglevel end def eAllReferences(element) @eAllReferences ||= {} @eAllReferences[element.class] ||= element.class.ecore.eAllReferences end def eAllStructuralFeatures(element) @eAllStructuralFeatures ||= {} @eAllStructuralFeatures[element.class] ||= element.class.ecore.eAllStructuralFeatures end end rgen-0.7.0/lib/rgen/array_extensions.rb0000644000004100000410000000302412352210062020114 0ustar www-datawww-data# RGen Framework # (c) Martin Thiede, 2006 require 'rgen/metamodel_builder' class Array def >>(method) compact.inject([]) { |r,e| r | ( (o=e.send(method)).is_a?(Array) ? o : [o] ) } end def method_missing(m, *args) # This extensions has the side effect that it allows to call any method on any # empty array with an empty array as the result. This behavior is required for # navigating models. # # This is a problem for Hash[] called with an (empty) array of tupels. # It will call to_hash expecting a Hash as the result. When it gets an array instead, # it fails with an exception. Make sure it gets a NoMethodException as without this # extension and it will catch that and return an empty hash as expected. # # Similar problems exist for other Ruby built-in methods which are expected to fail. # return super unless (size == 0 && m != :to_hash && m != :to_str) || compact.any?{|e| e.is_a? RGen::MetamodelBuilder::MMBase} # use an array to build the result to achiev similar ordering result = [] inResult = {} compact.each do |e| if e.is_a? RGen::MetamodelBuilder::MMBase ((o=e.send(m)).is_a?(Array) ? o : [o] ).each do |v| next if inResult[v.object_id] inResult[v.object_id] = true result << v end else raise StandardError.new("Trying to call a method on an array element not a RGen MMBase") end end result.compact end end rgen-0.7.0/lib/rgen/transformer.rb0000644000004100000410000005066612352210062017077 0ustar www-datawww-datarequire 'rgen/ecore/ecore' require 'rgen/ecore/ecore_ext' module RGen # The Transformer class can be used to specify model transformations. # # Model transformations take place between a source model (located in the source # environment being an instance of the source metamodel) and a target model (located # in the target environment being an instance of the target metamodel). # Normally a "model" consists of several model elements associated with each other. # # =Transformation Rules # # The transformation is specified within a subclass of Transformer. # Within the subclass, the Transformer.transform class method can be used to specify transformation # blocks for specific metamodel classes of the source metamodel. # # If there is no transformation rule for the current object's class, a rule for the superclass # is used instead. If there's no rule for the superclass, the class hierarchy is searched # this way until Object. # # Here is an example: # # class MyTransformer < RGen::Transformer # # transform InputClass, :to => OutputClass do # { :name => name, :otherClass => trans(otherClass) } # end # # transform OtherInputClass, :to => OtherOutputClass do # { :name => name } # end # end # # In this example a transformation rule is specified for model elements of class InputClass # as well as for elements of class OtherInputClass. The former is to be transformed into # an instance of OutputClass, the latter into an instance of OtherOutputClass. # Note that the Ruby class objects are used to specifiy the classes. # # =Transforming Attributes # # Besides the target class of a transformation, the attributes of the result object are # specified in the above example. This is done by providing a Ruby block with the call of # +transform+. Within this block arbitrary Ruby code may be placed, however the block # must return a hash. This hash object specifies the attribute assignment of the # result object using key/value pairs: The key must be a Symbol specifying the attribute # which is to be assigned by name, the value is the value that will be assigned. # # For convenience, the transformation block will be evaluated in the context of the # source model element which is currently being converted. This way it is possible to just # write :name => name in the example in order to assign the name of the source # object to the name attribute of the target object. # # =Transforming References # # When attributes of elements are references to other elements, those referenced # elements have to be transformed as well. As shown above, this can be done by calling # the Transformer#trans method. This method initiates a transformation of the element # or array of elements passed as parameter according to transformation rules specified # using +transform+. In fact the +trans+ method is the only way to start the transformation # at all. # # For convenience and performance reasons, the result of +trans+ is cached with respect # to the parameter object. I.e. calling trans on the same source object a second time will # return the same result object _without_ a second evaluation of the corresponding # transformation rules. # # This way the +trans+ method can be used to lookup the target element for some source # element without the need to locally store a reference to the target element. In addition # this can be useful if it is not clear if certain element has already been transformed # when it is required within some other transformation block. See example below. # # Special care has been taken to allow the transformation of elements which reference # each other cyclically. The key issue here is that the target element of some transformation # is created _before_ the transformation's block is evaluated, i.e before the elements # attributes are set. Otherwise a call to +trans+ within the transformation's block # could lead to a +trans+ of the element itself. # # Here is an example: # # transform ModelAIn, :to => ModelAOut do # { :name => name, :modelB => trans(modelB) } # end # # transform ModelBIn, :to => ModelBOut do # { :name => name, :modelA => trans(modelA) } # end # # Note that in this case it does not matter if the transformation is initiated by calling # +trans+ with a ModelAIn element or ModelBIn element due to the caching feature described # above. # # =Transformer Methods # # When code in transformer blocks becomes more complex it might be useful to refactor # it into smaller methods. If regular Ruby methods within the Transformer subclass are # used for this purpose, it is necessary to know the source element being transformed. # This could be achieved by explicitly passing the +@current_object+ as parameter of the # method (see Transformer#trans). # # A more convenient way however is to define a special kind of method using the # Transformer.method class method. Those methods are evaluated within the context of the # current source element being transformed just the same as transformer blocks are. # # Here is an example: # # transform ModelIn, :to => ModelOut do # { :number => doubleNumber } # end # # method :doubleNumber do # number * 2; # end # # In this example the transformation assigns the 'number' attribute of the source element # multiplied by 2 to the target element. The multiplication is done in a dedicated method # called 'doubleNumber'. Note that the 'number' attribute of the source element is # accessed without an explicit reference to the source element as the method's body # evaluates in the source element's context. # # =Conditional Transformations # # Using the transformations as described above, all elements of the same class are # transformed the same way. Conditional transformations allow to transform elements of # the same class into elements of different target classes as well as applying different # transformations on the attributes. # # Conditional transformations are defined by specifying multiple transformer blocks for # the same source class and providing a condition with each block. Since it is important # to create the target object before evaluation of the transformation block (see above), # the conditions must also be evaluated separately _before_ the transformer block. # # Conditions are specified using transformer methods as described above. If the return # value is true, the corresponding block is used for transformation. If more than one # conditions are true, only the first transformer block will be evaluated. # # If there is no rule with a condition evaluating to true, rules for superclasses will # be checked as described above. # # Here is an example: # # transform ModelIn, :to => ModelOut, :if => :largeNumber do # { :number => number * 2} # end # # transform ModelIn, :to => ModelOut, :if => :smallNumber do # { :number => number / 2 } # end # # method :largeNumber do # number > 1000 # end # # method :smallNumber do # number < 500 # end # # In this case the transformation of an element of class ModelIn depends on the value # of the element's 'number' attribute. If the value is greater than 1000, the first rule # as taken and the number is doubled. If the value is smaller than 500, the second rule # is taken and the number is divided by two. # # Note that it is up to the user to avoid cycles within the conditions. A cycle could # occure if the condition are based on transformation target elements, i.e. if +trans+ # is used within the condition to lookup or transform other elements. # # = Copy Transformations # # In some cases, transformations should just copy a model, either in the same metamodel # or in another metamodel with the same package/class structure. Sometimes, a transformation # is not exactly a copy, but a copy with slight modifications. Also in this case most # classes need to be copied verbatim. # # The class method Transformer.copy can be used to specify a copy rule for a single # metamodel class. If no target class is specified using the :to named parameter, the # target class will be the same as the source class (i.e. in the same metamodel). # # copy MM1::ClassA # copy within the same metamodel # copy MM1::ClassA, :to => MM2::ClassA # # The class method Transfomer.copy_all can be used to specify copy rules for all classes # of a particular metamodel package. Again with :to, the target metamodel package may # be specified which must have the same package/class structure. If :to is omitted, the # target metamodel is the same as the source metamodel. In case that for some classes # specific transformation rules should be used instead of copy rules, exceptions may be # specified using the :except named parameter. +copy_all+ also provides an easy way to # copy (clone) a model within the same metamodel. # # copy_all MM1 # copy rules for the whole metamodel MM1, # # used to clone models of MM1 # # copy_all MM1, :to => MM2, :except => %w( # copy rules for all classes of MM1 to # ClassA # equally named classes in MM2, except # Sub1::ClassB # "ClassA" and "Sub1::ClassB" # ) # # If a specific class transformation is not an exact copy, the Transformer.transform method # should be used to actually specify the transformation. If this transformation is also # mostly a copy, the helper method Transformer#copy_features can be used to create the # transformation Hash required by the transform method. Any changes to this hash may be done # in a hash returned by a block given to +copy_features+. This hash will extend or overwrite # the default copy hash. In case a particular feature should not be part of the copy hash # (e.g. because it does not exist in the target metamodel), exceptions can be specified using # the :except named parameter. Here is an example: # # transform ClassA, :to => ClassAx do # copy_features :except => [:featA] do # { :featB => featA } # end # end # # In this example, ClassAx is a copy of ClassA except, that feature "featA" in ClassA is renamed # into "featB" in ClassAx. Using +copy_features+ all features are copied except "featA". Then # "featB" of the target class is assigned the value of "featA" of the source class. # class Transformer TransformationDescription = Struct.new(:block, :target) # :nodoc: @@methods = {} @@transformer_blocks = {} def self._transformer_blocks # :nodoc: @@transformer_blocks[self] ||= {} end def self._methods # :nodoc: @@methods[self] ||= {} end # This class method is used to specify a transformation rule. # # The first argument specifies the class of elements for which this rule applies. # The second argument must be a hash including the target class # (as value of key ':to') and an optional condition (as value of key ':if'). # # The target class is specified by passing the actual Ruby class object. # The condition is either the name of a transformer method (see Transfomer.method) as # a symbol or a proc object. In either case the block is evaluated at transformation # time and its result value determines if the rule applies. # def self.transform(from, desc=nil, &block) to = (desc && desc.is_a?(Hash) && desc[:to]) condition = (desc && desc.is_a?(Hash) && desc[:if]) raise StandardError.new("No transformation target specified.") unless to block_desc = TransformationDescription.new(block, to) if condition _transformer_blocks[from] ||= {} raise StandardError.new("Multiple (non-conditional) transformations for class #{from.name}.") unless _transformer_blocks[from].is_a?(Hash) _transformer_blocks[from][condition] = block_desc else raise StandardError.new("Multiple (non-conditional) transformations for class #{from.name}.") unless _transformer_blocks[from].nil? _transformer_blocks[from] = block_desc end end # This class method specifies that all objects of class +from+ are to be copied # into an object of class +to+. If +to+ is omitted, +from+ is used as target class. # The target class may also be specified using the :to => hash notation. # During copy, all attributes and references of the target object # are set to their transformed counterparts of the source object. # def self.copy(from, to=nil) raise StandardError.new("Specify target class either directly as second parameter or using :to => ") \ unless to.nil? || to.is_a?(Class) || (to.is_a?(Hash) && to[:to].is_a?(Class)) to = to[:to] if to.is_a?(Hash) transform(from, :to => to || from) do copy_features end end # Create copy rules for all classes of metamodel package (module) +from+ and its subpackages. # The target classes are the classes with the same name in the metamodel package # specified using named parameter :to. If no target metamodel is specified, source # and target classes will be the same. # The named parameter :except can be used to specify classes by qualified name for which # no copy rules should be created. Qualified names are relative to the metamodel package # specified. # def self.copy_all(from, hash={}) to = hash[:to] || from except = hash[:except] fromDepth = from.ecore.qualifiedName.split("::").size from.ecore.eAllClasses.each do |c| path = c.qualifiedName.split("::")[fromDepth..-1] next if except && except.include?(path.join("::")) copy c.instanceClass, :to => path.inject(to){|m,c| m.const_get(c)} end end # Define a transformer method for the current transformer class. # In contrast to regular Ruby methods, a method defined this way executes in the # context of the object currently being transformed. # def self.method(name, &block) _methods[name.to_s] = block end # Creates a new transformer # Optionally an input and output Environment can be specified. # If an elementMap is provided (normally a Hash) this map will be used to lookup # and store transformation results. This way results can be predefined # and it is possible to have several transformers work on the same result map. # def initialize(env_in=nil, env_out=nil, elementMap=nil) @env_in = env_in @env_out = env_out @transformer_results = elementMap || {} @transformer_jobs = [] end # Transforms a given model element according to the rules specified by means of # the Transformer.transform class method. # # The transformation result element is created in the output environment and returned. # In addition, the result is cached, i.e. a second invocation with the same parameter # object will return the same result object without any further evaluation of the # transformation rules. Nil will be transformed into nil. Ruby "singleton" objects # +true+, +false+, numerics and symbols will be returned without any change. Ruby strings # will be duplicated with the result being cached. # # The transformation input can be given as: # * a single object # * an array each element of which is transformed in turn # * a hash used as input to Environment#find with the result being transformed # def trans(obj) if obj.is_a?(Hash) raise StandardError.new("No input environment available to find model element.") unless @env_in obj = @env_in.find(obj) end return nil if obj.nil? return obj if obj.is_a?(TrueClass) or obj.is_a?(FalseClass) or obj.is_a?(Numeric) or obj.is_a?(Symbol) return @transformer_results[obj] if @transformer_results[obj] return @transformer_results[obj] = obj.dup if obj.is_a?(String) return obj.collect{|o| trans(o)}.compact if obj.is_a? Array raise StandardError.new("No transformer for class #{obj.class.name}") unless _transformerBlock(obj.class) block_desc = _evaluateCondition(obj) return nil unless block_desc @transformer_results[obj] = _instantiateTargetClass(obj, block_desc.target) # we will transform the properties later @transformer_jobs << TransformerJob.new(self, obj, block_desc) # if there have been jobs in the queue before, don't process them in this call # this way calls to trans are not nested; a recursive implementation # may cause a "Stack level too deep" exception for large models return @transformer_results[obj] if @transformer_jobs.size > 1 # otherwise this is the first call of trans, process all jobs here # more jobs will be added during job execution while @transformer_jobs.size > 0 @transformer_jobs.first.execute @transformer_jobs.shift end @transformer_results[obj] end # Create the hash required as return value of the block given to the Transformer.transform method. # The hash will assign feature values of the source class to the features of the target class, # assuming the features of both classes are the same. If the :except named parameter specifies # an Array of symbols, the listed features are not copied by the hash. In order to easily manipulate # the resulting hash, a block may be given which should also return a feature assignmet hash. This # hash should be created manually and will extend/overwrite the automatically created hash. # def copy_features(options={}) hash = {} @current_object.class.ecore.eAllStructuralFeatures.each do |f| next if f.derived next if options[:except] && options[:except].include?(f.name.to_sym) hash[f.name.to_sym] = trans(@current_object.send(f.name)) end hash.merge!(yield) if block_given? hash end def _transformProperties(obj, block_desc) #:nodoc: old_object, @current_object = @current_object, obj block_result = instance_eval(&block_desc.block) raise StandardError.new("Transformer must return a hash") unless block_result.is_a? Hash @current_object = old_object _attributesFromHash(@transformer_results[obj], block_result) end class TransformerJob #:nodoc: def initialize(transformer, obj, block_desc) @transformer, @obj, @block_desc = transformer, obj, block_desc end def execute @transformer._transformProperties(@obj, @block_desc) end end # Each call which is not handled by the transformer object is passed to the object # currently being transformed. # If that object also does not respond to the call, it is treated as a transformer # method call (see Transformer.method). # def method_missing(m, *args) #:nodoc: if @current_object.respond_to?(m) @current_object.send(m, *args) else _invokeMethod(m, *args) end end private # returns _transformer_blocks content for clazz or one of its superclasses def _transformerBlock(clazz) # :nodoc: block = self.class._transformer_blocks[clazz] block = _transformerBlock(clazz.superclass) if block.nil? && clazz != Object block end # returns the first TransformationDescription for clazz or one of its superclasses # for which condition is true def _evaluateCondition(obj, clazz=obj.class) # :nodoc: tb = self.class._transformer_blocks[clazz] block_description = nil if tb.is_a?(TransformationDescription) # non-conditional block_description = tb elsif tb old_object, @current_object = @current_object, obj tb.each_pair {|condition, block| if condition.is_a?(Proc) result = instance_eval(&condition) elsif condition.is_a?(Symbol) result = _invokeMethod(condition) else result = condition end if result block_description = block break end } @current_object = old_object end block_description = _evaluateCondition(obj, clazz.superclass) if block_description.nil? && clazz != Object block_description end def _instantiateTargetClass(obj, target_desc) # :nodoc: old_object, @current_object = @current_object, obj if target_desc.is_a?(Proc) target_class = instance_eval(&target_desc) elsif target_desc.is_a?(Symbol) target_class = _invokeMethod(target_desc) else target_class = target_desc end @current_object = old_object result = target_class.new @env_out << result if @env_out result end def _invokeMethod(m) # :nodoc: raise StandardError.new("Method not found: #{m}") unless self.class._methods[m.to_s] instance_eval(&self.class._methods[m.to_s]) end def _attributesFromHash(obj, hash) # :nodoc: hash.delete(:class) hash.each_pair{|k,v| obj.send("#{k}=", v) } obj end end endrgen-0.7.0/lib/metamodels/0000755000004100000410000000000012352210062015372 5ustar www-datawww-datargen-0.7.0/lib/metamodels/uml13_metamodel.rb0000644000004100000410000004545112352210062020720 0ustar www-datawww-datarequire 'rgen/metamodel_builder' module UML13 extend RGen::MetamodelBuilder::ModuleExtension include RGen::MetamodelBuilder::DataTypes AggregationKind = Enum.new(:name => "AggregationKind", :literals =>[ :none, :aggregate, :composite ]) ChangeableKind = Enum.new(:name => "ChangeableKind", :literals =>[ :changeable, :frozen, :addOnly ]) OperationDirectionKind = Enum.new(:name => "OperationDirectionKind", :literals =>[ ]) ParameterDirectionKind = Enum.new(:name => "ParameterDirectionKind", :literals =>[ :in, :inout, :out, :return ]) MessageDirectionKind = Enum.new(:name => "MessageDirectionKind", :literals =>[ ]) ScopeKind = Enum.new(:name => "ScopeKind", :literals =>[ :instance, :classifier ]) VisibilityKind = Enum.new(:name => "VisibilityKind", :literals =>[ :public, :protected, :private ]) PseudostateKind = Enum.new(:name => "PseudostateKind", :literals =>[ :initial, :deepHistory, :shallowHistory, :join, :fork, :branch, :junction, :final ]) CallConcurrencyKind = Enum.new(:name => "CallConcurrencyKind", :literals =>[ :sequential, :guarded, :concurrent ]) OrderingKind = Enum.new(:name => "OrderingKind", :literals =>[ :unordered, :ordered, :sorted ]) class Element < RGen::MetamodelBuilder::MMBase end class ModelElement < Element has_attr 'name', String has_attr 'visibility', UML13::VisibilityKind, :defaultValueLiteral => "public" has_attr 'isSpecification', Boolean end class Namespace < ModelElement end class GeneralizableElement < ModelElement has_attr 'isRoot', Boolean has_attr 'isLeaf', Boolean has_attr 'isAbstract', Boolean end class Classifier < RGen::MetamodelBuilder::MMMultiple(GeneralizableElement, Namespace) end class Class < Classifier has_attr 'isActive', Boolean end class DataType < Classifier end class Feature < ModelElement has_attr 'ownerScope', UML13::ScopeKind, :defaultValueLiteral => "instance" end class StructuralFeature < Feature has_attr 'changeability', UML13::ChangeableKind, :defaultValueLiteral => "changeable" has_attr 'targetScope', UML13::ScopeKind, :defaultValueLiteral => "instance" end class AssociationEnd < ModelElement has_attr 'isNavigable', Boolean, :defaultValueLiteral => "false" has_attr 'ordering', UML13::OrderingKind, :defaultValueLiteral => "unordered" has_attr 'aggregation', UML13::AggregationKind, :defaultValueLiteral => "none" has_attr 'targetScope', UML13::ScopeKind, :defaultValueLiteral => "instance" has_attr 'changeability', UML13::ChangeableKind, :defaultValueLiteral => "changeable" end class Interface < Classifier end class Constraint < ModelElement end class Relationship < ModelElement end class Association < RGen::MetamodelBuilder::MMMultiple(GeneralizableElement, Relationship) end class Attribute < StructuralFeature end class BehavioralFeature < Feature has_attr 'isQuery', Boolean end class Operation < BehavioralFeature has_attr 'concurrency', UML13::CallConcurrencyKind, :defaultValueLiteral => "sequential" has_attr 'isRoot', Boolean has_attr 'isLeaf', Boolean has_attr 'isAbstract', Boolean end class Parameter < ModelElement has_attr 'kind', UML13::ParameterDirectionKind, :defaultValueLiteral => "inout" end class Method < BehavioralFeature end class Generalization < Relationship has_attr 'discriminator', String end class AssociationClass < RGen::MetamodelBuilder::MMMultiple(Class, Association) end class Dependency < Relationship end class Abstraction < Dependency end class PresentationElement < Element end class Usage < Dependency end class Binding < Dependency end class Component < Classifier end class Node < Classifier end class Permission < Dependency end class Comment < ModelElement has_attr 'body', String end class Flow < Relationship end class TemplateParameter < RGen::MetamodelBuilder::MMBase end class ElementResidence < RGen::MetamodelBuilder::MMBase has_attr 'visibility', UML13::VisibilityKind, :defaultValueLiteral => "public" end class Multiplicity < RGen::MetamodelBuilder::MMBase end class Expression < RGen::MetamodelBuilder::MMBase has_attr 'language', String has_attr 'body', String end class ObjectSetExpression < Expression end class TimeExpression < Expression end class BooleanExpression < Expression end class ActionExpression < Expression end class MultiplicityRange < RGen::MetamodelBuilder::MMBase has_attr 'lower', String has_attr 'upper', String end class Structure < DataType end class Primitive < DataType end class Enumeration < DataType end class EnumerationLiteral < RGen::MetamodelBuilder::MMBase has_attr 'name', String end class ProgrammingLanguageType < DataType end class IterationExpression < Expression end class TypeExpression < Expression end class ArgListsExpression < Expression end class MappingExpression < Expression end class ProcedureExpression < Expression end class Stereotype < GeneralizableElement has_attr 'icon', String has_attr 'baseClass', String end class TaggedValue < Element has_attr 'tag', String has_attr 'value', String end class UseCase < Classifier end class Actor < Classifier end class Instance < ModelElement end class UseCaseInstance < Instance end class Extend < Relationship end class Include < Relationship end class ExtensionPoint < ModelElement has_attr 'location', String end class StateMachine < ModelElement end class Event < ModelElement end class StateVertex < ModelElement end class State < StateVertex end class TimeEvent < Event end class CallEvent < Event end class SignalEvent < Event end class Transition < ModelElement end class CompositeState < State has_attr 'isConcurrent', Boolean end class ChangeEvent < Event end class Guard < ModelElement end class Pseudostate < StateVertex has_attr 'kind', UML13::PseudostateKind, :defaultValueLiteral => "initial" end class SimpleState < State end class SubmachineState < CompositeState end class SynchState < StateVertex has_attr 'bound', Integer end class StubState < StateVertex has_attr 'referenceState', String end class FinalState < State end class Collaboration < RGen::MetamodelBuilder::MMMultiple(GeneralizableElement, Namespace) end class ClassifierRole < Classifier end class AssociationRole < Association end class AssociationEndRole < AssociationEnd end class Message < ModelElement end class Interaction < ModelElement end class Signal < Classifier end class Action < ModelElement has_attr 'isAsynchronous', Boolean end class CreateAction < Action end class DestroyAction < Action end class UninterpretedAction < Action end class AttributeLink < ModelElement end class Object < Instance end class Link < ModelElement end class LinkObject < RGen::MetamodelBuilder::MMMultiple(Object, Link) end class DataValue < Instance end class CallAction < Action end class SendAction < Action end class ActionSequence < Action end class Argument < ModelElement end class Reception < BehavioralFeature has_attr 'isPolymorphic', Boolean has_attr 'specification', String end class LinkEnd < ModelElement end class Call < RGen::MetamodelBuilder::MMBase end class ReturnAction < Action end class TerminateAction < Action end class Stimulus < ModelElement end class ActionInstance < RGen::MetamodelBuilder::MMBase end class Exception < Signal end class AssignmentAction < Action end class ComponentInstance < Instance end class NodeInstance < Instance end class ActivityGraph < StateMachine end class Partition < ModelElement end class SubactivityState < SubmachineState has_attr 'isDynamic', Boolean end class ActionState < SimpleState has_attr 'isDynamic', Boolean end class CallState < ActionState end class ObjectFlowState < SimpleState has_attr 'isSynch', Boolean end class ClassifierInState < Classifier end class Package < RGen::MetamodelBuilder::MMMultiple(GeneralizableElement, Namespace) end class Model < Package end class Subsystem < RGen::MetamodelBuilder::MMMultiple(Classifier, Package) has_attr 'isInstantiable', Boolean end class ElementImport < RGen::MetamodelBuilder::MMBase has_attr 'visibility', UML13::VisibilityKind, :defaultValueLiteral => "public" has_attr 'alias', String end class DiagramElement < PresentationElement has_attr 'geometry', String has_attr 'style', String end class Diagram < PresentationElement has_attr 'name', String has_attr 'toolName', String has_attr 'diagramType', String has_attr 'style', String end end UML13::Classifier.many_to_many 'participant', UML13::AssociationEnd, 'specification' UML13::Classifier.one_to_many 'associationEnd', UML13::AssociationEnd, 'type' UML13::Classifier.contains_many 'feature', UML13::Feature, 'owner' UML13::StructuralFeature.contains_one_uni 'multiplicity', UML13::Multiplicity UML13::StructuralFeature.has_one 'type', UML13::Classifier, :lowerBound => 1 UML13::Namespace.contains_many 'ownedElement', UML13::ModelElement, 'namespace' UML13::AssociationEnd.contains_one_uni 'multiplicity', UML13::Multiplicity UML13::AssociationEnd.contains_many 'qualifier', UML13::Attribute, 'associationEnd' UML13::Association.contains_many 'connection', UML13::AssociationEnd, 'association', :lowerBound => 2 UML13::Constraint.contains_one_uni 'body', UML13::BooleanExpression UML13::Constraint.many_to_many 'constrainedElement', UML13::ModelElement, 'constraint', :lowerBound => 1 UML13::GeneralizableElement.one_to_many 'specialization', UML13::Generalization, 'parent' UML13::GeneralizableElement.one_to_many 'generalization', UML13::Generalization, 'child' UML13::Attribute.contains_one_uni 'initialValue', UML13::Expression UML13::Operation.one_to_many 'occurrence', UML13::CallEvent, 'operation' UML13::Operation.one_to_many 'method', UML13::Method, 'specification' UML13::Parameter.contains_one_uni 'defaultValue', UML13::Expression UML13::Parameter.many_to_many 'state', UML13::ObjectFlowState, 'parameter' UML13::Parameter.has_one 'type', UML13::Classifier, :lowerBound => 1 UML13::Method.contains_one_uni 'body', UML13::ProcedureExpression UML13::BehavioralFeature.many_to_many 'raisedSignal', UML13::Signal, 'context' UML13::BehavioralFeature.contains_many_uni 'parameter', UML13::Parameter UML13::ModelElement.one_to_many 'behavior', UML13::StateMachine, 'context' UML13::ModelElement.many_to_one 'stereotype', UML13::Stereotype, 'extendedElement' UML13::ModelElement.one_to_many 'elementResidence', UML13::ElementResidence, 'resident' UML13::ModelElement.many_to_many 'sourceFlow', UML13::Flow, 'source' UML13::ModelElement.many_to_many 'targetFlow', UML13::Flow, 'target' UML13::ModelElement.many_to_many 'presentation', UML13::PresentationElement, 'subject' UML13::ModelElement.many_to_many 'supplierDependency', UML13::Dependency, 'supplier', :lowerBound => 1 UML13::ModelElement.contains_many 'taggedValue', UML13::TaggedValue, 'modelElement' UML13::ModelElement.contains_many_uni 'templateParameter', UML13::TemplateParameter UML13::ModelElement.many_to_many 'clientDependency', UML13::Dependency, 'client', :lowerBound => 1 UML13::ModelElement.many_to_many 'comment', UML13::Comment, 'annotatedElement' UML13::ModelElement.one_to_many 'elementImport', UML13::ElementImport, 'modelElement' UML13::Abstraction.contains_one_uni 'mapping', UML13::MappingExpression UML13::Binding.has_many 'argument', UML13::ModelElement, :lowerBound => 1 UML13::Component.contains_many 'residentElement', UML13::ElementResidence, 'implementationLocation' UML13::Component.many_to_many 'deploymentLocation', UML13::Node, 'resident' UML13::TemplateParameter.has_one 'modelElement', UML13::ModelElement UML13::TemplateParameter.has_one 'defaultElement', UML13::ModelElement UML13::Multiplicity.contains_many_uni 'range', UML13::MultiplicityRange, :lowerBound => 1 UML13::Enumeration.contains_many_uni 'literal', UML13::EnumerationLiteral, :lowerBound => 1 UML13::ProgrammingLanguageType.contains_one_uni 'type', UML13::TypeExpression UML13::Stereotype.has_many 'requiredTag', UML13::TaggedValue UML13::UseCase.has_many 'extensionPoint', UML13::ExtensionPoint UML13::UseCase.one_to_many 'include', UML13::Include, 'base' UML13::UseCase.one_to_many 'extend', UML13::Extend, 'extension' UML13::Extend.contains_one_uni 'condition', UML13::BooleanExpression UML13::Extend.has_many 'extensionPoint', UML13::ExtensionPoint, :lowerBound => 1 UML13::Extend.has_one 'base', UML13::UseCase, :lowerBound => 1 UML13::Include.has_one 'addition', UML13::UseCase, :lowerBound => 1 UML13::StateMachine.contains_many_uni 'transitions', UML13::Transition UML13::StateMachine.contains_one_uni 'top', UML13::State, :lowerBound => 1 UML13::Event.contains_many_uni 'parameters', UML13::Parameter UML13::State.contains_one_uni 'doActivity', UML13::Action UML13::State.contains_many_uni 'internalTransition', UML13::Transition UML13::State.has_many 'deferrableEvent', UML13::Event UML13::State.contains_one_uni 'exit', UML13::Action UML13::State.contains_one_uni 'entry', UML13::Action UML13::TimeEvent.contains_one_uni 'when', UML13::TimeExpression UML13::SignalEvent.many_to_one 'signal', UML13::Signal, 'occurrence', :lowerBound => 1 UML13::Transition.many_to_one 'target', UML13::StateVertex, 'incoming', :lowerBound => 1 UML13::Transition.many_to_one 'source', UML13::StateVertex, 'outgoing', :lowerBound => 1 UML13::Transition.has_one 'trigger', UML13::Event UML13::Transition.contains_one_uni 'effect', UML13::Action UML13::Transition.contains_one_uni 'guard', UML13::Guard UML13::CompositeState.contains_many 'subvertex', UML13::StateVertex, 'container', :lowerBound => 1 UML13::ChangeEvent.contains_one_uni 'changeExpression', UML13::BooleanExpression UML13::Guard.contains_one_uni 'expression', UML13::BooleanExpression UML13::SubmachineState.has_one 'submachine', UML13::StateMachine, :lowerBound => 1 UML13::Collaboration.has_one 'representedOperation', UML13::Operation UML13::Collaboration.has_one 'representedClassifier', UML13::Classifier UML13::Collaboration.has_many 'constrainingElement', UML13::ModelElement UML13::Collaboration.contains_many 'interaction', UML13::Interaction, 'context' UML13::ClassifierRole.contains_one_uni 'multiplicity', UML13::Multiplicity UML13::ClassifierRole.has_many 'availableContents', UML13::ModelElement UML13::ClassifierRole.has_many 'availableFeature', UML13::Feature UML13::ClassifierRole.has_one 'base', UML13::Classifier, :lowerBound => 1 UML13::AssociationRole.contains_one_uni 'multiplicity', UML13::Multiplicity UML13::AssociationRole.has_one 'base', UML13::Association UML13::AssociationEndRole.has_many 'availableQualifier', UML13::Attribute UML13::AssociationEndRole.has_one 'base', UML13::AssociationEnd UML13::Message.has_one 'action', UML13::Action, :lowerBound => 1 UML13::Message.has_one 'communicationConnection', UML13::AssociationRole UML13::Message.has_many 'predecessor', UML13::Message UML13::Message.has_one 'receiver', UML13::ClassifierRole, :lowerBound => 1 UML13::Message.has_one 'sender', UML13::ClassifierRole, :lowerBound => 1 UML13::Message.has_one 'activator', UML13::Message UML13::Interaction.contains_many 'message', UML13::Message, 'interaction', :lowerBound => 1 UML13::Interaction.contains_many_uni 'link', UML13::Link UML13::Instance.contains_many_uni 'slot', UML13::AttributeLink UML13::Instance.one_to_many 'linkEnd', UML13::LinkEnd, 'instance' UML13::Instance.has_many 'classifier', UML13::Classifier, :lowerBound => 1 UML13::Signal.one_to_many 'reception', UML13::Reception, 'signal' UML13::CreateAction.has_one 'instantiation', UML13::Classifier, :lowerBound => 1 UML13::Action.contains_one_uni 'recurrence', UML13::IterationExpression UML13::Action.contains_one_uni 'target', UML13::ObjectSetExpression UML13::Action.contains_one_uni 'script', UML13::ActionExpression UML13::Action.contains_many_uni 'actualArgument', UML13::Argument UML13::AttributeLink.has_one 'value', UML13::Instance, :lowerBound => 1 UML13::AttributeLink.has_one 'attribute', UML13::Attribute, :lowerBound => 1 UML13::CallAction.has_one 'operation', UML13::Operation, :lowerBound => 1 UML13::SendAction.has_one 'signal', UML13::Signal, :lowerBound => 1 UML13::ActionSequence.contains_many_uni 'action', UML13::Action UML13::Argument.contains_one_uni 'value', UML13::Expression UML13::Link.contains_many_uni 'connection', UML13::LinkEnd, :lowerBound => 2 UML13::Link.has_one 'association', UML13::Association, :lowerBound => 1 UML13::LinkEnd.has_one 'associationEnd', UML13::AssociationEnd, :lowerBound => 1 UML13::LinkEnd.has_one 'participant', UML13::Instance, :lowerBound => 1 UML13::Stimulus.has_one 'dispatchAction', UML13::Action, :lowerBound => 1 UML13::Stimulus.has_one 'communicationLink', UML13::Link UML13::Stimulus.has_one 'receiver', UML13::Instance, :lowerBound => 1 UML13::Stimulus.has_one 'sender', UML13::Instance, :lowerBound => 1 UML13::Stimulus.has_many 'argument', UML13::Instance UML13::ComponentInstance.has_many 'resident', UML13::Instance UML13::NodeInstance.has_many 'resident', UML13::ComponentInstance UML13::ActivityGraph.contains_many_uni 'partition', UML13::Partition UML13::Partition.has_many 'contents', UML13::ModelElement UML13::SubactivityState.contains_one_uni 'dynamicArguments', UML13::ArgListsExpression UML13::ObjectFlowState.has_one 'type', UML13::Classifier, :lowerBound => 1 UML13::ObjectFlowState.has_one 'available', UML13::Parameter, :lowerBound => 1 UML13::ClassifierInState.has_one 'type', UML13::Classifier, :lowerBound => 1 UML13::ClassifierInState.has_many 'inState', UML13::State UML13::ActionState.contains_one_uni 'dynamicArguments', UML13::ArgListsExpression UML13::Package.contains_many 'importedElement', UML13::ElementImport, 'package' UML13::Diagram.contains_many 'element', UML13::DiagramElement, 'diagram' UML13::Diagram.has_one 'owner', UML13::ModelElement, :lowerBound => 1 rgen-0.7.0/lib/metamodels/uml13_metamodel_ext.rb0000644000004100000410000000116412352210062021571 0ustar www-datawww-data# Some handy extensions to the UML13 metamodel # module UML13 module AssociationEnd::ClassModule def otherEnd association.connection.find{|c| c != self} end end module Classifier::ClassModule def localCompositeEnd associationEnd.select{|e| e.aggregation == :composite} end def remoteCompositeEnd associationEnd.otherEnd.select{|e| e.aggregation == :composite} end def localNavigableEnd associationEnd.select{|e| e.isNavigable} end def remoteNavigableEnd associationEnd.otherEnd.select{|e| e.isNavigable} end end end rgen-0.7.0/lib/mmgen/0000755000004100000410000000000012352210062014343 5ustar www-datawww-datargen-0.7.0/lib/mmgen/templates/0000755000004100000410000000000012352210062016341 5ustar www-datawww-datargen-0.7.0/lib/mmgen/templates/metamodel_generator.tpl0000644000004100000410000001546112352210062023106 0ustar www-datawww-data <% 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 %> rgen-0.7.0/lib/mmgen/templates/annotations.tpl0000644000004100000410000000235312352210062021422 0ustar www-datawww-data<% define 'Annotations', :for => EPackage do %> <% for a in eAnnotations %> annotation <% expand 'AnnotationArgs', :for => a %> <% end %> <% end %> <% define 'Annotations', :for => EClass do %> <% for a in eAnnotations %> annotation <% expand 'AnnotationArgs', :for => a %> <% end %> <% end %> <% define 'Annotations', :for => EStructuralFeature do %> <% oppositeAnnotations = (this.respond_to?(:eOpposite) && eOpposite && eOpposite.eAnnotations) || [] %> <% if eAnnotations.size > 0 || oppositeAnnotations.size > 0 %> do<%iinc%> <% for a in eAnnotations %> annotation <% expand 'AnnotationArgs', :for => a %> <% end %> <% for a in oppositeAnnotations %> opposite_annotation <% expand 'AnnotationArgs', :for => a %> <% end %><%idec%> end<%nows%> <% end %> <% end %> <% define 'AnnotationArgs', :for => EAnnotation do %> <% if source.nil? %> <% expand 'Details' %> <% else %> :source => "<%= source.to_s %>", :details => {<% expand 'Details' %>}<%nows%> <% end %> <% end %> <% define 'Details', :for => EAnnotation do %> <%= details.sort{|a,b| a.key<=>b.key}.collect{ |d| "\'" + d.key + "\' => \'"+ (d.value || "").gsub('\'','\\\'').to_s + "\'"}.join(', ') %><%nows%> <% end %>rgen-0.7.0/lib/mmgen/mm_ext/0000755000004100000410000000000012352210062015634 5ustar www-datawww-datargen-0.7.0/lib/mmgen/mm_ext/ecore_mmgen_ext.rb0000644000004100000410000000473312352210062021330 0ustar www-datawww-datarequire 'rgen/util/name_helper' module RGen module ECore module EPackage::ClassModule include RGen::Util::NameHelper def moduleName firstToUpper(name) end def qualifiedModuleName(rootPackage) return moduleName unless eSuperPackage and self != rootPackage eSuperPackage.qualifiedModuleName(rootPackage) + "::" + moduleName end def ancestorPackages return [] unless eSuperPackage [eSuperPackage] + eSuperPackage.ancestorPackages end def ownClasses eClassifiers.select{|c| c.is_a?(EClass)} end def classesInGenerationOrdering ownClasses + eSubpackages.collect{|s| s.classesInGenerationOrdering}.flatten end def needClassReorder? classesInGenerationOrdering != inheritanceOrderClasses(classesInGenerationOrdering) end def allClassesSorted inheritanceOrderClasses(classesInGenerationOrdering) end def inheritanceOrderClasses(cls) sortArray = cls.dup i1 = 0 while i1 < sortArray.size-1 again = false for i2 in i1+1..sortArray.size-1 e2 = sortArray[i2] if sortArray[i1].eSuperTypes.include?(e2) sortArray.delete(e2) sortArray.insert(i1,e2) again = true break end end i1 += 1 unless again end sortArray end end module EClassifier::ClassModule include RGen::Util::NameHelper def classifierName firstToUpper(name) end def qualifiedClassifierName(rootPackage) (ePackage ? ePackage.qualifiedModuleName(rootPackage) + "::" : "") + classifierName end def ancestorPackages return [] unless ePackage [ePackage] + ePackage.ancestorPackages end def qualifiedClassifierNameIfRequired(package) if ePackage != package commonSuper = (package.ancestorPackages & ancestorPackages).first qualifiedClassifierName(commonSuper) else classifierName end end end module EAttribute::ClassModule def RubyType typeMap = {'float' => 'Float', 'int' => 'Integer'} (self.getType && typeMap[self.getType.downcase]) || 'String' end end end end rgen-0.7.0/lib/mmgen/metamodel_generator.rb0000644000004100000410000000104412352210062020704 0ustar www-datawww-datarequire 'rgen/environment' require 'rgen/template_language' require 'rgen/ecore/ecore' require 'rgen/ecore/ecore_ext' require 'mmgen/mm_ext/ecore_mmgen_ext' module MMGen module MetamodelGenerator def generateMetamodel(rootPackage, out_file) tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new(RGen::ECore, File.dirname(out_file)) tpl_path = File.dirname(__FILE__) + '/templates' tc.load(tpl_path) tc.expand('metamodel_generator::GenerateMetamodel', File.basename(out_file), :for => rootPackage) end end endrgen-0.7.0/lib/mmgen/mmgen.rb0000644000004100000410000000134612352210062015777 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..") require 'ea/xmi_ecore_instantiator' require 'mmgen/metamodel_generator' include MMGen::MetamodelGenerator unless ARGV.length >= 2 puts "Usage: mmgen.rb ()*" exit else file_name = ARGV.shift root_package_name = ARGV.shift modules = ARGV out_file = file_name.gsub(/\.\w+$/,'.rb') puts out_file end env = RGen::Environment.new File.open(file_name) { |f| puts "instantiating ..." XMIECoreInstantiator.new.instantiateECoreModel(env, f.read) } rootPackage = env.find(:class => RGen::ECore::EPackage, :name => root_package_name).first puts "generating ..." generateMetamodel(rootPackage, out_file, modules) rgen-0.7.0/metadata.yml0000644000004100000410000001775312352210062015012 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: rgen version: !ruby/object:Gem::Version version: 0.7.0 platform: ruby authors: - Martin Thiede autorequire: bindir: bin cert_chain: [] date: 2014-04-01 00:00:00.000000000 Z dependencies: [] description: RGen is a framework for Model Driven Software Development (MDSD) in Ruby. This means that it helps you build Metamodels, instantiate Models, modify and transform Models and finally generate arbitrary textual content from it. email: martin dot thiede at gmx de executables: [] extensions: [] extra_rdoc_files: - README.rdoc - CHANGELOG - MIT-LICENSE files: - lib/ea_support/ea_support.rb - lib/ea_support/id_store.rb - lib/ea_support/uml13_ea_metamodel.rb - lib/ea_support/uml13_ea_metamodel_ext.rb - lib/ea_support/uml13_ea_metamodel_generator.rb - lib/ea_support/uml13_ea_to_uml13.rb - lib/ea_support/uml13_to_uml13_ea.rb - lib/metamodels/uml13_metamodel.rb - lib/metamodels/uml13_metamodel_ext.rb - lib/mmgen/metamodel_generator.rb - lib/mmgen/mm_ext/ecore_mmgen_ext.rb - lib/mmgen/mmgen.rb - lib/mmgen/templates/annotations.tpl - lib/mmgen/templates/metamodel_generator.tpl - lib/rgen/array_extensions.rb - lib/rgen/ecore/ecore.rb - lib/rgen/ecore/ecore_builder_methods.rb - lib/rgen/ecore/ecore_ext.rb - lib/rgen/ecore/ecore_interface.rb - lib/rgen/ecore/ecore_to_ruby.rb - lib/rgen/ecore/ruby_to_ecore.rb - lib/rgen/environment.rb - lib/rgen/fragment/dump_file_cache.rb - lib/rgen/fragment/fragmented_model.rb - lib/rgen/fragment/model_fragment.rb - lib/rgen/instantiator/abstract_instantiator.rb - lib/rgen/instantiator/abstract_xml_instantiator.rb - lib/rgen/instantiator/default_xml_instantiator.rb - lib/rgen/instantiator/ecore_xml_instantiator.rb - lib/rgen/instantiator/json_instantiator.rb - lib/rgen/instantiator/json_parser.rb - lib/rgen/instantiator/json_parser.y - lib/rgen/instantiator/nodebased_xml_instantiator.rb - lib/rgen/instantiator/qualified_name_resolver.rb - lib/rgen/instantiator/reference_resolver.rb - lib/rgen/instantiator/resolution_helper.rb - lib/rgen/instantiator/xmi11_instantiator.rb - lib/rgen/metamodel_builder.rb - lib/rgen/metamodel_builder/builder_extensions.rb - lib/rgen/metamodel_builder/builder_runtime.rb - lib/rgen/metamodel_builder/constant_order_helper.rb - lib/rgen/metamodel_builder/data_types.rb - lib/rgen/metamodel_builder/intermediate/annotation.rb - lib/rgen/metamodel_builder/intermediate/feature.rb - lib/rgen/metamodel_builder/mm_multiple.rb - lib/rgen/metamodel_builder/module_extension.rb - lib/rgen/model_builder.rb - lib/rgen/model_builder/builder_context.rb - lib/rgen/model_builder/model_serializer.rb - lib/rgen/model_builder/reference_resolver.rb - lib/rgen/serializer/json_serializer.rb - lib/rgen/serializer/opposite_reference_filter.rb - lib/rgen/serializer/qualified_name_provider.rb - lib/rgen/serializer/xmi11_serializer.rb - lib/rgen/serializer/xmi20_serializer.rb - lib/rgen/serializer/xml_serializer.rb - lib/rgen/template_language.rb - lib/rgen/template_language/directory_template_container.rb - lib/rgen/template_language/output_handler.rb - lib/rgen/template_language/template_container.rb - lib/rgen/template_language/template_helper.rb - lib/rgen/transformer.rb - lib/rgen/util/auto_class_creator.rb - lib/rgen/util/cached_glob.rb - lib/rgen/util/file_cache_map.rb - lib/rgen/util/file_change_detector.rb - lib/rgen/util/method_delegation.rb - lib/rgen/util/model_comparator.rb - lib/rgen/util/model_comparator_base.rb - lib/rgen/util/model_dumper.rb - lib/rgen/util/name_helper.rb - lib/rgen/util/pattern_matcher.rb - lib/transformers/ecore_to_uml13.rb - lib/transformers/uml13_to_ecore.rb - test/array_extensions_test.rb - test/ea_instantiator_test.rb - test/ea_serializer_test.rb - test/ecore_self_test.rb - test/environment_test.rb - test/json_test.rb - test/metamodel_builder_test.rb - test/metamodel_from_ecore_test.rb - test/metamodel_order_test.rb - test/metamodel_roundtrip_test.rb - test/metamodel_roundtrip_test/TestModel.rb - test/metamodel_roundtrip_test/TestModel_Regenerated.rb - test/metamodel_roundtrip_test/houseMetamodel.ecore - test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore - test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb - test/metamodel_roundtrip_test/using_builtin_types.ecore - test/metamodel_roundtrip_test/using_builtin_types_serialized.ecore - test/method_delegation_test.rb - test/model_builder/builder_context_test.rb - test/model_builder/builder_test.rb - test/model_builder/ecore_internal.rb - test/model_builder/ecore_original.rb - test/model_builder/ecore_original_regenerated.rb - test/model_builder/reference_resolver_test.rb - test/model_builder/serializer_test.rb - test/model_builder/statemachine_metamodel.rb - test/model_builder/test_model/statemachine1.rb - test/model_builder_test.rb - test/model_fragment_test.rb - test/output_handler_test.rb - test/qualified_name_provider_test.rb - test/qualified_name_resolver_test.rb - test/reference_resolver_test.rb - test/rgen_test.rb - test/template_language_test.rb - test/template_language_test/expected_result1.txt - test/template_language_test/expected_result2.txt - test/template_language_test/expected_result3.txt - test/template_language_test/indentStringTestDefaultIndent.out - test/template_language_test/indentStringTestTabIndent.out - test/template_language_test/templates/callback_indent_test/a.tpl - test/template_language_test/templates/callback_indent_test/b.tpl - test/template_language_test/templates/code/array.tpl - test/template_language_test/templates/content/author.tpl - test/template_language_test/templates/content/chapter.tpl - test/template_language_test/templates/define_local_test/local.tpl - test/template_language_test/templates/define_local_test/test.tpl - test/template_language_test/templates/evaluate_test/test.tpl - test/template_language_test/templates/indent_string_test.tpl - test/template_language_test/templates/index/c/cmod.tpl - test/template_language_test/templates/index/chapter.tpl - test/template_language_test/templates/no_backslash_r_test.tpl - test/template_language_test/templates/no_indent_test/no_indent.tpl - test/template_language_test/templates/no_indent_test/sub1/no_indent.tpl - test/template_language_test/templates/no_indent_test/test.tpl - test/template_language_test/templates/no_indent_test/test2.tpl - test/template_language_test/templates/no_indent_test/test3.tpl - test/template_language_test/templates/null_context_test.tpl - test/template_language_test/templates/root.tpl - test/template_language_test/templates/template_resolution_test/sub1.tpl - test/template_language_test/templates/template_resolution_test/sub1/sub1.tpl - test/template_language_test/templates/template_resolution_test/test.tpl - test/template_language_test/testout.txt - test/testmodel/class_model_checker.rb - test/testmodel/ea_testmodel.eap - test/testmodel/ea_testmodel.xml - test/testmodel/ea_testmodel_partial.xml - test/testmodel/ea_testmodel_regenerated.xml - test/testmodel/ecore_model_checker.rb - test/testmodel/manual_testmodel.xml - test/testmodel/object_model_checker.rb - test/transformer_test.rb - test/util/file_cache_map_test.rb - test/util/file_cache_map_test/testdir/fileA - test/util/pattern_matcher_test.rb - test/util_test.rb - test/xml_instantiator_test.rb - test/xml_instantiator_test/simple_ecore_model_checker.rb - test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb - test/xml_instantiator_test/simple_xmi_metamodel.rb - test/xml_instantiator_test/simple_xmi_to_ecore.rb - README.rdoc - CHANGELOG - MIT-LICENSE - Rakefile homepage: http://ruby-gen.org licenses: [] metadata: {} post_install_message: rdoc_options: - --main - README.rdoc - -x - test - -x - metamodels - -x - ea_support/uml13* require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rgen rubygems_version: 2.0.3 signing_key: specification_version: 4 summary: Ruby Modelling and Generator Framework test_files: [] rgen-0.7.0/test/0000755000004100000410000000000012352210062013451 5ustar www-datawww-datargen-0.7.0/test/reference_resolver_test.rb0000644000004100000410000001022412352210062020713 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/metamodel_builder' require 'rgen/instantiator/reference_resolver' class ReferenceResolverTest < Test::Unit::TestCase class TestNode < RGen::MetamodelBuilder::MMBase has_attr 'name', String has_one 'other', TestNode has_many 'others', TestNode end class TestNode2 < RGen::MetamodelBuilder::MMBase has_attr 'name', String end def test_identifier_resolver nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new( :identifier_resolver => proc do |ident| {:a => nodeA, :b => nodeB, :c => nodeC}[ident] end) urefs = resolver.resolve(unresolved_refs) check_model(nodeA, nodeB, nodeC) assert urefs.empty? end def test_add_identifier nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new resolver.add_identifier(:a, nodeA) resolver.add_identifier(:b, nodeB) resolver.add_identifier(:c, nodeC) urefs = resolver.resolve(unresolved_refs) check_model(nodeA, nodeB, nodeC) assert urefs.empty? end def test_problems nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new( :identifier_resolver => proc do |ident| {:a => [nodeA, nodeB], :c => nodeC}[ident] end) problems = [] urefs = resolver.resolve(unresolved_refs, :problems => problems) assert_equal ["identifier b not found", "identifier a not uniq"], problems assert_equal 2, urefs.size assert urefs.all?{|ur| !ur.target_type_error} end def test_on_resolve_proc nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new resolver.add_identifier(:a, nodeA) resolver.add_identifier(:b, nodeB) resolver.add_identifier(:c, nodeC) data = [] resolver.resolve(unresolved_refs, :on_resolve => proc {|ur, e| data << [ ur, e ]}) assert data[0][0].is_a?(RGen::Instantiator::ReferenceResolver::UnresolvedReference) assert_equal nodeA, data[0][0].element assert_equal "other", data[0][0].feature_name assert_equal :b, data[0][0].proxy.targetIdentifier assert_equal nodeB, data[0][1] end def test_target_type_error nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new( :identifier_resolver => proc do |ident| {:a => TestNode2.new, :b => TestNode2.new, :c => nodeC}[ident] end) problems = [] urefs = resolver.resolve(unresolved_refs, :problems => problems) assert_equal 2, problems.size assert problems[0] =~ /invalid target type .*TestNode2/ assert problems[1] =~ /invalid target type .*TestNode2/ assert_equal 2, urefs.uniq.size assert urefs[0].target_type_error assert urefs[1].target_type_error assert urefs.any?{|ur| ur.proxy.object_id == nodeA.other.object_id} assert urefs.any?{|ur| ur.proxy.object_id == nodeB.others[0].object_id} end private def create_model nodeA = TestNode.new(:name => "NodeA") nodeB = TestNode.new(:name => "NodeB") nodeC = TestNode.new(:name => "NodeC") bProxy = RGen::MetamodelBuilder::MMProxy.new(:b) nodeA.other = bProxy aProxy = RGen::MetamodelBuilder::MMProxy.new(:a) cProxy = RGen::MetamodelBuilder::MMProxy.new(:c) nodeB.others = [aProxy, cProxy] unresolved_refs = [ RGen::Instantiator::ReferenceResolver::UnresolvedReference.new(nodeA, "other", bProxy), RGen::Instantiator::ReferenceResolver::UnresolvedReference.new(nodeB, "others", aProxy), RGen::Instantiator::ReferenceResolver::UnresolvedReference.new(nodeB, "others", cProxy) ] return nodeA, nodeB, nodeC, unresolved_refs end def check_model(nodeA, nodeB, nodeC) assert_equal nodeB, nodeA.other assert_equal [], nodeA.others assert_equal nil, nodeB.other assert_equal [nodeA, nodeC], nodeB.others assert_equal nil, nodeC.other assert_equal [], nodeC.others end end rgen-0.7.0/test/template_language_test.rb0000644000004100000410000001433512352210062020521 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/template_language' require 'rgen/metamodel_builder' class TemplateContainerTest < Test::Unit::TestCase TEMPLATES_DIR = File.dirname(__FILE__)+"/template_language_test/templates" OUTPUT_DIR = File.dirname(__FILE__)+"/template_language_test" module MyMM class Chapter attr_reader :title def initialize(title) @title = title end end class Document attr_reader :title, :authors, :chapters attr_accessor :sampleArray def initialize(title) @title = title @chapters = [] @authors = [] end end class Author attr_reader :name, :email def initialize(name, email) @name, @email = name, email end end end module CCodeMM class CArray < RGen::MetamodelBuilder::MMBase has_attr 'name' has_attr 'size', Integer has_attr 'type' end class PrimitiveInitValue < RGen::MetamodelBuilder::MMBase has_attr 'value', Integer end CArray.has_many 'initvalue', PrimitiveInitValue end TEST_MODEL = MyMM::Document.new("SomeDocument") TEST_MODEL.authors << MyMM::Author.new("Martin", "martin@somewhe.re") TEST_MODEL.authors << MyMM::Author.new("Otherguy", "other@somewhereel.se") TEST_MODEL.chapters << MyMM::Chapter.new("Intro") TEST_MODEL.chapters << MyMM::Chapter.new("MainPart") TEST_MODEL.chapters << MyMM::Chapter.new("Summary") TEST_MODEL.sampleArray = CCodeMM::CArray.new(:name => "myArray", :type => "int", :size => 5, :initvalue => (1..5).collect { |v| CCodeMM::PrimitiveInitValue.new(:value => v) }) def test_with_model tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) File.delete(OUTPUT_DIR+"/testout.txt") if File.exists? OUTPUT_DIR+"/testout.txt" tc.expand('root::Root', :for => TEST_MODEL, :indent => 1) result = expected = "" File.open(OUTPUT_DIR+"/testout.txt") {|f| result = f.read} File.open(OUTPUT_DIR+"/expected_result1.txt") {|f| expected = f.read} assert_equal expected, result end def test_immediate_result tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) expected = "" File.open(OUTPUT_DIR+"/expected_result2.txt","rb") {|f| expected = f.read} assert_equal expected, tc.expand('code/array::ArrayDefinition', :for => TEST_MODEL.sampleArray).to_s end def test_indent_string tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) tc.indentString = " " # 2 spaces instead of 3 (default) tc.expand('indent_string_test::IndentStringTest', :for => :dummy) File.open(OUTPUT_DIR+"/indentStringTestDefaultIndent.out","rb") do |f| assert_equal " <- your default here\r\n", f.read end File.open(OUTPUT_DIR+"/indentStringTestTabIndent.out","rb") do |f| assert_equal "\t<- tab\r\n", f.read end end def test_null_context tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) assert_raise StandardError do # the template must raise an exception because it calls expand :for => nil tc.expand('null_context_test::NullContextTestBad', :for => :dummy) end assert_raise StandardError do # the template must raise an exception because it calls expand :foreach => nil tc.expand('null_context_test::NullContextTestBad2', :for => :dummy) end assert_nothing_raised do tc.expand('null_context_test::NullContextTestOk', :for => :dummy) end end def test_no_indent tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) assert_equal " xxx<---\r\n xxx<---\r\n xxx<---\r\n xxx<---\r\n", tc.expand('no_indent_test/test::Test', :for => :dummy) end def test_no_indent2 tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) assert_equal " return xxxx;\r\n", tc.expand("no_indent_test/test2::Test", :for => :dummy) end def test_no_indent3 tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) assert_equal " l1<---\r\n l2\r\n\r\n", tc.expand("no_indent_test/test3::Test", :for => :dummy) end def test_template_resolution tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) assert_equal "Sub1\r\nSub1 in sub1\r\n", tc.expand('template_resolution_test/test::Test', :for => :dummy) assert_equal "Sub1\r\nSub1\r\nSub1 in sub1\r\n", tc.expand('template_resolution_test/sub1::Test', :for => :dummy) end def test_evaluate tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) assert_equal "xx1xxxx2xxxx3xxxx4xx\r\n", tc.expand('evaluate_test/test::Test', :for => :dummy) end def test_define_local tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) assert_equal "Local1\r\n", tc.expand('define_local_test/test::Test', :for => :dummy) assert_raise StandardError do tc.expand('define_local_test/test::TestForbidden', :for => :dummy) end end def test_no_backslash_r tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) expected = "" File.open(OUTPUT_DIR+"/expected_result3.txt") {|f| expected = f.read} assert_equal expected, tc.expand('no_backslash_r_test::Test', :for => :dummy).to_s end def test_callback_indent tc = RGen::TemplateLanguage::DirectoryTemplateContainer.new([MyMM, CCodeMM], OUTPUT_DIR) tc.load(TEMPLATES_DIR) assert_equal("|before callback\r\n |in callback\r\n|after callback\r\n |after iinc\r\n", tc.expand('callback_indent_test/a::caller', :for => :dummy)) end end rgen-0.7.0/test/transformer_test.rb0000644000004100000410000001640712352210062017407 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") $:.unshift File.join(File.dirname(__FILE__),"..","test") require 'test/unit' require 'rgen/transformer' require 'rgen/environment' require 'rgen/util/model_comparator' require 'metamodels/uml13_metamodel' require 'testmodel/class_model_checker' class TransformerTest < Test::Unit::TestCase class ModelIn attr_accessor :name end class ModelInSub < ModelIn end class ModelAIn attr_accessor :name attr_accessor :modelB end class ModelBIn attr_accessor :name attr_accessor :modelA end class ModelCIn attr_accessor :number end class ModelOut attr_accessor :name end class ModelAOut attr_accessor :name attr_accessor :modelB end class ModelBOut attr_accessor :name attr_accessor :modelA end class ModelCOut attr_accessor :number end class MyTransformer < RGen::Transformer attr_reader :modelInTrans_count attr_reader :modelAInTrans_count attr_reader :modelBInTrans_count transform ModelIn, :to => ModelOut do # aribitrary ruby code may be placed before the hash creating the output element @modelInTrans_count ||= 0; @modelInTrans_count += 1 { :name => name } end transform ModelAIn, :to => ModelAOut do @modelAInTrans_count ||= 0; @modelAInTrans_count += 1 { :name => name, :modelB => trans(modelB) } end transform ModelBIn, :to => ModelBOut do @modelBInTrans_count ||= 0; @modelBInTrans_count += 1 { :name => name, :modelA => trans(modelA) } end transform ModelCIn, :to => ModelCOut, :if => :largeNumber do # a method can be called anywhere in a transformer block { :number => duplicateNumber } end transform ModelCIn, :to => ModelCOut, :if => :smallNumber do { :number => number / 2 } end method :largeNumber do number > 1000 end method :smallNumber do number < 500 end method :duplicateNumber do number * 2; end end class MyTransformer2 < RGen::Transformer # check that subclasses are independent (i.e. do not share the rules) transform ModelIn, :to => ModelOut do { :name => name } end end def test_transformer from = ModelIn.new from.name = "TestName" env_out = RGen::Environment.new t = MyTransformer.new(:env_in, env_out) assert t.trans(from).is_a?(ModelOut) assert_equal "TestName", t.trans(from).name assert_equal 1, env_out.elements.size assert_equal env_out.elements.first, t.trans(from) assert_equal 1, t.modelInTrans_count end def test_transformer_chain from = ModelIn.new from.name = "Test1" from2 = ModelIn.new from2.name = "Test2" from3 = ModelIn.new from3.name = "Test3" env_out = RGen::Environment.new elementMap = {} t1 = MyTransformer.new(:env_in, env_out, elementMap) assert t1.trans(from).is_a?(ModelOut) assert_equal "Test1", t1.trans(from).name assert_equal 1, t1.modelInTrans_count # modifying the element map means that following calls of +trans+ will be affected assert_equal( {from => t1.trans(from)}, elementMap ) elementMap.merge!({from2 => :dummy}) assert_equal :dummy, t1.trans(from2) # second transformer based on the element map of the first t2 = MyTransformer.new(:env_in, env_out, elementMap) # second transformer returns same objects assert_equal t1.trans(from).object_id, t2.trans(from).object_id assert_equal :dummy, t2.trans(from2) # and no transformer rule is evaluated at this point assert_equal nil, t2.modelInTrans_count # now transform a new object in second transformer assert t2.trans(from3).is_a?(ModelOut) assert_equal "Test3", t2.trans(from3).name assert_equal 1, t2.modelInTrans_count # the first transformer returns the same object without evaluation of a transformer rule assert_equal t1.trans(from3).object_id, t2.trans(from3).object_id assert_equal 1, t1.modelInTrans_count end def test_transformer_subclass from = ModelInSub.new from.name = "TestName" t = MyTransformer.new assert t.trans(from).is_a?(ModelOut) assert_equal "TestName", t.trans(from).name assert_equal 1, t.modelInTrans_count end def test_transformer_array froms = [ModelIn.new, ModelIn.new] froms[0].name = "M1" froms[1].name = "M2" env_out = RGen::Environment.new t = MyTransformer.new(:env_in, env_out) assert t.trans(froms).is_a?(Array) assert t.trans(froms)[0].is_a?(ModelOut) assert_equal "M1", t.trans(froms)[0].name assert t.trans(froms)[1].is_a?(ModelOut) assert_equal "M2", t.trans(froms)[1].name assert_equal 2, env_out.elements.size assert (t.trans(froms)-env_out.elements).empty? assert_equal 2, t.modelInTrans_count end def test_transformer_cyclic # setup a cyclic dependency between fromA and fromB fromA = ModelAIn.new fromB = ModelBIn.new fromA.modelB = fromB fromA.name = "ModelA" fromB.modelA = fromA fromB.name = "ModelB" env_out = RGen::Environment.new t = MyTransformer.new(:env_in, env_out) # check that trans resolves the cycle correctly (no endless loop) # both elements, fromA and fromB will be transformed with the transformation # of the first element, either fromA or fromB assert t.trans(fromA).is_a?(ModelAOut) assert_equal "ModelA", t.trans(fromA).name assert t.trans(fromA).modelB.is_a?(ModelBOut) assert_equal "ModelB", t.trans(fromA).modelB.name assert_equal t.trans(fromA), t.trans(fromA).modelB.modelA assert_equal t.trans(fromB), t.trans(fromA).modelB assert_equal 2, env_out.elements.size assert (env_out.elements - [t.trans(fromA), t.trans(fromB)]).empty? assert_equal 1, t.modelAInTrans_count assert_equal 1, t.modelBInTrans_count end def test_transformer_conditional froms = [ModelCIn.new, ModelCIn.new, ModelCIn.new] froms[0].number = 100 froms[1].number = 1000 froms[2].number = 2000 env_out = RGen::Environment.new t = MyTransformer.new(:env_in, env_out) assert t.trans(froms).is_a?(Array) assert_equal 2, t.trans(froms).size # this one matched the smallNumber rule assert t.trans(froms[0]).is_a?(ModelCOut) assert_equal 50, t.trans(froms[0]).number # this one did not match any rule assert t.trans(froms[1]).nil? # this one matched the largeNumber rule assert t.trans(froms[2]).is_a?(ModelCOut) assert_equal 4000, t.trans(froms[2]).number # elements in environment are the same as the ones returned assert_equal 2, env_out.elements.size assert (t.trans(froms)-env_out.elements).empty? end class CopyTransformer < RGen::Transformer include UML13 def transform trans(:class => UML13::Package) end UML13.ecore.eClassifiers.each do |c| copy c.instanceClass end end MODEL_DIR = File.join(File.dirname(__FILE__),"testmodel") include Testmodel::ClassModelChecker include RGen::Util::ModelComparator def test_copyTransformer envIn = RGen::Environment.new envOut = RGen::Environment.new EASupport.instantiateUML13FromXMI11(envIn, MODEL_DIR+"/ea_testmodel.xml") CopyTransformer.new(envIn, envOut).transform checkClassModel(envOut) assert modelEqual?( envIn.find(:class => UML13::Model).first, envOut.find(:class => UML13::Model).first) end end rgen-0.7.0/test/util_test.rb0000644000004100000410000000016012352210062016007 0ustar www-datawww-data$:.unshift File.dirname(__FILE__) require 'util/file_cache_map_test' require 'util/pattern_matcher_test' rgen-0.7.0/test/template_language_test/0000755000004100000410000000000012352210062020166 5ustar www-datawww-datargen-0.7.0/test/template_language_test/expected_result3.txt0000644000004100000410000000023012352210062024204 0ustar www-datawww-dataThis file was created on Linux and does not contain \r before \n The next blank line is done by the "nl" command which shall only add a \n, no \r: END rgen-0.7.0/test/template_language_test/indentStringTestTabIndent.out0000644000004100000410000000001112352210062026010 0ustar www-datawww-data <- tab rgen-0.7.0/test/template_language_test/expected_result2.txt0000644000004100000410000000013212352210062024204 0ustar www-datawww-dataint myArray[5] = { 1, 2, 3, 4, 5 }; Text from Root Text from Root rgen-0.7.0/test/template_language_test/indentStringTestDefaultIndent.out0000644000004100000410000000003012352210062026667 0ustar www-datawww-data <- your default here rgen-0.7.0/test/template_language_test/templates/0000755000004100000410000000000012352210062022164 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/root.tpl0000644000004100000410000000152412352210062023672 0ustar www-datawww-data<% define 'Root' do %> <% file 'testout.txt' do %> Document: <%= title %> <%nl%> <%iinc%> by <% expand 'content/author::Author', :foreach => authors, :separator => ' and ' %> <%idec%> <%nl%> Index:<%iinc%> <% for c in chapters %> <% nr = (nr || 0); nr += 1 %> <% expand 'index/chapter::Root', nr, this, :for => c %> <% end %><%idec%> <%nl%> ---------------- <%nl%> Chapters in one line: <% expand 'content/chapter::Root', :foreach => chapters, :separator => ", " %><%nl%> <%nl%> Chapters each in one line: <% expand 'content/chapter::Root', :foreach => chapters, :separator => ",\r\n" %><%nl%> <%nl%> Here are some code examples: <% expand 'code/array::ArrayDefinition', :for => sampleArray %> <% end %> <% end %> <% define 'TextFromRoot' do %> Text from Root <% end %> rgen-0.7.0/test/template_language_test/templates/indent_string_test.tpl0000644000004100000410000000042112352210062026610 0ustar www-datawww-data<% define 'IndentStringTest', :for => Object do %> <% file 'indentStringTestDefaultIndent.out' do %> <%iinc%> <- your default here <%idec%> <% end %> <% file 'indentStringTestTabIndent.out', "\t" do %> <%iinc%> <- tab <%idec%> <% end %> <% end %>rgen-0.7.0/test/template_language_test/templates/no_indent_test/0000755000004100000410000000000012352210062025200 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/no_indent_test/sub1/0000755000004100000410000000000012352210062026052 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/no_indent_test/sub1/no_indent.tpl0000644000004100000410000000010612352210062030545 0ustar www-datawww-data<% define 'NoIndent', :for => Object do %> <---<%nows%> <% end %> rgen-0.7.0/test/template_language_test/templates/no_indent_test/test.tpl0000644000004100000410000000104212352210062026675 0ustar www-datawww-data<% define 'Test', :for => Object do %> <%iinc%> xxx<% expand 'NoIndent1' %> xxx<% expand 'NoIndent2' %> xxx<% expand 'NoIndent3' %> xxx<% expand 'NoIndent4' %> <%idec%> <% end %> <% define 'NoIndent1', :for => Object do %> <---<%nows%> <% end %> <% define 'NoIndent2', :for => Object do %> <% expand 'NoIndent1' %> <% end %> <% define 'NoIndent3', :for => Object do %> <% expand 'no_indent::NoIndent' %> <% end %> <% define 'NoIndent4', :for => Object do %> <% expand 'sub1/no_indent::NoIndent' %> <% end %> rgen-0.7.0/test/template_language_test/templates/no_indent_test/test3.tpl0000644000004100000410000000024212352210062026761 0ustar www-datawww-data<% define 'Test', :for => Object do %> <%iinc%> l1<% expand 'Call1' %> <%idec%> <% end %> <% define 'Call1', :for => Object do %> <--- l2 <% end %> rgen-0.7.0/test/template_language_test/templates/no_indent_test/no_indent.tpl0000644000004100000410000000010612352210062027673 0ustar www-datawww-data<% define 'NoIndent', :for => Object do %> <---<%nows%> <% end %> rgen-0.7.0/test/template_language_test/templates/no_indent_test/test2.tpl0000644000004100000410000000041512352210062026762 0ustar www-datawww-data<% define 'Test', :for => Object do %> <%iinc%><%iinc%> return <% expand 'Call1' %>; <%idec%><%idec%> <% end %> <% define 'Call1', :for => Object do %> x<% expand 'Call2' %><%nows%> <% end %> <% define 'Call2', :for => Object do %> xxx<%nows%> <% end %>rgen-0.7.0/test/template_language_test/templates/no_backslash_r_test.tpl0000644000004100000410000000031512352210062026713 0ustar www-datawww-data<% define 'Test', :for => Object do %> This file was created on Linux and does not contain \r before \n The next blank line is done by the "nl" command which shall only add a \n, no \r: <%nl%>END <% end %>rgen-0.7.0/test/template_language_test/templates/index/0000755000004100000410000000000012352210062023273 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/index/c/0000755000004100000410000000000012352210062023515 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/index/c/cmod.tpl0000644000004100000410000000006412352210062025160 0ustar www-datawww-data<% define 'cmod' do %>Module C is special !<% end %>rgen-0.7.0/test/template_language_test/templates/index/chapter.tpl0000644000004100000410000000013112352210062025435 0ustar www-datawww-data<% define 'Root' do |idx, doc| %> <%= idx%> <%= title %> in <%= doc.title %> <% end %>rgen-0.7.0/test/template_language_test/templates/define_local_test/0000755000004100000410000000000012352210062025627 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/define_local_test/local.tpl0000644000004100000410000000023112352210062027436 0ustar www-datawww-data<% define 'CallLocal1', :for => Object do %> <% expand 'Local1' %> <% end %> <% define_local 'Local1', :for => Object do %> Local1 <% end %> rgen-0.7.0/test/template_language_test/templates/define_local_test/test.tpl0000644000004100000410000000026412352210062027331 0ustar www-datawww-data<% define 'Test', :for => Object do %> <% expand 'local::CallLocal1' %> <% end %> <% define 'TestForbidden', :for => Object do %> <% expand 'local::Local1' %> <% end %> rgen-0.7.0/test/template_language_test/templates/template_resolution_test/0000755000004100000410000000000012352210062027321 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/template_resolution_test/sub1.tpl0000644000004100000410000000030212352210062030707 0ustar www-datawww-data<% define 'Sub1', :for => Object do %> Sub1 <% end %> <% define 'Test', :for => Object do %> <% expand 'Sub1' %> <% expand 'sub1::Sub1' %> <% expand 'sub1/sub1::Sub1' %> <% end %> rgen-0.7.0/test/template_language_test/templates/template_resolution_test/sub1/0000755000004100000410000000000012352210062030173 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/template_resolution_test/sub1/sub1.tpl0000644000004100000410000000010012352210062031555 0ustar www-datawww-data<% define 'Sub1', :for => Object do %> Sub1 in sub1 <% end %>rgen-0.7.0/test/template_language_test/templates/template_resolution_test/test.tpl0000644000004100000410000000015612352210062031023 0ustar www-datawww-data<% define 'Test', :for => Object do %> <% expand 'sub1::Sub1' %> <% expand 'sub1/sub1::Sub1' %> <% end %>rgen-0.7.0/test/template_language_test/templates/code/0000755000004100000410000000000012352210062023076 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/code/array.tpl0000644000004100000410000000060112352210062024732 0ustar www-datawww-data<% define 'ArrayDefinition', :for => CArray do %> <%= getType %> <%= name %>[<%= size %>] = {<%iinc%> <% expand 'InitValue', :foreach => initvalue, :separator => ",\r\n" %><%nl%><%idec%> }; <% expand '../root::TextFromRoot' %> <% expand '/root::TextFromRoot' %> <% end %> <% define 'InitValue', :for => PrimitiveInitValue do %> <%= value %><%nows%> <% end %> rgen-0.7.0/test/template_language_test/templates/content/0000755000004100000410000000000012352210062023636 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/content/chapter.tpl0000644000004100000410000000012612352210062026004 0ustar www-datawww-data<% define 'Root', :for => Chapter do %> *** <%= title %> ***<%nows%> <% end %>rgen-0.7.0/test/template_language_test/templates/content/author.tpl0000644000004100000410000000030512352210062025657 0ustar www-datawww-data<% define 'Author', :for => Author do %> <% expand 'SubAuthor' %> <% end %> <% define 'SubAuthor', :for => Author do %> <%= name %>, EMail: <%= email.sub('@','(at)') %><%nows%> <% end %> rgen-0.7.0/test/template_language_test/templates/null_context_test.tpl0000644000004100000410000000071212352210062026462 0ustar www-datawww-data<% define 'NullContextTestBad', :for => Object do %> <%# this must raise an exception %> <% expand 'Callee', :for => nil %> <% end %> <% define 'NullContextTestBad2', :for => Object do %> <%# this must raise an exception %> <% expand 'Callee', :foreach => nil %> <% end %> <% define 'NullContextTestOk', :for => Object do %> <%# however this is ok %> <% expand 'Callee' %> <% end %> <% define 'Callee', :for => Object do %> <% end %>rgen-0.7.0/test/template_language_test/templates/evaluate_test/0000755000004100000410000000000012352210062025031 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/evaluate_test/test.tpl0000644000004100000410000000030212352210062026524 0ustar www-datawww-data<% define 'Test', :for => Object do %> <%= [1,2,3,4].collect{|n| evaluate 'Eval', :for => n}.join %> <% end %> <% define 'Eval', :for => Object do %> xx<%= this %>xx<%nows%> <% end %> rgen-0.7.0/test/template_language_test/templates/callback_indent_test/0000755000004100000410000000000012352210062026320 5ustar www-datawww-datargen-0.7.0/test/template_language_test/templates/callback_indent_test/a.tpl0000644000004100000410000000034312352210062027261 0ustar www-datawww-data<% define 'caller', :for => Object do %> |before callback <% expand 'b::do_callback' %> |after callback <%iinc%> |after iinc <% end %> <% define 'callback', :for => Object do %> |in callback <% end %> rgen-0.7.0/test/template_language_test/templates/callback_indent_test/b.tpl0000644000004100000410000000016112352210062027260 0ustar www-datawww-data<% define 'do_callback', :for => Object do %> <%iinc%> <% expand 'a::callback' %> <%idec%> <% end %> rgen-0.7.0/test/template_language_test/testout.txt0000644000004100000410000000110512352210062022433 0ustar www-datawww-data Document: SomeDocument by Martin, EMail: martin(at)somewhe.re and Otherguy, EMail: other(at)somewhereel.se Index: 1 Intro in SomeDocument 2 MainPart in SomeDocument 3 Summary in SomeDocument ---------------- Chapters in one line: *** Intro ***, *** MainPart ***, *** Summary *** Chapters each in one line: *** Intro ***, *** MainPart ***, *** Summary *** Here are some code examples: int myArray[5] = { 1, 2, 3, 4, 5 }; Text from Root Text from Root rgen-0.7.0/test/template_language_test/expected_result1.txt0000644000004100000410000000110512352210062024204 0ustar www-datawww-data Document: SomeDocument by Martin, EMail: martin(at)somewhe.re and Otherguy, EMail: other(at)somewhereel.se Index: 1 Intro in SomeDocument 2 MainPart in SomeDocument 3 Summary in SomeDocument ---------------- Chapters in one line: *** Intro ***, *** MainPart ***, *** Summary *** Chapters each in one line: *** Intro ***, *** MainPart ***, *** Summary *** Here are some code examples: int myArray[5] = { 1, 2, 3, 4, 5 }; Text from Root Text from Root rgen-0.7.0/test/rgen_test.rb0000644000004100000410000000133112352210062015766 0ustar www-datawww-data$:.unshift File.dirname(__FILE__) require 'test/unit' require 'array_extensions_test' require 'ea_instantiator_test' require 'ecore_self_test' require 'environment_test' require 'metamodel_builder_test' require 'metamodel_roundtrip_test' require 'output_handler_test' require 'template_language_test' require 'transformer_test' require 'xml_instantiator_test' require 'ea_serializer_test' require 'model_builder_test' require 'method_delegation_test' require 'json_test' require 'reference_resolver_test' require 'qualified_name_resolver_test' require 'metamodel_order_test' require 'metamodel_from_ecore_test' require 'util_test' require 'model_fragment_test' require 'qualified_name_provider_test' rgen-0.7.0/test/model_builder_test.rb0000644000004100000410000000033712352210062017646 0ustar www-datawww-data$:.unshift File.dirname(__FILE__) + "/../lib" require 'model_builder/builder_test' require 'model_builder/serializer_test' require 'model_builder/builder_context_test' require 'model_builder/reference_resolver_test' rgen-0.7.0/test/metamodel_roundtrip_test.rb0000644000004100000410000000670612352210062021123 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/array_extensions' require 'rgen/util/model_comparator' require 'mmgen/metamodel_generator' require 'rgen/instantiator/ecore_xml_instantiator' require 'rgen/serializer/xmi20_serializer' class MetamodelRoundtripTest < Test::Unit::TestCase TEST_DIR = File.dirname(__FILE__)+"/metamodel_roundtrip_test" include MMGen::MetamodelGenerator include RGen::Util::ModelComparator module Regenerated Inside = binding end def test_generator require TEST_DIR+"/TestModel.rb" outfile = TEST_DIR+"/TestModel_Regenerated.rb" generateMetamodel(HouseMetamodel.ecore, outfile) File.open(outfile) do |f| eval(f.read, Regenerated::Inside) end assert modelEqual?(HouseMetamodel.ecore, Regenerated::HouseMetamodel.ecore, ["instanceClassName"]) end module UMLRegenerated Inside = binding end def test_generate_from_ecore outfile = TEST_DIR+"/houseMetamodel_from_ecore.rb" env = RGen::Environment.new File.open(TEST_DIR+"/houseMetamodel.ecore") { |f| ECoreXMLInstantiator.new(env).instantiate(f.read) } rootpackage = env.find(:class => RGen::ECore::EPackage).first rootpackage.name = "HouseMetamodel" generateMetamodel(rootpackage, outfile) File.open(outfile) do |f| eval(f.read, UMLRegenerated::Inside, "test_eval", 0) end end def test_ecore_serializer require TEST_DIR+"/TestModel.rb" File.open(TEST_DIR+"/houseMetamodel_Regenerated.ecore","w") do |f| ser = RGen::Serializer::XMI20Serializer.new(f) ser.serialize(HouseMetamodel.ecore) end end BuiltinTypesTestEcore = TEST_DIR+"/using_builtin_types.ecore" def test_ecore_serializer_builtin_types mm = RGen::ECore::EPackage.new(:name => "P1", :eClassifiers => [ RGen::ECore::EClass.new(:name => "C1", :eStructuralFeatures => [ RGen::ECore::EAttribute.new(:name => "a1", :eType => RGen::ECore::EString), RGen::ECore::EAttribute.new(:name => "a2", :eType => RGen::ECore::EInt), RGen::ECore::EAttribute.new(:name => "a3", :eType => RGen::ECore::ELong), RGen::ECore::EAttribute.new(:name => "a4", :eType => RGen::ECore::EFloat), RGen::ECore::EAttribute.new(:name => "a5", :eType => RGen::ECore::EBoolean) ]) ]) outfile = TEST_DIR+"/using_builtin_types_serialized.ecore" File.open(outfile, "w") do |f| ser = RGen::Serializer::XMI20Serializer.new(f) ser.serialize(mm) end assert_equal(File.read(BuiltinTypesTestEcore), File.read(outfile)) end def test_ecore_instantiator_builtin_types env = RGen::Environment.new File.open(BuiltinTypesTestEcore) { |f| ECoreXMLInstantiator.new(env).instantiate(f.read) } a1 = env.find(:class => RGen::ECore::EAttribute, :name => "a1").first assert_equal(RGen::ECore::EString, a1.eType) a2 = env.find(:class => RGen::ECore::EAttribute, :name => "a2").first assert_equal(RGen::ECore::EInt, a2.eType) a3 = env.find(:class => RGen::ECore::EAttribute, :name => "a3").first assert_equal(RGen::ECore::ELong, a3.eType) a4 = env.find(:class => RGen::ECore::EAttribute, :name => "a4").first assert_equal(RGen::ECore::EFloat, a4.eType) a5 = env.find(:class => RGen::ECore::EAttribute, :name => "a5").first assert_equal(RGen::ECore::EBoolean, a5.eType) end end rgen-0.7.0/test/metamodel_roundtrip_test/0000755000004100000410000000000012352210062020565 5ustar www-datawww-datargen-0.7.0/test/metamodel_roundtrip_test/houseMetamodel.ecore0000644000004100000410000000456412352210062024570 0ustar www-datawww-data
rgen-0.7.0/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb0000644000004100000410000000251412352210062026267 0ustar www-datawww-datarequire 'rgen/metamodel_builder' module HouseMetamodel extend RGen::MetamodelBuilder::ModuleExtension include RGen::MetamodelBuilder::DataTypes SexEnum = Enum.new(:name => 'SexEnum', :literals =>[ :male, :female ]) class House < RGen::MetamodelBuilder::MMBase annotation :source => "bla", :details => {'a' => 'b'} has_attr 'address', String, :changeable => false end class MeetingPlace < RGen::MetamodelBuilder::MMBase end class Person < RGen::MetamodelBuilder::MMBase has_attr 'sex', HouseMetamodel::SexEnum has_attr 'id', Long has_many_attr 'nicknames', String end module Rooms extend RGen::MetamodelBuilder::ModuleExtension include RGen::MetamodelBuilder::DataTypes class Room < RGen::MetamodelBuilder::MMBase end class Bathroom < Room end class Kitchen < RGen::MetamodelBuilder::MMMultiple(Room, HouseMetamodel::MeetingPlace) end end end HouseMetamodel::House.has_one 'bathroom', HouseMetamodel::Rooms::Bathroom, :lowerBound => 1 HouseMetamodel::House.one_to_one 'kitchen', HouseMetamodel::Rooms::Kitchen, 'house', :lowerBound => 1 HouseMetamodel::House.contains_many 'room', HouseMetamodel::Rooms::Room, 'house' HouseMetamodel::Person.has_many 'house', HouseMetamodel::House rgen-0.7.0/test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore0000644000004100000410000003775312352210062027103 0ustar www-datawww-data
rgen-0.7.0/test/metamodel_roundtrip_test/TestModel.rb0000644000004100000410000001215712352210062023020 0ustar www-datawww-datarequire 'rgen/metamodel_builder' module HouseMetamodel extend RGen::MetamodelBuilder::ModuleExtension include RGen::MetamodelBuilder::DataTypes SexEnum = Enum.new(:name => "SexEnum", :literals => [ :male, :female ]) # TODO: Datatypes # AggregationKind = Enum.new([ :none, :aggregate, :composite ]) class MeetingPlace < RGen::MetamodelBuilder::MMBase annotation :source => "testmodel", :details => { 'complexity' => '1', 'date_created' => '2006-07-12 08:40:46', 'date_modified' => '2006-07-12 08:44:02', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' } end class Person < RGen::MetamodelBuilder::MMBase annotation 'complexity' => '1', 'date_created' => '2006-06-27 08:34:23', 'date_modified' => '2006-06-27 08:34:26', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' has_attr 'sex', SexEnum has_attr 'id', Long has_many_attr 'nicknames', String end class House < RGen::MetamodelBuilder::MMBase annotation 'complexity' => '1', 'date_created' => '2005-09-16 19:52:18', 'date_modified' => '2006-02-28 08:29:19', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'stereotype' => 'dummy', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' has_attr 'size', Integer has_attr 'module' has_attr 'address', String, :changeable => false do annotation 'collection' => 'false', 'containment' => 'Not Specified', 'derived' => '0', 'duplicates' => '0', 'ea_guid' => '{A8DF581B-9AC6-4f75-AB48-8FAEDFC6E068}', 'lowerBound' => '1', 'ordered' => '0', 'position' => '0', 'styleex' => 'volatile=0;', 'type' => 'String', 'upperBound' => '1' end end module Rooms extend RGen::MetamodelBuilder::ModuleExtension class Room < RGen::MetamodelBuilder::MMBase abstract annotation 'complexity' => '1', 'date_created' => '2005-09-16 19:52:28', 'date_modified' => '2006-06-22 21:15:25', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' end class Bathroom < Room annotation 'complexity' => '1', 'date_created' => '2006-06-27 08:32:25', 'date_modified' => '2006-06-27 08:34:23', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' end class Kitchen < RGen::MetamodelBuilder::MMMultiple(HouseMetamodel::MeetingPlace, Room) annotation 'complexity' => '1', 'date_created' => '2005-11-30 19:26:13', 'date_modified' => '2006-06-22 21:15:34', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' end end module DependingOnRooms extend RGen::MetamodelBuilder::ModuleExtension class RoomSub < Rooms::Room end end end HouseMetamodel::Person.has_many 'home', HouseMetamodel::House do annotation 'containment' => 'Unspecified' end HouseMetamodel::House.has_one 'bathroom', HouseMetamodel::Rooms::Bathroom, :lowerBound => 1, :transient => true HouseMetamodel::House.one_to_one 'kitchen', HouseMetamodel::Rooms::Kitchen, 'house', :lowerBound => 1, :opposite_lowerBound => 1 do annotation 'containment' => 'Unspecified' opposite_annotation 'containment' => 'Unspecified' end HouseMetamodel::House.contains_many 'room', HouseMetamodel::Rooms::Room, 'house', :lowerBound => 1 do # only an opposite annotation opposite_annotation 'containment' => 'Unspecified' end rgen-0.7.0/test/metamodel_roundtrip_test/using_builtin_types.ecore0000644000004100000410000000331712352210062025707 0ustar www-datawww-data rgen-0.7.0/test/metamodel_roundtrip_test/TestModel_Regenerated.rb0000644000004100000410000001214712352210062025324 0ustar www-datawww-datarequire 'rgen/metamodel_builder' module HouseMetamodel extend RGen::MetamodelBuilder::ModuleExtension include RGen::MetamodelBuilder::DataTypes SexEnum = Enum.new(:name => 'SexEnum', :literals =>[ :male, :female ]) class MeetingPlace < RGen::MetamodelBuilder::MMBase annotation :source => "testmodel", :details => {'complexity' => '1', 'date_created' => '2006-07-12 08:40:46', 'date_modified' => '2006-07-12 08:44:02', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'} end class Person < RGen::MetamodelBuilder::MMBase annotation 'complexity' => '1', 'date_created' => '2006-06-27 08:34:23', 'date_modified' => '2006-06-27 08:34:26', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' has_attr 'sex', HouseMetamodel::SexEnum has_attr 'id', Long has_many_attr 'nicknames', String end class House < RGen::MetamodelBuilder::MMBase annotation 'complexity' => '1', 'date_created' => '2005-09-16 19:52:18', 'date_modified' => '2006-02-28 08:29:19', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'stereotype' => 'dummy', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' has_attr 'size', Integer has_attr 'module', String has_attr 'address', String, :changeable => false do annotation 'collection' => 'false', 'containment' => 'Not Specified', 'derived' => '0', 'duplicates' => '0', 'ea_guid' => '{A8DF581B-9AC6-4f75-AB48-8FAEDFC6E068}', 'lowerBound' => '1', 'ordered' => '0', 'position' => '0', 'styleex' => 'volatile=0;', 'type' => 'String', 'upperBound' => '1' end end module Rooms extend RGen::MetamodelBuilder::ModuleExtension include RGen::MetamodelBuilder::DataTypes class Room < RGen::MetamodelBuilder::MMBase abstract annotation 'complexity' => '1', 'date_created' => '2005-09-16 19:52:28', 'date_modified' => '2006-06-22 21:15:25', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' end class Bathroom < Room annotation 'complexity' => '1', 'date_created' => '2006-06-27 08:32:25', 'date_modified' => '2006-06-27 08:34:23', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' end class Kitchen < RGen::MetamodelBuilder::MMMultiple(HouseMetamodel::MeetingPlace, Room) annotation 'complexity' => '1', 'date_created' => '2005-11-30 19:26:13', 'date_modified' => '2006-06-22 21:15:34', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0' end end module DependingOnRooms extend RGen::MetamodelBuilder::ModuleExtension include RGen::MetamodelBuilder::DataTypes class RoomSub < HouseMetamodel::Rooms::Room end end end HouseMetamodel::Person.has_many 'home', HouseMetamodel::House do annotation 'containment' => 'Unspecified' end HouseMetamodel::House.has_one 'bathroom', HouseMetamodel::Rooms::Bathroom, :lowerBound => 1, :transient => true HouseMetamodel::House.one_to_one 'kitchen', HouseMetamodel::Rooms::Kitchen, 'house', :lowerBound => 1, :opposite_lowerBound => 1 do annotation 'containment' => 'Unspecified' opposite_annotation 'containment' => 'Unspecified' end HouseMetamodel::House.contains_many 'room', HouseMetamodel::Rooms::Room, 'house', :lowerBound => 1 do opposite_annotation 'containment' => 'Unspecified' end rgen-0.7.0/test/metamodel_roundtrip_test/using_builtin_types_serialized.ecore0000644000004100000410000000333012352210062030115 0ustar www-datawww-data rgen-0.7.0/test/method_delegation_test.rb0000644000004100000410000001317012352210062020512 0ustar www-datawww-data$:.unshift File.dirname(__FILE__) + "/../lib" require 'test/unit' require 'rgen/util/method_delegation' class MethodDelegationTest < Test::Unit::TestCase include RGen class TestDelegate attr_accessor :mode, :callcount def common_delegated(delegator) @callcount ||= 0 @callcount += 1 case @mode when :continue throw :continue when :delegatorId delegator.object_id when :return7 7 end end alias to_s_delegated common_delegated alias methodInSingleton_delegated common_delegated alias class_delegated common_delegated alias artificialMethod_delegated common_delegated end class ConstPathElement < Module def self.const_missing_delegated(delegator, const) ConstPathElement.new(const) end def initialize(name, parent=nil) @name = name.to_s @parent = parent end def const_missing(const) ConstPathElement.new(const, self) end def to_s if @parent @parent.to_s+"::"+@name else @name end end end # missing: check with multiple params and block param def test_method_defined_in_singleton # delegator is an Array delegator = [] # delegating method is a method defined in the singleton class class << delegator def methodInSingleton "result from method in singleton" end end checkDelegation(delegator, "methodInSingleton", "result from method in singleton") end def test_method_defined_in_class # delegator is a String delegator = "Delegator1" checkDelegation(delegator, "to_s", "Delegator1") end def test_method_defined_in_superclass # delegator is an instance of a new anonymous class delegator = Class.new.new # delegating method is +object_id+ which is defined in the superclass checkDelegation(delegator, "class", delegator.class) end def test_new_method # delegator is an String delegator = "Delegator2" # delegating method is a new method which does not exist on String checkDelegation(delegator, "artificialMethod", delegator.object_id, true) end def test_const_missing surroundingModule = Module.nesting.first Util::MethodDelegation.registerDelegate(ConstPathElement, surroundingModule, "const_missing") assert_equal "SomeArbitraryConst", SomeArbitraryConst.to_s assert_equal "AnotherConst::A::B::C", AnotherConst::A::B::C.to_s Util::MethodDelegation.unregisterDelegate(ConstPathElement, surroundingModule, "const_missing") assert_raise NameError do SomeArbitraryConst end end def checkDelegation(delegator, method, originalResult, newMethod=false) delegate1 = TestDelegate.new delegate2 = TestDelegate.new Util::MethodDelegation.registerDelegate(delegate1, delegator, method) Util::MethodDelegation.registerDelegate(delegate2, delegator, method) assert delegator.respond_to?(:_methodDelegates) if newMethod assert !delegator.respond_to?("#{method}_delegate_original".to_sym) else assert delegator.respond_to?("#{method}_delegate_original".to_sym) end # check delegator parameter delegate1.mode = :delegatorId assert_equal delegator.object_id, delegator.send(method) delegate1.callcount = 0 delegate2.callcount = 0 delegate1.mode = :return7 # delegate1 returns a value assert_equal 7, delegator.send(method) assert_equal 1, delegate1.callcount # delegate2 is not called assert_equal 0, delegate2.callcount delegate1.mode = :nothing # delegate1 just exits and thus returns nil assert_equal nil, delegator.send(method) assert_equal 2, delegate1.callcount # delegate2 is not called assert_equal 0, delegate2.callcount delegate1.mode = :continue delegate2.mode = :return7 # delegate1 is called but continues # delegate2 returns a value assert_equal 7, delegator.send(method) assert_equal 3, delegate1.callcount assert_equal 1, delegate2.callcount delegate1.mode = :continue delegate2.mode = :continue # both delegates continue, the original method returns its value checkCallOriginal(delegator, method, originalResult, newMethod) # both delegates are called though assert_equal 4, delegate1.callcount assert_equal 2, delegate2.callcount # calling unregister with a non existing method has no effect Util::MethodDelegation.unregisterDelegate(delegate1, delegator, "xxx") Util::MethodDelegation.unregisterDelegate(delegate1, delegator, method) checkCallOriginal(delegator, method, originalResult, newMethod) # delegate1 not called any more assert_equal 4, delegate1.callcount # delegate2 is still called assert_equal 3, delegate2.callcount Util::MethodDelegation.unregisterDelegate(delegate2, delegator, method) checkCallOriginal(delegator, method, originalResult, newMethod) # both delegates not called any more assert_equal 4, delegate1.callcount assert_equal 3, delegate2.callcount # after all delegates were unregistered, singleton class should be clean assert !delegator.respond_to?(:_methodDelegates) end def checkCallOriginal(delegator, method, originalResult, newMethod) if newMethod assert_raise NoMethodError do result = delegator.send(method) end else result = delegator.send(method) assert_equal originalResult, result end end end rgen-0.7.0/test/xml_instantiator_test/0000755000004100000410000000000012352210062020107 5ustar www-datawww-datargen-0.7.0/test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb0000644000004100000410000000332012352210062026554 0ustar www-datawww-datarequire 'rgen/instantiator/default_xml_instantiator' require 'rgen/environment' require 'rgen/ecore/ecore' require 'xml_instantiator_test/simple_xmi_metamodel' # SimpleXMIECoreInstantiator demonstrates the usage of the DefaultXMLInstantiator. # It can be used to instantiate an ECore model from an XMI description # produced by Enterprise Architect. # # Note however, that this is *not* the recommended way to read an EA model. # See EAInstantiatorTest for the clean way to do this. # # This example shows how arbitrary XML content can be used to instantiate # an implicit metamodel. The resulting model is transformed into a simple # ECore model. # # See XMLInstantiatorTest for an example of how to use this class. # class SimpleXMIECoreInstantiator < RGen::Instantiator::DefaultXMLInstantiator map_tag_ns "omg.org/UML1.3", SimpleXMIMetaModel::UML resolve_by_id :typeClass, :src => :type, :id => :xmi_id resolve_by_id :subtypeClass, :src => :subtype, :id => :xmi_id resolve_by_id :supertypeClass, :src => :supertype, :id => :xmi_id def initialize @envXMI = RGen::Environment.new super(@envXMI, SimpleXMIMetaModel, true) end def new_object(node) if node.tag == "EAStub" class_name = saneClassName(node.attributes["UMLType"]) mod = XMIMetaModel::UML build_on_error(NameError, :build_class, class_name, mod) do mod.const_get(class_name).new end else super end end # This method does the actual work. def instantiateECoreModel(envOut, str) instantiate(str) require 'xml_instantiator_test/simple_xmi_to_ecore' SimpleXmiToECore.new(@envXMI,envOut).transform end end rgen-0.7.0/test/xml_instantiator_test/simple_xmi_to_ecore.rb0000644000004100000410000000567312352210062024474 0ustar www-datawww-datarequire 'rgen/transformer' require 'rgen/ecore/ecore' require 'rgen/array_extensions' require 'xml_instantiator_test/simple_xmi_metamodel' class SimpleXmiToECore < RGen::Transformer include RGen::ECore class MapHelper def initialize(keyMethod,valueMethod,elements) @keyMethod, @valueMethod, @elements = keyMethod, valueMethod, elements end def [](key) return @elements.select{|e| e.send(@keyMethod) == key}.first.send(@valueMethod) rescue NoMethodError nil end end class TaggedValueHelper < MapHelper def initialize(element) super('tag','value',element.modelElement_taggedValue.taggedValue) end end # Do the actual transformation. # Input and output environment have to be provided to the transformer constructor. def transform trans(:class => SimpleXMIMetaModel::UML::Clazz) end transform SimpleXMIMetaModel::UML::Package, :to => EPackage do { :name => name, :eSuperPackage => trans(parent.parent.is_a?(SimpleXMIMetaModel::UML::Package) ? parent.parent : nil) } end transform SimpleXMIMetaModel::UML::Clazz, :to => EClass do { :name => name, :ePackage => trans(parent.parent.is_a?(SimpleXMIMetaModel::UML::Package) ? parent.parent : nil), :eStructuralFeatures => trans(classifier_feature.attribute + associationEnds), :eOperations => trans(classifier_feature.operation), :eSuperTypes => trans(generalizationsAsSubtype.supertypeClass), :eAnnotations => [ EAnnotation.new(:details => trans(modelElement_taggedValue.taggedValue)) ] } end transform SimpleXMIMetaModel::UML::TaggedValue, :to => EStringToStringMapEntry do { :key => tag, :value => value} end transform SimpleXMIMetaModel::UML::Attribute, :to => EAttribute do typemap = { "String" => EString, "boolean" => EBoolean, "int" => EInt, "long" => ELong, "float" => EFloat } tv = TaggedValueHelper.new(@current_object) { :name => name, :eType => typemap[tv['type']], :eAnnotations => [ EAnnotation.new(:details => trans(modelElement_taggedValue.taggedValue)) ] } end transform SimpleXMIMetaModel::UML::Operation, :to => EOperation do { :name => name } end transform SimpleXMIMetaModel::UML::AssociationEnd, :to => EReference, :if => :isReference do { :eType => trans(otherEnd.typeClass), :name => otherEnd.name, :eOpposite => trans(otherEnd), :lowerBound => (otherEnd.multiplicity || '0').split('..').first.to_i, :upperBound => (otherEnd.multiplicity || '1').split('..').last.gsub('*','-1').to_i, :containment => (aggregation == 'composite'), :eAnnotations => [ EAnnotation.new(:details => trans(modelElement_taggedValue.taggedValue)) ] } end method :isReference do otherEnd.isNavigable == 'true' || # composite assocations are bidirectional aggregation == 'composite' || otherEnd.aggregation == 'composite' end end rgen-0.7.0/test/xml_instantiator_test/simple_ecore_model_checker.rb0000644000004100000410000001011412352210062025743 0ustar www-datawww-datarequire 'rgen/ecore/ecore' # This "light" version of the ECore model checker is used to check the # model produced by the XMLInstantiatorTest only. # module SimpleECoreModelChecker include RGen::ECore def checkECoreModel(env) # check main package mainPackage = env.elements.select {|e| e.is_a? EPackage and e.name == "HouseMetamodel"}.first assert_not_nil mainPackage # check Rooms package assert mainPackage.eSubpackages.is_a?(Array) assert_equal 1, mainPackage.eSubpackages.size assert mainPackage.eSubpackages[0].is_a?(EPackage) roomsPackage = mainPackage.eSubpackages[0] assert_equal "Rooms", roomsPackage.name # check main package classes assert mainPackage.eClassifiers.is_a?(Array) assert_equal 3, mainPackage.eClassifiers.size assert mainPackage.eClassifiers.all?{|c| c.is_a?(EClass)} houseClass = mainPackage.eClassifiers.select{|c| c.name == "House"}.first personClass = mainPackage.eClassifiers.select{|c| c.name == "Person"}.first meetingPlaceClass = mainPackage.eClassifiers.select{|c| c.name == "MeetingPlace"}.first assert_not_nil houseClass assert_not_nil personClass assert_not_nil meetingPlaceClass # check Rooms package classes assert roomsPackage.eClassifiers.is_a?(Array) assert_equal 3, roomsPackage.eClassifiers.size assert roomsPackage.eClassifiers.all?{|c| c.is_a?(EClass)} roomClass = roomsPackage.eClassifiers.select{|c| c.name == "Room"}.first kitchenClass = roomsPackage.eClassifiers.select{|c| c.name == "Kitchen"}.first bathroomClass = roomsPackage.eClassifiers.select{|c| c.name == "Bathroom"}.first assert_not_nil roomClass assert_not_nil kitchenClass assert_not_nil bathroomClass # check Room inheritance assert kitchenClass.eSuperTypes.is_a?(Array) assert_equal 2, kitchenClass.eSuperTypes.size assert_equal roomClass.object_id, kitchenClass.eSuperTypes.select{|c| c.name == "Room"}.first.object_id assert_equal meetingPlaceClass.object_id, kitchenClass.eSuperTypes.select{|c| c.name == "MeetingPlace"}.first.object_id assert bathroomClass.eSuperTypes.is_a?(Array) assert_equal 1, bathroomClass.eSuperTypes.size assert_equal roomClass.object_id, bathroomClass.eSuperTypes[0].object_id # check House-Room "part of" association assert houseClass.eAllContainments.eType.is_a?(Array) assert_equal 1, houseClass.eAllContainments.eType.size roomRef = houseClass.eAllContainments.first assert_equal roomClass.object_id, roomRef.eType.object_id assert_equal "room", roomRef.name assert_equal 1, roomRef.lowerBound assert_equal(-1, roomRef.upperBound) assert_not_nil roomRef.eOpposite assert_equal houseClass.object_id, roomRef.eOpposite.eType.object_id partOfRefs = roomClass.eReferences.select{|r| r.eOpposite && r.eOpposite.containment} assert_equal 1, partOfRefs.size assert_equal houseClass.object_id, partOfRefs.first.eType.object_id assert_equal "house", partOfRefs.first.name assert_equal roomRef.object_id, partOfRefs.first.eOpposite.object_id # check House OUT associations assert houseClass.eReferences.is_a?(Array) assert_equal 3, houseClass.eReferences.size bathRef = houseClass.eReferences.find {|e| e.name == "bathroom"} kitchenRef = houseClass.eReferences.find {|e| e.name == "kitchen"} roomRef = houseClass.eReferences.find {|e| e.name == "room"} assert_not_nil bathRef assert_nil bathRef.eOpposite assert_not_nil kitchenRef assert_not_nil roomRef assert_equal 1, kitchenRef.lowerBound assert_equal 1, kitchenRef.upperBound assert_equal 1, roomRef.lowerBound assert_equal(-1, roomRef.upperBound) # check House IN associations houseInRefs = env.find(:class => EReference, :eType => houseClass) assert_equal 3, houseInRefs.size homeEnd = houseInRefs.find{|e| e.name == "home"} assert_not_nil homeEnd assert_equal 0, homeEnd.lowerBound assert_equal(-1, homeEnd.upperBound) end end rgen-0.7.0/test/xml_instantiator_test/simple_xmi_metamodel.rb0000644000004100000410000000216412352210062024634 0ustar www-datawww-data# This is an extension of the implicit metamodel created by the # DefaultXMLInstantiator when it reads an Enterprise Architect # XMI file. # module SimpleXMIMetaModel module UML include RGen::MetamodelBuilder class Classifier_feature < MMBase end class ClassifierRole < MMBase end class Clazz < ClassifierRole end class Interface < ClassifierRole end class Operation < MMBase end class Generalization < MMBase end class ModelElement_stereotype < MMBase end class AssociationEnd < MMBase module ClassModule def otherEnd parent.associationEnd.find{|ae| ae != self} end end end class AssociationEndRole < MMBase end ClassifierRole.one_to_many 'associationEnds', AssociationEnd, 'typeClass' ClassifierRole.one_to_many 'associationEndRoles', AssociationEndRole, 'typeClass' Clazz.one_to_many 'generalizationsAsSubtype', Generalization, 'subtypeClass' Clazz.one_to_many 'generalizationsAsSupertype', Generalization, 'supertypeClass' end end rgen-0.7.0/test/json_test.rb0000644000004100000410000001452212352210062016012 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/environment' require 'rgen/metamodel_builder' require 'rgen/serializer/json_serializer' require 'rgen/instantiator/json_instantiator' class JsonTest < Test::Unit::TestCase module TestMM extend RGen::MetamodelBuilder::ModuleExtension class TestNode < RGen::MetamodelBuilder::MMBase has_attr 'text', String has_attr 'integer', Integer has_attr 'float', Float has_one 'other', TestNode contains_many 'childs', TestNode, 'parent' end end module TestMMData extend RGen::MetamodelBuilder::ModuleExtension # class "Data" exists in the standard Ruby namespace class Data < RGen::MetamodelBuilder::MMBase has_attr 'notTheBuiltin', String end end module TestMMSubpackage extend RGen::MetamodelBuilder::ModuleExtension module SubPackage extend RGen::MetamodelBuilder::ModuleExtension class Data < RGen::MetamodelBuilder::MMBase has_attr 'notTheBuiltin', String end class Data2 < RGen::MetamodelBuilder::MMBase has_attr 'data2', String end end end class StringWriter < String alias write concat end def test_json_serializer testModel = TestMM::TestNode.new(:text => "some text", :childs => [ TestMM::TestNode.new(:text => "child")]) output = StringWriter.new ser = RGen::Serializer::JsonSerializer.new(output) assert_equal %q({ "_class": "TestNode", "text": "some text", "childs": [ { "_class": "TestNode", "text": "child" }] }), ser.serialize(testModel) end def test_json_instantiator env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM) inst.instantiate(%q({ "_class": "TestNode", "text": "some text", "childs": [ { "_class": "TestNode", "text": "child" }] })) root = env.find(:class => TestMM::TestNode, :text => "some text").first assert_not_nil root assert_equal 1, root.childs.size assert_equal TestMM::TestNode, root.childs.first.class assert_equal "child", root.childs.first.text end def test_json_serializer_escapes testModel = TestMM::TestNode.new(:text => %Q(some " \\ \\" text \r xx \n xx \r\n xx \t xx \b xx \f)) output = StringWriter.new ser = RGen::Serializer::JsonSerializer.new(output) assert_equal %q({ "_class": "TestNode", "text": "some \" \\\\ \\\\\" text \r xx \n xx \r\n xx \t xx \b xx \f" }), ser.serialize(testModel) end def test_json_instantiator_escapes env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM) inst.instantiate(%q({ "_class": "TestNode", "text": "some \" \\\\ \\\\\" text \r xx \n xx \r\n xx \t xx \b xx \f" })) assert_equal %Q(some " \\ \\" text \r xx \n xx \r\n xx \t xx \b xx \f), env.elements.first.text end def test_json_instantiator_escape_single_backslash env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM) inst.instantiate(%q({ "_class": "TestNode", "text": "a single \\ will be just itself" })) assert_equal %q(a single \\ will be just itself), env.elements.first.text end def test_json_serializer_integer testModel = TestMM::TestNode.new(:integer => 7) output = StringWriter.new ser = RGen::Serializer::JsonSerializer.new(output) assert_equal %q({ "_class": "TestNode", "integer": 7 }), ser.serialize(testModel) end def test_json_instantiator_integer env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM) inst.instantiate(%q({ "_class": "TestNode", "integer": 7 })) assert_equal 7, env.elements.first.integer end def test_json_serializer_float testModel = TestMM::TestNode.new(:float => 1.23) output = StringWriter.new ser = RGen::Serializer::JsonSerializer.new(output) assert_equal %q({ "_class": "TestNode", "float": 1.23 }), ser.serialize(testModel) end def test_json_instantiator_float env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM) inst.instantiate(%q({ "_class": "TestNode", "float": 1.23 })) assert_equal 1.23, env.elements.first.float end def test_json_instantiator_conflict_builtin env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMMData) inst.instantiate(%q({ "_class": "Data", "notTheBuiltin": "for sure" })) assert_equal "for sure", env.elements.first.notTheBuiltin end def test_json_serializer_subpacakge testModel = TestMMSubpackage::SubPackage::Data2.new(:data2 => "xxx") output = StringWriter.new ser = RGen::Serializer::JsonSerializer.new(output) assert_equal %q({ "_class": "Data2", "data2": "xxx" }), ser.serialize(testModel) end def test_json_instantiator_builtin_in_subpackage env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMMSubpackage) inst.instantiate(%q({ "_class": "Data", "notTheBuiltin": "for sure" })) assert_equal "for sure", env.elements.first.notTheBuiltin end def test_json_instantiator_subpackage env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMMSubpackage) inst.instantiate(%q({ "_class": "Data2", "data2": "something" })) assert_equal "something", env.elements.first.data2 end def test_json_instantiator_subpackage_no_shortname_opt env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMMSubpackage, :short_class_names => false) assert_raise RuntimeError do inst.instantiate(%q({ "_class": "Data2", "data2": "something" })) end end def test_json_instantiator_references env = RGen::Environment.new inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM, :nameAttribute => "text") inst.instantiate(%q([ { "_class": "TestNode", "text": "A", "childs": [ { "_class": "TestNode", "text": "B" } ]}, { "_class": "TestNode", "text": "C", "other": "/A/B"}] )) nodeA = env.find(:class => TestMM::TestNode, :text => "A").first nodeC = env.find(:class => TestMM::TestNode, :text => "C").first assert_equal 1, nodeA.childs.size assert_equal nodeA.childs[0], nodeC.other end end rgen-0.7.0/test/output_handler_test.rb0000644000004100000410000000300212352210062020065 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/template_language/output_handler' class MetamodelBuilderTest < Test::Unit::TestCase def test_direct_nl h = RGen::TemplateLanguage::OutputHandler.new h.mode = :direct h << "Test" h.ignoreNextNL h << "\nContent" assert_equal "TestContent", h.to_s end def test_direct_ws h = RGen::TemplateLanguage::OutputHandler.new h.mode = :direct h << "Test" h.ignoreNextWS h << " \n Content" assert_equal "TestContent", h.to_s end def test_explicit_indent h = RGen::TemplateLanguage::OutputHandler.new h.mode = :explicit h.indent = 1 h << "Start" h << " \n " h << "Test" h << " \n \n Content" assert_equal " Start\n Test\n Content", h.to_s end def test_explicit_endswithws h = RGen::TemplateLanguage::OutputHandler.new h.mode = :explicit h.indent = 1 h << "Start \n\n" assert_equal " Start\n", h.to_s end def test_performance h = RGen::TemplateLanguage::OutputHandler.new h.mode = :explicit h.indent = 1 line = (1..50).collect{|w| "someword"}.join(" ")+"\n" # repeat more often to make performance differences visible 20.times do h << line end end def test_indent_string h = RGen::TemplateLanguage::OutputHandler.new(1, "\t", :explicit) h << "Start" h << " \n " h << "Test" h << " \n \n Content" assert_equal "\tStart\n\tTest\n\tContent", h.to_s end endrgen-0.7.0/test/ea_serializer_test.rb0000644000004100000410000000133512352210062017655 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/environment' require 'metamodels/uml13_metamodel' require 'ea_support/ea_support' require 'rgen/serializer/xmi11_serializer' class EASerializerTest < Test::Unit::TestCase MODEL_DIR = File.join(File.dirname(__FILE__),"testmodel") TEST_DIR = File.join(File.dirname(__FILE__),"ea_serializer_test") def test_serializer envUML = RGen::Environment.new EASupport.instantiateUML13FromXMI11(envUML, MODEL_DIR+"/ea_testmodel.xml") models = envUML.find(:class => UML13::Model) assert_equal 1, models.size EASupport.serializeUML13ToXMI11(envUML, MODEL_DIR+"/ea_testmodel_regenerated.xml") end endrgen-0.7.0/test/array_extensions_test.rb0000644000004100000410000000310012352210062020424 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/array_extensions' class ArrayExtensionsTest < Test::Unit::TestCase def test_element_methods c = Struct.new("SomeClass",:name,:age) a = [] a << c.new('MyName',33) a << c.new('YourName',22) assert_equal ["MyName", "YourName"], a >> :name assert_raise NoMethodError do a.name end assert_equal [33, 22], a>>:age assert_raise NoMethodError do a.age end # unfortunately, any method can be called on an empty array assert_equal [], [].age end class MMBaseClass < RGen::MetamodelBuilder::MMBase has_attr 'name' has_attr 'age', Integer end def test_with_mmbase e1 = MMBaseClass.new e1.name = "MyName" e1.age = 33 e2 = MMBaseClass.new e2.name = "YourName" e2.age = 22 a = [e1, e2] assert_equal ["MyName", "YourName"], a >> :name assert_equal ["MyName", "YourName"], a.name assert_equal [33, 22], a>>:age assert_equal [33, 22], a.age # put something into the array that is not an MMBase a << "not a MMBase" # the dot operator will tell that there is something not a MMBase assert_raise StandardError do a.age end # the >> operator will try to call the method anyway assert_raise NoMethodError do a >> :age end end def test_hash_square assert_equal({}, Hash[[]]) end def test_to_str_on_empty_array assert_raise NoMethodError do [].to_str end end end rgen-0.7.0/test/qualified_name_provider_test.rb0000644000004100000410000000247512352210062021722 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/metamodel_builder' require 'rgen/serializer/qualified_name_provider' class QualifiedNameProviderTest < Test::Unit::TestCase class AbstractTestNode < RGen::MetamodelBuilder::MMBase contains_many 'children', AbstractTestNode, "parent" end class NamedNode < AbstractTestNode has_attr 'n', String end class UnnamedNode < AbstractTestNode end def test_simple root = NamedNode.new(:n => "root", :children => [ NamedNode.new(:n => "a", :children => [ NamedNode.new(:n => "a1") ]), UnnamedNode.new(:children => [ NamedNode.new(:n => "b1") ]) ]) qnp = RGen::Serializer::QualifiedNameProvider.new(:attribute_name => "n") assert_equal "/root", qnp.identifier(root) assert_equal "/root/a", qnp.identifier(root.children[0]) assert_equal "/root/a/a1", qnp.identifier(root.children[0].children[0]) assert_equal "/root", qnp.identifier(root.children[1]) assert_equal "/root/b1", qnp.identifier(root.children[1].children[0]) end def test_unnamed_root root = UnnamedNode.new qnp = RGen::Serializer::QualifiedNameProvider.new(:attribute_name => "n") assert_equal "/", qnp.identifier(root) end end rgen-0.7.0/test/metamodel_builder_test.rb0000644000004100000410000013561512352210062020525 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/metamodel_builder' require 'rgen/array_extensions' require 'bigdecimal' class MetamodelBuilderTest < Test::Unit::TestCase module TestMetamodel extend RGen::MetamodelBuilder::ModuleExtension class SimpleClass < RGen::MetamodelBuilder::MMBase KindType = RGen::MetamodelBuilder::DataTypes::Enum.new([:simple, :extended]) has_attr 'name' # default is String has_attr 'stringWithDefault', String, :defaultValueLiteral => "xtest" has_attr 'integerWithDefault', Integer, :defaultValueLiteral => "123" has_attr 'longWithDefault', Long, :defaultValueLiteral => "1234567890" has_attr 'floatWithDefault', Float, :defaultValueLiteral => "0.123" has_attr 'boolWithDefault', Boolean, :defaultValueLiteral => "true" has_attr 'anything', Object has_attr 'allowed', RGen::MetamodelBuilder::DataTypes::Boolean has_attr 'kind', KindType has_attr 'kindWithDefault', KindType, :defaultValueLiteral => "extended" end class ManyAttrClass < RGen::MetamodelBuilder::MMBase has_many_attr 'literals', String has_many_attr 'bools', Boolean has_many_attr 'integers', Integer has_many_attr 'enums', RGen::MetamodelBuilder::DataTypes::Enum.new([:a, :b, :c]) has_many_attr 'limitTest', Integer, :upperBound => 2 end class ClassA < RGen::MetamodelBuilder::MMBase # metamodel accessors must work independent of the ==() method module ClassModule def ==(o) o.is_a?(ClassA) end end end class ClassB < RGen::MetamodelBuilder::MMBase end class ClassC < RGen::MetamodelBuilder::MMBase end class HasOneTestClass < RGen::MetamodelBuilder::MMBase has_one 'classA', ClassA has_one 'classB', ClassB end class HasManyTestClass < RGen::MetamodelBuilder::MMBase has_many 'classA', ClassA end class OneClass < RGen::MetamodelBuilder::MMBase end class ManyClass < RGen::MetamodelBuilder::MMBase end OneClass.one_to_many 'manyClasses', ManyClass, 'oneClass', :upperBound => 5 class AClassMM < RGen::MetamodelBuilder::MMBase end class BClassMM < RGen::MetamodelBuilder::MMBase end AClassMM.many_to_many 'bClasses', BClassMM, 'aClasses' module SomePackage extend RGen::MetamodelBuilder::ModuleExtension class ClassA < RGen::MetamodelBuilder::MMBase end module SubPackage extend RGen::MetamodelBuilder::ModuleExtension class ClassB < RGen::MetamodelBuilder::MMBase end end end class OneClass2 < RGen::MetamodelBuilder::MMBase end class ManyClass2 < RGen::MetamodelBuilder::MMBase end ManyClass2.many_to_one 'oneClass', OneClass2, 'manyClasses' class AClassOO < RGen::MetamodelBuilder::MMBase end class BClassOO < RGen::MetamodelBuilder::MMBase end AClassOO.one_to_one 'bClass', BClassOO, 'aClass' class SomeSuperClass < RGen::MetamodelBuilder::MMBase has_attr "name" has_many "classAs", ClassA end class SomeSubClass < SomeSuperClass has_attr "subname" has_many "classBs", ClassB end class OtherSubClass < SomeSuperClass has_attr "othersubname" has_many "classCs", ClassC end class SubSubClass < RGen::MetamodelBuilder::MMMultiple(SomeSubClass, OtherSubClass) has_attr "subsubname" end module AnnotatedModule extend RGen::MetamodelBuilder::ModuleExtension annotation "moduletag" => "modulevalue" class AnnotatedClass < RGen::MetamodelBuilder::MMBase annotation "sometag" => "somevalue", "othertag" => "othervalue" annotation :source => "rgen/test", :details => {"thirdtag" => "thirdvalue"} has_attr "boolAttr", Boolean do annotation "attrtag" => "attrval" annotation :source => "rgen/test2", :details => {"attrtag2" => "attrvalue2", "attrtag3" => "attrvalue3"} end has_many "others", AnnotatedClass do annotation "reftag" => "refval" annotation :source => "rgen/test3", :details => {"reftag2" => "refvalue2", "reftag3" => "refvalue3"} end many_to_many "m2m", AnnotatedClass, "m2mback" do annotation "m2mtag" => "m2mval" opposite_annotation "opposite_m2mtag" => "opposite_m2mval" end end end class AbstractClass < RGen::MetamodelBuilder::MMBase abstract end class ContainedClass < RGen::MetamodelBuilder::MMBase end class ContainerClass < RGen::MetamodelBuilder::MMBase contains_one_uni 'oneChildUni', ContainedClass contains_one_uni 'oneChildUni2', ContainedClass contains_one 'oneChild', ContainedClass, 'parentOne' contains_one 'oneChild2', ContainedClass, 'parentOne2' contains_many_uni 'manyChildUni', ContainedClass contains_many_uni 'manyChildUni2', ContainedClass contains_many 'manyChild', ContainedClass, 'parentMany' contains_many 'manyChild2', ContainedClass, 'parentMany2' end class NestedContainerClass < ContainedClass contains_one_uni 'oneChildUni', ContainedClass end class OppositeRefAssocA < RGen::MetamodelBuilder::MMBase end class OppositeRefAssocB < RGen::MetamodelBuilder::MMBase end OppositeRefAssocA.one_to_one 'bClass', OppositeRefAssocB, 'aClass' end def mm TestMetamodel end def test_has_attr sc = mm::SimpleClass.new assert_respond_to sc, :name assert_respond_to sc, :name= sc.name = "TestName" assert_equal "TestName", sc.name sc.name = nil assert_equal nil, sc.name err = assert_raise StandardError do sc.name = 5 end assert_match /In (\w+::)+SimpleClass : Can not use a Fixnum where a String is expected/, err.message assert_equal "EString", mm::SimpleClass.ecore.eAttributes.find{|a| a.name=="name"}.eType.name assert_equal "xtest", sc.stringWithDefault assert_equal :extended, sc.kindWithDefault assert_equal 123, sc.integerWithDefault assert_equal 1234567890, sc.longWithDefault assert_equal 0.123, sc.floatWithDefault assert_equal true, sc.boolWithDefault # setting nil should not make the default value appear on next read sc.stringWithDefault = nil assert_nil sc.stringWithDefault sc.anything = :asymbol assert_equal :asymbol, sc.anything sc.anything = self # a class assert_equal self, sc.anything assert_respond_to sc, :allowed assert_respond_to sc, :allowed= sc.allowed = true assert_equal true, sc.allowed sc.allowed = false assert_equal false, sc.allowed sc.allowed = nil assert_equal nil, sc.allowed err = assert_raise StandardError do sc.allowed = :someSymbol end assert_match /In (\w+::)+SimpleClass : Can not use a Symbol\(:someSymbol\) where a \[true,false\] is expected/, err.message err = assert_raise StandardError do sc.allowed = "a string" end assert_match /In (\w+::)+SimpleClass : Can not use a String where a \[true,false\] is expected/, err.message assert_equal "EBoolean", mm::SimpleClass.ecore.eAttributes.find{|a| a.name=="allowed"}.eType.name assert_respond_to sc, :kind assert_respond_to sc, :kind= sc.kind = :simple assert_equal :simple, sc.kind sc.kind = :extended assert_equal :extended, sc.kind sc.kind = nil assert_equal nil, sc.kind err = assert_raise StandardError do sc.kind = :false end assert_match /In (\w+::)+SimpleClass : Can not use a Symbol\(:false\) where a \[:simple,:extended\] is expected/, err.message err = assert_raise StandardError do sc.kind = "a string" end assert_match /In (\w+::)+SimpleClass : Can not use a String where a \[:simple,:extended\] is expected/, err.message enum = mm::SimpleClass.ecore.eAttributes.find{|a| a.name=="kind"}.eType assert_equal ["extended", "simple"], enum.eLiterals.name.sort end def test_float sc = mm::SimpleClass.new sc.floatWithDefault = 7.89 assert_equal 7.89, sc.floatWithDefault if BigDecimal.double_fig == 16 sc.floatWithDefault = 123456789012345678.0 # loss of precision assert_equal "123456789012345680.0", sprintf("%.1f", sc.floatWithDefault) end sc.floatWithDefault = nil sc.floatWithDefault = BigDecimal.new("123456789012345678.0") assert sc.floatWithDefault.is_a?(BigDecimal) assert_equal "123456789012345678.0", sc.floatWithDefault.to_s("F") dump = Marshal.dump(sc) sc2 = Marshal.load(dump) assert sc2.floatWithDefault.is_a?(BigDecimal) assert_equal "123456789012345678.0", sc2.floatWithDefault.to_s("F") end def test_long sc = mm::SimpleClass.new sc.longWithDefault = 5 assert_equal 5, sc.longWithDefault sc.longWithDefault = 1234567890 assert_equal 1234567890, sc.longWithDefault assert sc.longWithDefault.is_a?(Bignum) assert sc.longWithDefault.is_a?(Integer) err = assert_raise StandardError do sc.longWithDefault = "a string" end assert_match /In (\w+::)+SimpleClass : Can not use a String where a Integer is expected/, err.message end def test_many_attr o = mm::ManyAttrClass.new assert_respond_to o, :literals assert_respond_to o, :addLiterals assert_respond_to o, :removeLiterals err = assert_raise(StandardError) do o.addLiterals(1) end assert_match /In (\w+::)+ManyAttrClass : Can not use a Fixnum where a String is expected/, err.message assert_equal [], o.literals o.addLiterals("a") assert_equal ["a"], o.literals o.addLiterals("b") assert_equal ["a", "b"], o.literals o.addLiterals("b") assert_equal ["a", "b", "b"], o.literals # attributes allow the same object several times o.addLiterals(o.literals.first) assert_equal ["a", "b", "b", "a"], o.literals assert o.literals[0].object_id == o.literals[3].object_id # removing works by object identity, so providing a new string won't delete an existing one o.removeLiterals("a") assert_equal ["a", "b", "b", "a"], o.literals theA = o.literals.first # each remove command removes only one element: remove first "a" o.removeLiterals(theA) assert_equal ["b", "b", "a"], o.literals # remove second "a" (same object) o.removeLiterals(theA) assert_equal ["b", "b"], o.literals o.removeLiterals(o.literals.first) assert_equal ["b"], o.literals o.removeLiterals(o.literals.first) assert_equal [], o.literals # setting multiple elements at a time o.literals = ["a", "b", "c"] assert_equal ["a", "b", "c"], o.literals # can only take enumerables err = assert_raise(StandardError) do o.literals = 1 end assert_match /In (\w+::)+ManyAttrClass : Can not use a Fixnum where a Enumerable is expected/, err.message o.bools = [true, false, true, false] assert_equal [true, false, true, false], o.bools o.integers = [1, 2, 2, 3, 3] assert_equal [1, 2, 2, 3, 3], o.integers o.enums = [:a, :a, :b, :c, :c] assert_equal [:a, :a, :b, :c, :c], o.enums lit = mm::ManyAttrClass.ecore.eAttributes.find{|a| a.name == "literals"} assert lit.is_a?(RGen::ECore::EAttribute) assert lit.many lim = mm::ManyAttrClass.ecore.eAttributes.find{|a| a.name == "limitTest"} assert lit.many assert_equal 2, lim.upperBound end def test_many_attr_insert o = mm::ManyAttrClass.new o.addLiterals("a") o.addLiterals("b", 0) o.addLiterals("c", 1) assert_equal ["b", "c", "a"], o.literals end def test_has_one sc = mm::HasOneTestClass.new assert_respond_to sc, :classA assert_respond_to sc, :classA= ca = mm::ClassA.new sc.classA = ca assert_equal ca, sc.classA sc.classA = nil assert_equal nil, sc.classA assert_respond_to sc, :classB assert_respond_to sc, :classB= cb = mm::ClassB.new sc.classB = cb assert_equal cb, sc.classB err = assert_raise StandardError do sc.classB = ca end assert_match /In (\w+::)+HasOneTestClass : Can not use a (\w+::)+ClassA where a (\w+::)+ClassB is expected/, err.message assert_equal [], mm::ClassA.ecore.eReferences assert_equal [], mm::ClassB.ecore.eReferences assert_equal ["classA", "classB"].sort, mm::HasOneTestClass.ecore.eReferences.name.sort assert_equal [], mm::HasOneTestClass.ecore.eReferences.select { |a| a.many == true } assert_equal [], mm::HasOneTestClass.ecore.eAttributes end def test_has_many o = mm::HasManyTestClass.new ca1 = mm::ClassA.new ca2 = mm::ClassA.new ca3 = mm::ClassA.new o.addClassA(ca1) o.addClassA(ca2) assert_equal [ca1, ca2], o.classA # make sure we get a copy o.classA.clear assert_equal [ca1, ca2], o.classA o.removeClassA(ca3) assert_equal [ca1, ca2], o.classA o.removeClassA(ca2) assert_equal [ca1], o.classA err = assert_raise StandardError do o.addClassA(mm::ClassB.new) end assert_match /In (\w+::)+HasManyTestClass : Can not use a (\w+::)+ClassB where a (\w+::)+ClassA is expected/, err.message assert_equal [], mm::HasManyTestClass.ecore.eReferences.select{|r| r.many == false} assert_equal ["classA"], mm::HasManyTestClass.ecore.eReferences.select{|r| r.many == true}.name end def test_has_many_insert o = mm::HasManyTestClass.new ca1 = mm::ClassA.new ca2 = mm::ClassA.new ca3 = mm::ClassA.new ca4 = mm::ClassA.new ca5 = mm::ClassA.new o.addClassA(ca1) o.addClassA(ca2) o.addClassA(ca3,0) o.addClassA(ca4,1) o.addGeneric("classA",ca5,2) assert_equal [ca3, ca4, ca5, ca1, ca2], o.classA end def test_one_to_many oc = mm::OneClass.new assert_respond_to oc, :manyClasses assert oc.manyClasses.empty? mc = mm::ManyClass.new assert_respond_to mc, :oneClass assert_respond_to mc, :oneClass= assert_nil mc.oneClass # put the OneClass into the ManyClass mc.oneClass = oc assert_equal oc, mc.oneClass assert oc.manyClasses.include?(mc) # remove the OneClass from the ManyClass mc.oneClass = nil assert_equal nil, mc.oneClass assert !oc.manyClasses.include?(mc) # put the ManyClass into the OneClass oc.addManyClasses mc assert oc.manyClasses.include?(mc) assert_equal oc, mc.oneClass # remove the ManyClass from the OneClass oc.removeManyClasses mc assert !oc.manyClasses.include?(mc) assert_equal nil, mc.oneClass assert_equal [], mm::OneClass.ecore.eReferences.select{|r| r.many == false} assert_equal ["manyClasses"], mm::OneClass.ecore.eReferences.select{|r| r.many == true}.name assert_equal 5, mm::OneClass.ecore.eReferences.find{|r| r.many == true}.upperBound assert_equal ["oneClass"], mm::ManyClass.ecore.eReferences.select{|r| r.many == false}.name assert_equal [], mm::ManyClass.ecore.eReferences.select{|r| r.many == true} end def test_one_to_many_replace1 oc1 = mm::OneClass.new oc2 = mm::OneClass.new mc = mm::ManyClass.new oc1.manyClasses = [mc] assert_equal [mc], oc1.manyClasses assert_equal [], oc2.manyClasses assert_equal oc1, mc.oneClass oc2.manyClasses = [mc] assert_equal [mc], oc2.manyClasses assert_equal [], oc1.manyClasses assert_equal oc2, mc.oneClass end def test_one_to_many_replace2 oc = mm::OneClass.new mc1 = mm::ManyClass.new mc2 = mm::ManyClass.new mc1.oneClass = oc assert_equal [mc1], oc.manyClasses assert_equal oc, mc1.oneClass assert_equal nil, mc2.oneClass mc2.oneClass = oc assert_equal [mc1, mc2], oc.manyClasses assert_equal oc, mc1.oneClass assert_equal oc, mc2.oneClass end def test_one_to_many_insert oc = mm::OneClass.new mc1 = mm::ManyClass.new mc2 = mm::ManyClass.new oc.addManyClasses(mc1, 0) oc.addManyClasses(mc2, 0) assert_equal [mc2, mc1], oc.manyClasses assert_equal oc, mc1.oneClass assert_equal oc, mc2.oneClass end def test_one_to_many2 oc = mm::OneClass2.new assert_respond_to oc, :manyClasses assert oc.manyClasses.empty? mc = mm::ManyClass2.new assert_respond_to mc, :oneClass assert_respond_to mc, :oneClass= assert_nil mc.oneClass # put the OneClass into the ManyClass mc.oneClass = oc assert_equal oc, mc.oneClass assert oc.manyClasses.include?(mc) # remove the OneClass from the ManyClass mc.oneClass = nil assert_equal nil, mc.oneClass assert !oc.manyClasses.include?(mc) # put the ManyClass into the OneClass oc.addManyClasses mc assert oc.manyClasses.include?(mc) assert_equal oc, mc.oneClass # remove the ManyClass from the OneClass oc.removeManyClasses mc assert !oc.manyClasses.include?(mc) assert_equal nil, mc.oneClass assert_equal [], mm::OneClass2.ecore.eReferences.select{|r| r.many == false} assert_equal ["manyClasses"], mm::OneClass2.ecore.eReferences.select{|r| r.many == true}.name assert_equal ["oneClass"], mm::ManyClass2.ecore.eReferences.select{|r| r.many == false}.name assert_equal [], mm::ManyClass2.ecore.eReferences.select{|r| r.many == true} end def test_one_to_one ac = mm::AClassOO.new assert_respond_to ac, :bClass assert_respond_to ac, :bClass= assert_nil ac.bClass bc = mm::BClassOO.new assert_respond_to bc, :aClass assert_respond_to bc, :aClass= assert_nil bc.aClass # put the AClass into the BClass bc.aClass = ac assert_equal ac, bc.aClass assert_equal bc, ac.bClass # remove the AClass from the BClass bc.aClass = nil assert_equal nil, bc.aClass assert_equal nil, ac.bClass # put the BClass into the AClass ac.bClass = bc assert_equal bc, ac.bClass assert_equal ac, bc.aClass # remove the BClass from the AClass ac.bClass = nil assert_equal nil, ac.bClass assert_equal nil, bc.aClass assert_equal ["bClass"], mm::AClassOO.ecore.eReferences.select{|r| r.many == false}.name assert_equal [], mm::AClassOO.ecore.eReferences.select{|r| r.many == true} assert_equal ["aClass"], mm::BClassOO.ecore.eReferences.select{|r| r.many == false}.name assert_equal [], mm::BClassOO.ecore.eReferences.select{|r| r.many == true} end def test_one_to_one_replace a = mm::AClassOO.new b1 = mm::BClassOO.new b2 = mm::BClassOO.new a.bClass = b1 assert_equal b1, a.bClass assert_equal a, b1.aClass assert_equal nil, b2.aClass a.bClass = b2 assert_equal b2, a.bClass assert_equal nil, b1.aClass assert_equal a, b2.aClass end def test_many_to_many ac = mm::AClassMM.new assert_respond_to ac, :bClasses assert ac.bClasses.empty? bc = mm::BClassMM.new assert_respond_to bc, :aClasses assert bc.aClasses.empty? # put the AClass into the BClass bc.addAClasses ac assert bc.aClasses.include?(ac) assert ac.bClasses.include?(bc) # put something else into the BClass err = assert_raise StandardError do bc.addAClasses :notaaclass end assert_match /In (\w+::)+BClassMM : Can not use a Symbol\(:notaaclass\) where a (\w+::)+AClassMM is expected/, err.message # remove the AClass from the BClass bc.removeAClasses ac assert !bc.aClasses.include?(ac) assert !ac.bClasses.include?(bc) # put the BClass into the AClass ac.addBClasses bc assert ac.bClasses.include?(bc) assert bc.aClasses.include?(ac) # put something else into the AClass err = assert_raise StandardError do ac.addBClasses :notabclass end assert_match /In (\w+::)+AClassMM : Can not use a Symbol\(:notabclass\) where a (\w+::)+BClassMM is expected/, err.message # remove the BClass from the AClass ac.removeBClasses bc assert !ac.bClasses.include?(bc) assert !bc.aClasses.include?(ac) assert_equal [], mm::AClassMM.ecore.eReferences.select{|r| r.many == false} assert_equal ["bClasses"], mm::AClassMM.ecore.eReferences.select{|r| r.many == true}.name assert_equal [], mm::BClassMM.ecore.eReferences.select{|r| r.many == false} assert_equal ["aClasses"], mm::BClassMM.ecore.eReferences.select{|r| r.many == true}.name end def test_many_to_many_insert ac1 = mm::AClassMM.new ac2 = mm::AClassMM.new bc1= mm::BClassMM.new bc2= mm::BClassMM.new ac1.addBClasses(bc1) ac1.addBClasses(bc2, 0) ac2.addBClasses(bc1) ac2.addBClasses(bc2, 0) assert_equal [bc2, bc1], ac1.bClasses assert_equal [bc2, bc1], ac2.bClasses assert_equal [ac1, ac2], bc1.aClasses assert_equal [ac1, ac2], bc2.aClasses end def test_inheritance assert_equal ["name"], mm::SomeSuperClass.ecore.eAllAttributes.name assert_equal ["classAs"], mm::SomeSuperClass.ecore.eAllReferences.name assert_equal ["name", "subname"], mm::SomeSubClass.ecore.eAllAttributes.name.sort assert_equal ["classAs", "classBs"], mm::SomeSubClass.ecore.eAllReferences.name.sort assert_equal ["name", "othersubname"], mm::OtherSubClass.ecore.eAllAttributes.name.sort assert_equal ["classAs", "classCs"], mm::OtherSubClass.ecore.eAllReferences.name.sort assert mm::SomeSubClass.new.is_a?(mm::SomeSuperClass) assert_equal ["name", "othersubname", "subname", "subsubname"], mm::SubSubClass.ecore.eAllAttributes.name.sort assert_equal ["classAs", "classBs", "classCs"], mm::SubSubClass.ecore.eAllReferences.name.sort assert mm::SubSubClass.new.is_a?(mm::SomeSuperClass) assert mm::SubSubClass.new.is_a?(mm::SomeSubClass) assert mm::SubSubClass.new.is_a?(mm::OtherSubClass) end def test_annotations assert_equal 1, mm::AnnotatedModule.ecore.eAnnotations.size anno = mm::AnnotatedModule.ecore.eAnnotations.first checkAnnotation(anno, nil, {"moduletag" => "modulevalue"}) eClass = mm::AnnotatedModule::AnnotatedClass.ecore assert_equal 2, eClass.eAnnotations.size anno = eClass.eAnnotations.find{|a| a.source == "rgen/test"} checkAnnotation(anno, "rgen/test", {"thirdtag" => "thirdvalue"}) anno = eClass.eAnnotations.find{|a| a.source == nil} checkAnnotation(anno, nil, {"sometag" => "somevalue", "othertag" => "othervalue"}) eAttr = eClass.eAttributes.first assert_equal 2, eAttr.eAnnotations.size anno = eAttr.eAnnotations.find{|a| a.source == "rgen/test2"} checkAnnotation(anno, "rgen/test2", {"attrtag2" => "attrvalue2", "attrtag3" => "attrvalue3"}) anno = eAttr.eAnnotations.find{|a| a.source == nil} checkAnnotation(anno, nil, {"attrtag" => "attrval"}) eRef = eClass.eReferences.find{|r| !r.eOpposite} assert_equal 2, eRef.eAnnotations.size anno = eRef.eAnnotations.find{|a| a.source == "rgen/test3"} checkAnnotation(anno, "rgen/test3", {"reftag2" => "refvalue2", "reftag3" => "refvalue3"}) anno = eRef.eAnnotations.find{|a| a.source == nil} checkAnnotation(anno, nil, {"reftag" => "refval"}) eRef = eClass.eReferences.find{|r| r.eOpposite} assert_equal 1, eRef.eAnnotations.size anno = eRef.eAnnotations.first checkAnnotation(anno, nil, {"m2mtag" => "m2mval"}) eRef = eRef.eOpposite assert_equal 1, eRef.eAnnotations.size anno = eRef.eAnnotations.first checkAnnotation(anno, nil, {"opposite_m2mtag" => "opposite_m2mval"}) end def checkAnnotation(anno, source, hash) assert anno.is_a?(RGen::ECore::EAnnotation) assert_equal source, anno.source assert_equal hash.size, anno.details.size hash.each_pair do |k, v| detail = anno.details.find{|d| d.key == k} assert detail.is_a?(RGen::ECore::EStringToStringMapEntry) assert_equal v, detail.value end end def test_ecore_identity subPackage = mm::SomePackage::SubPackage.ecore assert_equal subPackage.eClassifiers.first.object_id, mm::SomePackage::SubPackage::ClassB.ecore.object_id somePackage = mm::SomePackage.ecore assert_equal somePackage.eSubpackages.first.object_id, subPackage.object_id end def test_proxy p = RGen::MetamodelBuilder::MMProxy.new("test") assert_equal "test", p.targetIdentifier p.targetIdentifier = 123 assert_equal 123, p.targetIdentifier p.data = "additional info" assert_equal "additional info", p.data q = RGen::MetamodelBuilder::MMProxy.new("ident", "data") assert_equal "data", q.data end def test_proxies_has_one e = mm::HasOneTestClass.new proxy = RGen::MetamodelBuilder::MMProxy.new e.classA = proxy assert_equal proxy, e.classA a = mm::ClassA.new # displace proxy e.classA = a assert_equal a, e.classA # displace by proxy e.classA = proxy assert_equal proxy, e.classA end def test_proxies_has_many e = mm::HasManyTestClass.new proxy = RGen::MetamodelBuilder::MMProxy.new e.addClassA(proxy) assert_equal [proxy], e.classA # again e.addClassA(proxy) assert_equal [proxy], e.classA proxy2 = RGen::MetamodelBuilder::MMProxy.new e.addClassA(proxy2) assert_equal [proxy, proxy2], e.classA e.removeClassA(proxy) assert_equal [proxy2], e.classA # again e.removeClassA(proxy) assert_equal [proxy2], e.classA e.removeClassA(proxy2) assert_equal [], e.classA end def test_proxies_one_to_one ea = mm::AClassOO.new eb = mm::BClassOO.new proxy1 = RGen::MetamodelBuilder::MMProxy.new proxy2 = RGen::MetamodelBuilder::MMProxy.new ea.bClass = proxy1 eb.aClass = proxy2 assert_equal proxy1, ea.bClass assert_equal proxy2, eb.aClass # displace proxies ea.bClass = eb assert_equal eb, ea.bClass assert_equal ea, eb.aClass # displace by proxy ea.bClass = proxy1 assert_equal proxy1, ea.bClass assert_nil eb.aClass end def test_proxies_one_to_many eo = mm::OneClass.new em = mm::ManyClass.new proxy1 = RGen::MetamodelBuilder::MMProxy.new proxy2 = RGen::MetamodelBuilder::MMProxy.new eo.addManyClasses(proxy1) assert_equal [proxy1], eo.manyClasses em.oneClass = proxy2 assert_equal proxy2, em.oneClass # displace proxies at many side # adding em will set em.oneClass to eo and displace the proxy from em.oneClass eo.addManyClasses(em) assert_equal [proxy1, em], eo.manyClasses assert_equal eo, em.oneClass eo.removeManyClasses(proxy1) assert_equal [em], eo.manyClasses assert_equal eo, em.oneClass # displace by proxy em.oneClass = proxy2 assert_equal [], eo.manyClasses assert_equal proxy2, em.oneClass # displace proxies at one side em.oneClass = eo assert_equal [em], eo.manyClasses assert_equal eo, em.oneClass end def test_proxies_many_to_many e1 = mm::AClassMM.new e2 = mm::BClassMM.new proxy1 = RGen::MetamodelBuilder::MMProxy.new proxy2 = RGen::MetamodelBuilder::MMProxy.new e1.addBClasses(proxy1) e2.addAClasses(proxy2) assert_equal [proxy1], e1.bClasses assert_equal [proxy2], e2.aClasses e1.addBClasses(e2) assert_equal [proxy1, e2], e1.bClasses assert_equal [proxy2, e1], e2.aClasses e1.removeBClasses(proxy1) e2.removeAClasses(proxy2) assert_equal [e2], e1.bClasses assert_equal [e1], e2.aClasses end # Multiplicity agnostic convenience methods def test_genericAccess e1 = mm::OneClass.new e2 = mm::ManyClass.new e3 = mm::OneClass.new e4 = mm::ManyClass.new # use on "many" feature e1.setOrAddGeneric("manyClasses", e2) assert_equal [e2], e1.manyClasses assert_equal [e2], e1.getGeneric("manyClasses") assert_equal [e2], e1.getGenericAsArray("manyClasses") # use on "one" feature e2.setOrAddGeneric("oneClass", e3) assert_equal e3, e2.oneClass assert_equal e3, e2.getGeneric("oneClass") assert_equal [e3], e2.getGenericAsArray("oneClass") assert_nil e4.getGeneric("oneClass") assert_equal [], e4.getGenericAsArray("oneClass") end def test_setNilOrRemoveGeneric e1 = mm::OneClass.new e2 = mm::ManyClass.new e3 = mm::OneClass.new # use on "many" feature e1.addManyClasses(e2) assert_equal [e2], e1.manyClasses e1.setNilOrRemoveGeneric("manyClasses", e2) assert_equal [], e1.manyClasses # use on "one" feature e2.oneClass = e3 assert_equal e3, e2.oneClass e2.setNilOrRemoveGeneric("oneClass", e3) assert_nil e2.oneClass end def test_setNilOrRemoveAllGeneric e1 = mm::OneClass.new e2 = mm::ManyClass.new e3 = mm::OneClass.new e4 = mm::ManyClass.new # use on "many" feature e1.addManyClasses(e2) e1.addManyClasses(e4) assert_equal [e2, e4], e1.manyClasses e1.setNilOrRemoveAllGeneric("manyClasses") assert_equal [], e1.manyClasses # use on "one" feature e2.oneClass = e3 assert_equal e3, e2.oneClass e2.setNilOrRemoveAllGeneric("oneClass") assert_nil e2.oneClass end def test_abstract err = assert_raise StandardError do mm::AbstractClass.new end assert_match /Class (\w+::)+AbstractClass is abstract/, err.message end module BadDefaultValueLiteralContainer Test1 = proc do class BadClass < RGen::MetamodelBuilder::MMBase has_attr 'integerWithDefault', Integer, :defaultValueLiteral => "1.1" end end Test2 = proc do class BadClass < RGen::MetamodelBuilder::MMBase has_attr 'integerWithDefault', Integer, :defaultValueLiteral => "x" end end Test3 = proc do class BadClass < RGen::MetamodelBuilder::MMBase has_attr 'boolWithDefault', Boolean, :defaultValueLiteral => "1" end end Test4 = proc do class BadClass < RGen::MetamodelBuilder::MMBase has_attr 'floatWithDefault', Float, :defaultValueLiteral => "1" end end Test5 = proc do class BadClass < RGen::MetamodelBuilder::MMBase has_attr 'floatWithDefault', Float, :defaultValueLiteral => "true" end end Test6 = proc do class BadClass < RGen::MetamodelBuilder::MMBase kindType = RGen::MetamodelBuilder::DataTypes::Enum.new([:simple, :extended]) has_attr 'enumWithDefault', kindType, :defaultValueLiteral => "xxx" end end Test7 = proc do class BadClass < RGen::MetamodelBuilder::MMBase kindType = RGen::MetamodelBuilder::DataTypes::Enum.new([:simple, :extended]) has_attr 'enumWithDefault', kindType, :defaultValueLiteral => "7" end end Test8 = proc do class BadClass < RGen::MetamodelBuilder::MMBase has_attr 'longWithDefault', Integer, :defaultValueLiteral => "1.1" end end end def test_bad_default_value_literal err = assert_raise StandardError do BadDefaultValueLiteralContainer::Test1.call end assert_equal "Property integerWithDefault can not take value 1.1, expected an Integer", err.message err = assert_raise StandardError do BadDefaultValueLiteralContainer::Test2.call end assert_equal "Property integerWithDefault can not take value x, expected an Integer", err.message err = assert_raise StandardError do BadDefaultValueLiteralContainer::Test3.call end assert_equal "Property boolWithDefault can not take value 1, expected true or false", err.message err = assert_raise StandardError do BadDefaultValueLiteralContainer::Test4.call end assert_equal "Property floatWithDefault can not take value 1, expected a Float", err.message err = assert_raise StandardError do BadDefaultValueLiteralContainer::Test5.call end assert_equal "Property floatWithDefault can not take value true, expected a Float", err.message err = assert_raise StandardError do BadDefaultValueLiteralContainer::Test6.call end assert_equal "Property enumWithDefault can not take value xxx, expected one of :simple, :extended", err.message err = assert_raise StandardError do BadDefaultValueLiteralContainer::Test7.call end assert_equal "Property enumWithDefault can not take value 7, expected one of :simple, :extended", err.message err = assert_raise StandardError do BadDefaultValueLiteralContainer::Test8.call end assert_equal "Property longWithDefault can not take value 1.1, expected an Integer", err.message end def test_isset_set_to_nil e = mm::SimpleClass.new assert_respond_to e, :name assert !e.eIsSet(:name) assert !e.eIsSet("name") e.name = nil assert e.eIsSet(:name) end def test_isset_set_to_default e = mm::SimpleClass.new assert !e.eIsSet(:stringWithDefault) # set the default value e.name = "xtest" assert e.eIsSet(:name) end def test_isset_many_add e = mm::ManyAttrClass.new assert_equal [], e.literals assert !e.eIsSet(:literals) e.addLiterals("x") assert e.eIsSet(:literals) end def test_isset_many_remove e = mm::ManyAttrClass.new assert_equal [], e.literals assert !e.eIsSet(:literals) # removing a value which is not there e.removeLiterals("x") assert e.eIsSet(:literals) end def test_isset_ref ac = mm::AClassOO.new bc = mm::BClassOO.new assert !bc.eIsSet(:aClass) assert !ac.eIsSet(:bClass) bc.aClass = ac assert bc.eIsSet(:aClass) assert ac.eIsSet(:bClass) end def test_isset_ref_many ac = mm::AClassMM.new bc = mm::BClassMM.new assert !bc.eIsSet(:aClasses) assert !ac.eIsSet(:bClasses) bc.aClasses = [ac] assert bc.eIsSet(:aClasses) assert ac.eIsSet(:bClasses) end def test_unset_nil e = mm::SimpleClass.new e.name = nil assert e.eIsSet(:name) e.eUnset(:name) assert !e.eIsSet(:name) end def test_unset_string e = mm::SimpleClass.new e.name = "someone" assert e.eIsSet(:name) e.eUnset(:name) assert !e.eIsSet(:name) end def test_unset_ref ac = mm::AClassOO.new bc = mm::BClassOO.new bc.aClass = ac assert bc.eIsSet(:aClass) assert ac.eIsSet(:bClass) assert_equal bc, ac.bClass bc.eUnset(:aClass) assert_nil bc.aClass assert_nil ac.bClass assert !bc.eIsSet(:aClass) # opposite ref is nil but still "set" assert ac.eIsSet(:bClass) end def test_unset_ref_many ac = mm::AClassMM.new bc = mm::BClassMM.new bc.aClasses = [ac] assert bc.eIsSet(:aClasses) assert ac.eIsSet(:bClasses) assert_equal [bc], ac.bClasses bc.eUnset(:aClasses) assert_equal [], bc.aClasses assert_equal [], ac.bClasses assert !bc.eIsSet(:aClasses) # opposite ref is empty but still "set" assert ac.eIsSet(:bClasses) end def test_unset_marshal e = mm::SimpleClass.new e.name = "someone" e.eUnset(:name) e2 = Marshal.load(Marshal.dump(e)) assert e.object_id != e2.object_id assert !e2.eIsSet(:name) end def test_conainer_one_uni a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainedClass.new assert_equal [], a.eContents assert_equal [], a.eAllContents assert_nil b.eContainer assert_nil b.eContainingFeature a.oneChildUni = b assert_equal a, b.eContainer assert_equal :oneChildUni, b.eContainingFeature assert_equal [b], a.eContents assert_equal [b], a.eAllContents a.oneChildUni = c assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal a, c.eContainer assert_equal :oneChildUni, c.eContainingFeature assert_equal [c], a.eContents assert_equal [c], a.eAllContents a.oneChildUni = nil assert_nil c.eContainer assert_nil c.eContainingFeature assert_equal [], a.eContents assert_equal [], a.eAllContents end def test_container_many_uni a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainedClass.new assert_equal [], a.eContents assert_equal [], a.eAllContents a.addManyChildUni(b) assert_equal a, b.eContainer assert_equal :manyChildUni, b.eContainingFeature assert_equal [b], a.eContents assert_equal [b], a.eAllContents a.addManyChildUni(c) assert_equal a, c.eContainer assert_equal :manyChildUni, c.eContainingFeature assert_equal [b, c], a.eContents assert_equal [b, c], a.eAllContents a.removeManyChildUni(b) assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal a, c.eContainer assert_equal :manyChildUni, c.eContainingFeature assert_equal [c], a.eContents assert_equal [c], a.eAllContents a.removeManyChildUni(c) assert_nil c.eContainer assert_nil c.eContainingFeature assert_equal [], a.eContents assert_equal [], a.eAllContents end def test_conainer_one_bi a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainerClass.new d = mm::ContainedClass.new a.oneChild = b assert_equal a, b.eContainer assert_equal :oneChild, b.eContainingFeature assert_equal [b], a.eContents assert_equal [b], a.eAllContents c.oneChild = d assert_equal c, d.eContainer assert_equal :oneChild, d.eContainingFeature assert_equal [d], c.eContents assert_equal [d], c.eAllContents a.oneChild = d assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal a, d.eContainer assert_equal :oneChild, d.eContainingFeature assert_equal [d], a.eContents assert_equal [d], a.eAllContents assert_equal [], c.eContents assert_equal [], c.eAllContents end def test_conainer_one_bi_rev a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainerClass.new d = mm::ContainedClass.new a.oneChild = b assert_equal a, b.eContainer assert_equal :oneChild, b.eContainingFeature assert_equal [b], a.eContents assert_equal [b], a.eAllContents c.oneChild = d assert_equal c, d.eContainer assert_equal :oneChild, d.eContainingFeature assert_equal [d], c.eContents assert_equal [d], c.eAllContents d.parentOne = a assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal a, d.eContainer assert_equal :oneChild, d.eContainingFeature assert_equal [d], a.eContents assert_equal [d], a.eAllContents assert_equal [], c.eContents assert_equal [], c.eAllContents end def test_conainer_one_bi_nil a = mm::ContainerClass.new b = mm::ContainedClass.new a.oneChild = b assert_equal a, b.eContainer assert_equal :oneChild, b.eContainingFeature assert_equal [b], a.eContents assert_equal [b], a.eAllContents a.oneChild = nil assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal [], a.eContents assert_equal [], a.eAllContents end def test_conainer_one_bi_nil_rev a = mm::ContainerClass.new b = mm::ContainedClass.new a.oneChild = b assert_equal a, b.eContainer assert_equal :oneChild, b.eContainingFeature assert_equal [b], a.eContents assert_equal [b], a.eAllContents b.parentOne = nil assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal [], a.eContents assert_equal [], a.eAllContents end def test_container_many_bi a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainedClass.new a.addManyChild(b) a.addManyChild(c) assert_equal a, b.eContainer assert_equal :manyChild, b.eContainingFeature assert_equal a, c.eContainer assert_equal :manyChild, c.eContainingFeature assert_equal [b, c], a.eContents assert_equal [b, c], a.eAllContents a.removeManyChild(b) assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal [c], a.eContents assert_equal [c], a.eAllContents end def test_conainer_many_bi_steal a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainedClass.new d = mm::ContainerClass.new a.addManyChild(b) a.addManyChild(c) assert_equal a, b.eContainer assert_equal :manyChild, b.eContainingFeature assert_equal a, c.eContainer assert_equal :manyChild, c.eContainingFeature assert_equal [b, c], a.eContents assert_equal [b, c], a.eAllContents d.addManyChild(b) assert_equal d, b.eContainer assert_equal :manyChild, b.eContainingFeature assert_equal [c], a.eContents assert_equal [c], a.eAllContents assert_equal [b], d.eContents assert_equal [b], d.eAllContents end def test_conainer_many_bi_steal_rev a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainedClass.new d = mm::ContainerClass.new a.addManyChild(b) a.addManyChild(c) assert_equal a, b.eContainer assert_equal :manyChild, b.eContainingFeature assert_equal a, c.eContainer assert_equal :manyChild, c.eContainingFeature assert_equal [b, c], a.eContents assert_equal [b, c], a.eAllContents b.parentMany = d assert_equal d, b.eContainer assert_equal :manyChild, b.eContainingFeature assert_equal [c], a.eContents assert_equal [c], a.eAllContents assert_equal [b], d.eContents assert_equal [b], d.eAllContents end def test_all_contents a = mm::ContainerClass.new b = mm::NestedContainerClass.new c = mm::ContainedClass.new a.oneChildUni = b b.oneChildUni = c assert_equal [b, c], a.eAllContents end def test_all_contents_with_block a = mm::ContainerClass.new b = mm::NestedContainerClass.new c = mm::ContainedClass.new a.oneChildUni = b b.oneChildUni = c yielded = [] a.eAllContents do |e| yielded << e end assert_equal [b, c], yielded end def test_all_contents_prune a = mm::ContainerClass.new b = mm::NestedContainerClass.new c = mm::ContainedClass.new a.oneChildUni = b b.oneChildUni = c yielded = [] a.eAllContents do |e| yielded << e :prune end assert_equal [b], yielded end def test_container_generic a = mm::ContainerClass.new assert_nothing_raised do a.oneChild = RGen::MetamodelBuilder::MMGeneric.new end end def test_opposite_assoc_on_first_write ac = mm::OppositeRefAssocA.new bc = mm::OppositeRefAssocB.new # no access to 'aClass' or 'bClass' methods before # test if on-demand metamodel building creates opposite ref association on first write bc.aClass = ac assert_equal ac, bc.aClass assert_equal bc, ac.bClass end def test_clear_by_array_assignment oc1 = mm::OneClass.new mc1 = mm::ManyClass.new mc2 = mm::ManyClass.new mc3 = mm::ManyClass.new oc1.manyClasses = [mc1, mc2] assert_equal [mc1, mc2], oc1.manyClasses oc1.manyClasses = [] assert_equal [], oc1.manyClasses end def test_clear_by_array_assignment_uni a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainedClass.new a.manyChildUni = [b, c] assert_equal [b, c], a.manyChildUni a.manyChildUni = [] assert_equal [], a.manyChildUni end def test_disconnectContainer_one_uni a = mm::ContainerClass.new b = mm::ContainedClass.new a.oneChildUni = b b.disconnectContainer assert_nil a.oneChildUni end def test_disconnectContainer_one a = mm::ContainerClass.new b = mm::ContainedClass.new a.oneChild = b b.disconnectContainer assert_nil a.oneChild assert_nil b.parentOne end def test_disconnectContainer_many_uni a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainedClass.new a.addManyChildUni(b) a.addManyChildUni(c) b.disconnectContainer assert_equal [c], a.manyChildUni end def test_disconnectContainer_many a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainedClass.new a.addManyChild(b) a.addManyChild(c) b.disconnectContainer assert_nil b.parentMany assert_equal [c], a.manyChild end # Duplicate Containment Tests # # Testing that no element is contained in two different containers at a time. # This must also work for uni-directional containments as well as # for containments via different roles. # here the bi-dir reference disconnects from the previous container def test_duplicate_containment_bidir_samerole_one a1 = mm::ContainerClass.new a2 = mm::ContainerClass.new b = mm::ContainedClass.new a1.oneChild = b a2.oneChild = b assert_nil a1.oneChild end # here the bi-dir reference disconnects from the previous container def test_duplicate_containment_bidir_samerole_many a1 = mm::ContainerClass.new a2 = mm::ContainerClass.new b = mm::ContainedClass.new a1.addManyChild(b) a2.addManyChild(b) assert_equal [], a1.manyChild end def test_duplicate_containment_unidir_samerole_one a1 = mm::ContainerClass.new a2 = mm::ContainerClass.new b = mm::ContainedClass.new a1.oneChildUni = b a2.oneChildUni = b assert_nil a1.oneChildUni end def test_duplicate_containment_unidir_samerole_many a1 = mm::ContainerClass.new a2 = mm::ContainerClass.new b = mm::ContainedClass.new a1.addManyChildUni(b) a2.addManyChildUni(b) assert_equal [], a1.manyChildUni end def test_duplicate_containment_bidir_otherrole_one a1 = mm::ContainerClass.new a2 = mm::ContainerClass.new b = mm::ContainedClass.new a1.oneChild = b a2.oneChild2 = b assert_nil a1.oneChild end def test_duplicate_containment_bidir_otherrole_many a1 = mm::ContainerClass.new a2 = mm::ContainerClass.new b = mm::ContainedClass.new a1.addManyChild(b) a2.addManyChild2(b) assert_equal [], a1.manyChild end def test_duplicate_containment_unidir_otherrole_one a1 = mm::ContainerClass.new a2 = mm::ContainerClass.new b = mm::ContainedClass.new a1.oneChildUni = b a2.oneChildUni2 = b assert_nil a1.oneChildUni end def test_duplicate_containment_unidir_otherrole_many a1 = mm::ContainerClass.new a2 = mm::ContainerClass.new b = mm::ContainedClass.new a1.addManyChildUni(b) a2.addManyChildUni2(b) assert_equal [], a1.manyChildUni end end rgen-0.7.0/test/metamodel_from_ecore_test.rb0000644000004100000410000000423412352210062021207 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","test") require 'metamodel_builder_test' require 'rgen/ecore/ecore_to_ruby' # this test suite runs all the tests of MetamodelBuilderTest with the TestMetamodel # replaced by the result of feeding its ecore model through ECoreToRuby # class MetamodelFromEcoreTest < MetamodelBuilderTest # clone the ecore model, because it will be modified below test_ecore = Marshal.load(Marshal.dump(TestMetamodel.ecore)) # some EEnum types are not hooked into the EPackage because they do not # appear with a constant assignment in TestMetamodel # fix this by explicitly assigning the ePackage # also fix the name of anonymous enums test_ecore.eClassifiers.find{|c| c.name == "SimpleClass"}. eAttributes.select{|a| a.name == "kind" || a.name == "kindWithDefault"}.each{|a| a.eType.name = "KindType" a.eType.ePackage = test_ecore} test_ecore.eClassifiers.find{|c| c.name == "ManyAttrClass"}. eAttributes.select{|a| a.name == "enums"}.each{|a| a.eType.name = "ABCEnum" a.eType.ePackage = test_ecore} MetamodelFromEcore = RGen::ECore::ECoreToRuby.new.create_module(test_ecore) def mm MetamodelFromEcore end # alternative implementation for dynamic variant def test_bad_default_value_literal package = RGen::ECore::EPackage.new(:name => "Package1", :eClassifiers => [ RGen::ECore::EClass.new(:name => "Class1", :eStructuralFeatures => [ RGen::ECore::EAttribute.new(:name => "value", :eType => RGen::ECore::EInt, :defaultValueLiteral => "x")])]) mod = RGen::ECore::ECoreToRuby.new.create_module(package) obj = mod::Class1.new # the error is raised only when the feature is lazily constructed assert_raise StandardError do obj.value end end # define all the test methods explicitly in the subclass # otherwise minitest is smart enough to run the tests only in the superclass context MetamodelBuilderTest.instance_methods.select{|m| m.to_s =~ /^test_/}.each do |m| next if instance_methods(false).include?(m) module_eval <<-END def #{m} super end END end end rgen-0.7.0/test/ea_instantiator_test.rb0000644000004100000410000000211712352210062020222 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/environment' require 'metamodels/uml13_metamodel' require 'ea_support/ea_support' require 'transformers/uml13_to_ecore' require 'testmodel/class_model_checker' require 'testmodel/object_model_checker' require 'testmodel/ecore_model_checker' class EAInstantiatorTest < Test::Unit::TestCase include Testmodel::ClassModelChecker include Testmodel::ObjectModelChecker include Testmodel::ECoreModelChecker MODEL_DIR = File.join(File.dirname(__FILE__),"testmodel") def test_instantiator envUML = RGen::Environment.new EASupport.instantiateUML13FromXMI11(envUML, MODEL_DIR+"/ea_testmodel.xml") checkClassModel(envUML) checkObjectModel(envUML) envECore = RGen::Environment.new UML13ToECore.new(envUML, envECore).transform checkECoreModel(envECore) end def test_partial envUML = RGen::Environment.new EASupport.instantiateUML13FromXMI11(envUML, MODEL_DIR+"/ea_testmodel_partial.xml") checkClassModelPartial(envUML) end endrgen-0.7.0/test/util/0000755000004100000410000000000012352210062014426 5ustar www-datawww-datargen-0.7.0/test/util/pattern_matcher_test.rb0000644000004100000410000000477612352210062021210 0ustar www-datawww-data$:.unshift(File.dirname(__FILE__)+"/../../lib") require 'test/unit' require 'rgen/environment' require 'rgen/metamodel_builder' require 'rgen/model_builder' require 'rgen/util/pattern_matcher' class PatternMatcherTest < Test::Unit::TestCase module TestMM extend RGen::MetamodelBuilder::ModuleExtension class Node < RGen::MetamodelBuilder::MMBase has_attr 'name', String contains_many 'children', Node, 'parent' end end def modelA env = RGen::Environment.new RGen::ModelBuilder.build(TestMM, env) do node "A" do node "AA" end node "B" do node "B1" node "B2" node "B3" end node "C" do node "C1" node "C2" end node "D" do node "DD" end end env end def test_simple matcher = RGen::Util::PatternMatcher.new matcher.add_pattern("simple") do |env, c| TestMM::Node.new(:name => "A", :children => [ TestMM::Node.new(:name => "AA")]) end matcher.add_pattern("bad") do |env, c| TestMM::Node.new(:name => "X") end env = modelA match = matcher.find_pattern(env, "simple") assert_not_nil match assert_equal "A", match.root.name assert_equal env.find(:class => TestMM::Node, :name => "A").first.object_id, match.root.object_id assert_equal 2, match.elements.size assert_equal [nil], match.bound_values assert_nil matcher.find_pattern(env, "bad") end def test_value_binding matcher = RGen::Util::PatternMatcher.new matcher.add_pattern("single_child") do |env, name, child| TestMM::Node.new(:name => name, :children => [ child ]) end matcher.add_pattern("double_child") do |env, name, child1, child2| TestMM::Node.new(:name => name, :children => [ child1, child2 ]) end matcher.add_pattern("child_pattern") do |env, child_name| TestMM::Node.new(:name => "A", :children => [ TestMM::Node.new(:name => child_name)]) end env = modelA match = matcher.find_pattern(env, "single_child") assert_not_nil match assert_equal "A", match.root.name assert_equal "AA", match.bound_values[1].name match = matcher.find_pattern(env, "single_child", "D") assert_not_nil match assert_equal "D", match.root.name assert_equal "DD", match.bound_values[0].name match = matcher.find_pattern(env, "double_child") assert_not_nil match assert_equal "C", match.root.name match = matcher.find_pattern(env, "child_pattern") assert_not_nil match assert_equal ["AA"], match.bound_values end end rgen-0.7.0/test/util/file_cache_map_test/0000755000004100000410000000000012352210062020364 5ustar www-datawww-datargen-0.7.0/test/util/file_cache_map_test/testdir/0000755000004100000410000000000012352210062022042 5ustar www-datawww-datargen-0.7.0/test/util/file_cache_map_test/testdir/fileA0000644000004100000410000000001012352210062022774 0ustar www-datawww-datasomedatargen-0.7.0/test/util/file_cache_map_test.rb0000644000004100000410000000627012352210062020716 0ustar www-datawww-data$:.unshift(File.dirname(__FILE__)+"/../../lib") require 'test/unit' require 'fileutils' require 'rgen/util/file_cache_map' class FileCacheMapTest < Test::Unit::TestCase TestDir = File.dirname(__FILE__)+"/file_cache_map_test/testdir" def setup FileUtils.rm_r(Dir[TestDir+"/*"]) # * doesn't include dot files FileUtils.rm_r(Dir[TestDir+"/.cache"]) @cm = RGen::Util::FileCacheMap.new(".cache", ".test") end def test_nocache reasons = [] assert_equal(:invalid, @cm.load_data(TestDir+"/fileA", :invalidation_reasons => reasons)) assert_equal [:no_cachefile], reasons end def test_storeload keyFile = TestDir+"/fileA" File.open(keyFile, "w") {|f| f.write("somedata")} @cm.store_data(keyFile, "valuedata") assert(File.exist?(TestDir+"/.cache/fileA.test")) assert_equal("valuedata", @cm.load_data(keyFile)) end def test_storeload_subdir keyFile = TestDir+"/subdir/fileA" FileUtils.mkdir(TestDir+"/subdir") File.open(keyFile, "w") {|f| f.write("somedata")} @cm.store_data(keyFile, "valuedata") assert(File.exist?(TestDir+"/subdir/.cache/fileA.test")) assert_equal("valuedata", @cm.load_data(keyFile)) end def test_storeload_postfix keyFile = TestDir+"/fileB.txt" File.open(keyFile, "w") {|f| f.write("somedata")} @cm.store_data(keyFile, "valuedata") assert(File.exist?(TestDir+"/.cache/fileB.txt.test")) assert_equal("valuedata", @cm.load_data(keyFile)) end def test_storeload_empty keyFile = TestDir+"/fileA" File.open(keyFile, "w") {|f| f.write("")} @cm.store_data(keyFile, "valuedata") assert(File.exist?(TestDir+"/.cache/fileA.test")) assert_equal("valuedata", @cm.load_data(keyFile)) end def test_corruptcache keyFile = TestDir+"/fileA" File.open(keyFile, "w") {|f| f.write("somedata")} @cm.store_data(keyFile, "valuedata") File.open(TestDir+"/.cache/fileA.test","a") {|f| f.write("more data")} reasons = [] assert_equal(:invalid, @cm.load_data(keyFile, :invalidation_reasons => reasons)) assert_equal [:cachefile_corrupted], reasons end def test_changedcontent keyFile = TestDir+"/fileA" File.open(keyFile, "w") {|f| f.write("somedata")} @cm.store_data(keyFile, "valuedata") File.open(keyFile, "a") {|f| f.write("more data")} reasons = [] assert_equal(:invalid, @cm.load_data(keyFile, :invalidation_reasons => reasons)) assert_equal [:keyfile_changed], reasons end def test_versioninfo keyFile = TestDir+"/fileA" File.open(keyFile, "w") {|f| f.write("somedata")} @cm.version_info = "123" @cm.store_data(keyFile, "valuedata") assert(File.exist?(TestDir+"/.cache/fileA.test")) assert_equal("valuedata", @cm.load_data(keyFile)) end def test_changed_version keyFile = TestDir+"/fileA" File.open(keyFile, "w") {|f| f.write("somedata")} @cm.version_info = "123" @cm.store_data(keyFile, "valuedata") @cm.version_info = "456" reasons = [] assert_equal(:invalid, @cm.load_data(keyFile, :invalidation_reasons => reasons)) assert_equal [:keyfile_changed], reasons end end rgen-0.7.0/test/xml_instantiator_test.rb0000644000004100000410000001135412352210062020440 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/instantiator/default_xml_instantiator' require 'rgen/environment' require 'rgen/util/model_dumper' require 'xml_instantiator_test/simple_xmi_ecore_instantiator' require 'xml_instantiator_test/simple_ecore_model_checker' module EmptyMM end module DefaultMM module MNS class Room < RGen::MetamodelBuilder::MMBase; end end class Person < RGen::MetamodelBuilder::MMBase; end Person.one_to_one 'personalRoom', MNS::Room, 'inhabitant' end class XMLInstantiatorTest < Test::Unit::TestCase XML_DIR = File.join(File.dirname(__FILE__),"testmodel") include RGen::Util::ModelDumper class MyInstantiator < RGen::Instantiator::DefaultXMLInstantiator map_tag_ns "testmodel.org/myNamespace", DefaultMM::MNS def class_name(str) camelize(str) end # resolve :type do # @env.find(:xmi_id => getType).first # end resolve_by_id :personalRoom, :id => :getId, :src => :room end class PruneTestInstantiator < RGen::Instantiator::NodebasedXMLInstantiator attr_reader :max_depth set_prune_level 2 def initialize(env) super(env) @max_depth = 0 end def on_descent(node) end def on_ascent(node) calc_max_depth(node, 0) end def calc_max_depth(node, offset) if node.children.nil? || node.children.size == 0 @max_depth = offset if offset > @max_depth else node.children.each do |c| calc_max_depth(c, offset+1) end end end end module PruneTestMM end def test_pruning env = RGen::Environment.new # prune level 2 is set in the class body inst = PruneTestInstantiator.new(env) inst.instantiate_file(File.join(XML_DIR,"manual_testmodel.xml")) assert_equal 2, inst.max_depth PruneTestInstantiator.set_prune_level(0) inst = PruneTestInstantiator.new(env) inst.instantiate_file(File.join(XML_DIR,"manual_testmodel.xml")) assert_equal 5, inst.max_depth PruneTestInstantiator.set_prune_level(1) inst = PruneTestInstantiator.new(env) inst.instantiate_file(File.join(XML_DIR,"manual_testmodel.xml")) assert_equal 1, inst.max_depth end def test_custom env = RGen::Environment.new inst = MyInstantiator.new(env, DefaultMM, true) inst.instantiate_file(File.join(XML_DIR,"manual_testmodel.xml")) house = env.find(:class => DefaultMM::MNS::House).first assert_not_nil house assert_equal 2, house.room.size rooms = env.find(:class => DefaultMM::MNS::Room) assert_equal 2, rooms.size assert_equal 0, (house.room - rooms).size rooms.each {|r| assert r.parent == house} tomsRoom = rooms.select{|r| r.name == "TomsRoom"}.first assert_not_nil tomsRoom persons = env.find(:class => DefaultMM::Person) assert_equal 4, persons.size tom = persons.select{|p| p.name == "Tom"}.first assert_not_nil tom assert tom.personalRoom == tomsRoom mpns = env.find(:class => DefaultMM::MultiPartName) assert mpns.first.respond_to?("insideMultiPart") end def test_default env = RGen::Environment.new inst = RGen::Instantiator::DefaultXMLInstantiator.new(env, EmptyMM, true) inst.instantiate_file(File.join(XML_DIR,"manual_testmodel.xml")) house = env.find(:class => EmptyMM::MNS_House).first assert_not_nil house assert_equal 2, house.mNS_Room.size assert_equal "before kitchen", remove_whitespace_elements(house.chardata)[0].strip assert_equal "after kitchen", remove_whitespace_elements(house.chardata)[1].strip assert_equal "after toms room", remove_whitespace_elements(house.chardata)[2].strip rooms = env.find(:class => EmptyMM::MNS_Room) assert_equal 2, rooms.size assert_equal 0, (house.mNS_Room - rooms).size rooms.each {|r| assert r.parent == house} tomsRoom = rooms.select{|r| r.name == "TomsRoom"}.first assert_not_nil tomsRoom assert_equal "within toms room", remove_whitespace_elements(tomsRoom.chardata)[0] persons = env.find(:class => EmptyMM::Person) assert_equal 4, persons.size tom = persons.select{|p| p.name == "Tom"}.first assert_not_nil tom end def remove_whitespace_elements(elements) elements.reject{|e| e.strip == ""} end include SimpleECoreModelChecker def test_simle_xmi_ecore_instantiator envECore = RGen::Environment.new File.open(XML_DIR+"/ea_testmodel.xml") { |f| SimpleXMIECoreInstantiator.new.instantiateECoreModel(envECore, f.read) } checkECoreModel(envECore) end end rgen-0.7.0/test/qualified_name_resolver_test.rb0000644000004100000410000000737212352210062021732 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/metamodel_builder' require 'rgen/instantiator/qualified_name_resolver' class QualifiedNameResolverTest < Test::Unit::TestCase class TestNode < RGen::MetamodelBuilder::MMBase has_attr 'name', String has_one 'nextSibling', TestNode contains_many 'children', TestNode, "parent" end class TestNode2 < RGen::MetamodelBuilder::MMBase has_attr 'cname', String has_one 'nextSibling', TestNode2 contains_many 'children', TestNode2, "parent" end class TestNode3 < RGen::MetamodelBuilder::MMBase has_attr 'name', String contains_one 'child', TestNode3, "parent" end def testModel [TestNode.new(:name => "Root1", :children => [ TestNode.new(:name => "Sub11"), TestNode.new(:name => "Sub12", :children => [ TestNode.new(:name => "Sub121")])]), TestNode.new(:name => "Root2", :children => [ TestNode.new(:name => "Sub21", :children => [ TestNode.new(:name => "Sub211")])]), TestNode.new(:name => "Root3"), TestNode.new(:name => "Root3") ] end def testModel2 [TestNode2.new(:cname => "Root1", :children => [ TestNode2.new(:cname => "Sub11")])] end def testModel3 [TestNode3.new(:name => "Root1", :child => TestNode3.new(:name => "Sub11", :child => TestNode3.new(:name => "Sub111")))] end def test_customNameAttribute model = testModel2 res = RGen::Instantiator::QualifiedNameResolver.new(model, :nameAttribute => "cname") assert_equal model[0], res.resolveIdentifier("/Root1") assert_equal model[0].children[0], res.resolveIdentifier("/Root1/Sub11") end def test_customSeparator model = testModel res = RGen::Instantiator::QualifiedNameResolver.new(model, :separator => "|") assert_equal model[0], res.resolveIdentifier("|Root1") assert_nil res.resolveIdentifier("/Root1") assert_equal model[0].children[0], res.resolveIdentifier("|Root1|Sub11") end def test_noLeadingSeparator model = testModel res = RGen::Instantiator::QualifiedNameResolver.new(model, :leadingSeparator => false) assert_equal model[0], res.resolveIdentifier("Root1") assert_nil res.resolveIdentifier("/Root1") assert_equal model[0].children[0], res.resolveIdentifier("Root1/Sub11") end def test_resolve model = testModel res = RGen::Instantiator::QualifiedNameResolver.new(model) assert_equal model[0], res.resolveIdentifier("/Root1") # again assert_equal model[0], res.resolveIdentifier("/Root1") assert_equal model[0].children[0], res.resolveIdentifier("/Root1/Sub11") # again assert_equal model[0].children[0], res.resolveIdentifier("/Root1/Sub11") assert_equal model[0].children[1], res.resolveIdentifier("/Root1/Sub12") assert_equal model[0].children[1].children[0], res.resolveIdentifier("/Root1/Sub12/Sub121") assert_equal model[1], res.resolveIdentifier("/Root2") assert_equal model[1].children[0], res.resolveIdentifier("/Root2/Sub21") assert_equal model[1].children[0].children[0], res.resolveIdentifier("/Root2/Sub21/Sub211") # duplicate name yields two result elements assert_equal [model[2], model[3]], res.resolveIdentifier("/Root3") assert_equal nil, res.resolveIdentifier("/RootX") assert_equal nil, res.resolveIdentifier("/Root1/SubX") end def test_oneChild model = testModel3 res = RGen::Instantiator::QualifiedNameResolver.new(model) assert_equal model[0], res.resolveIdentifier("/Root1") assert_equal model[0].child, res.resolveIdentifier("/Root1/Sub11") assert_equal model[0].child.child, res.resolveIdentifier("/Root1/Sub11/Sub111") end end rgen-0.7.0/test/model_fragment_test.rb0000644000004100000410000000133112352210062020016 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/metamodel_builder' require 'rgen/fragment/model_fragment' class ModelFragmentTest < Test::Unit::TestCase module TestMetamodel extend RGen::MetamodelBuilder::ModuleExtension class SimpleClass < RGen::MetamodelBuilder::MMBase has_attr 'name', String contains_many 'subclass', SimpleClass, 'parent' end end def test_elements root = TestMetamodel::SimpleClass.new(:name => "parent", :subclass => [TestMetamodel::SimpleClass.new(:name => "child")]) frag = RGen::Fragment::ModelFragment.new("location") frag.set_root_elements([root]) assert_equal 2, frag.elements.size end end rgen-0.7.0/test/ecore_self_test.rb0000644000004100000410000000374412352210062017153 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/ecore/ecore' require 'rgen/array_extensions' class ECoreSelfTest < Test::Unit::TestCase include RGen::ECore def test_simple assert_equal \ %w(lowerBound ordered unique upperBound many required eType).sort, ETypedElement.ecore.eStructuralFeatures.name.sort assert_equal \ EClassifier.ecore, ETypedElement.ecore.eStructuralFeatures.find{|f| f.name=="eType"}.eType assert_equal %w(ENamedElement), ETypedElement.ecore.eSuperTypes.name assert_equal \ EModelElement.ecore, EModelElement.ecore.eStructuralFeatures.find{|f| f.name=="eAnnotations"}.eOpposite.eType assert_equal \ %w(eType), ETypedElement.ecore.eReferences.name assert_equal \ %w(lowerBound ordered unique upperBound many required).sort, ETypedElement.ecore.eAttributes.name.sort assert RGen::ECore.ecore.is_a?(EPackage) assert_equal "ECore", RGen::ECore.ecore.name assert_equal "RGen", RGen::ECore.ecore.eSuperPackage.name assert_equal %w(ECore), RGen.ecore.eSubpackages.name assert_equal\ %w(EObject EModelElement EAnnotation ENamedElement ETypedElement EStructuralFeature EAttribute EClassifier EDataType EEnum EEnumLiteral EFactory EOperation EPackage EParameter EReference EStringToStringMapEntry EClass ETypeArgument EGenericType).sort, RGen::ECore.ecore.eClassifiers.name.sort assert_equal "false", EAttribute.ecore.eAllAttributes. find{|a|a.name == "derived"}.defaultValueLiteral assert_equal false, EAttribute.ecore.eAllAttributes. find{|a|a.name == "derived"}.defaultValue assert_nil EAttribute.ecore.eAllAttributes. find{|a|a.name == "defaultValueLiteral"}.defaultValueLiteral assert_nil EAttribute.ecore.eAllAttributes. find{|a|a.name == "defaultValueLiteral"}.defaultValue end end rgen-0.7.0/test/model_builder/0000755000004100000410000000000012352210062016257 5ustar www-datawww-datargen-0.7.0/test/model_builder/reference_resolver_test.rb0000644000004100000410000001201112352210062023515 0ustar www-datawww-data$:.unshift File.dirname(__FILE__)+"/../lib" require 'test/unit' require 'rgen/metamodel_builder' require 'rgen/model_builder/reference_resolver' class ReferenceResolverTest < Test::Unit::TestCase class ClassA < RGen::MetamodelBuilder::MMBase has_attr "name" end class ClassB < RGen::MetamodelBuilder::MMBase has_attr "name" end class ClassC < RGen::MetamodelBuilder::MMBase has_attr "name" end ClassA.contains_many 'childB', ClassB, 'parentA' ClassB.contains_many 'childC', ClassC, 'parentB' ClassA.has_one 'refC', ClassC ClassB.has_one 'refC', ClassC ClassC.has_many 'refCs', ClassC ClassC.has_one 'refA', ClassA ClassC.has_one 'refB', ClassB def testModel a1 = ClassA.new(:name => "a1") a2 = ClassA.new(:name => "a2") b1 = ClassB.new(:name => "b1", :parentA => a1) b2 = ClassB.new(:name => "b2", :parentA => a1) c1 = ClassC.new(:name => "c1", :parentB => b1) c2 = ClassC.new(:name => "c2", :parentB => b1) c3 = ClassC.new(:name => "c3", :parentB => b1) [a1, a2, b1, b2, c1, c2, c3] end def setElementNames(resolver, elements) elements.each do |e| resolver.setElementName(e, e.name) end end def createJob(hash) raise "Invalid arguments" unless \ hash.is_a?(Hash) && (hash.keys & [:receiver, :reference, :namespace, :string]).size == 4 RGen::ModelBuilder::ReferenceResolver::ResolverJob.new( hash[:receiver], hash[:reference], hash[:namespace], hash[:string]) end def test_resolve_same_namespace a1, a2, b1, b2, c1, c2, c3 = testModel toplevelNamespace = [a1, a2] resolver = RGen::ModelBuilder::ReferenceResolver.new setElementNames(resolver, [a1, a2, b1, b2, c1, c2, c3]) resolver.addJob(createJob( :receiver => c2, :reference => ClassC.ecore.eReferences.find{|r| r.name == "refCs"}, :namespace => b1, :string => "c1")) resolver.addJob(createJob( :receiver => b2, :reference => ClassB.ecore.eReferences.find{|r| r.name == "refC"}, :namespace => a1, :string => "b1.c1")) resolver.addJob(createJob( :receiver => a2, :reference => ClassA.ecore.eReferences.find{|r| r.name == "refC"}, :namespace => nil, :string => "a1.b1.c1")) resolver.resolve(toplevelNamespace) assert_equal [c1], c2.refCs assert_equal c1, b2.refC assert_equal c1, a2.refC end def test_resolve_parent_namespace a1, a2, b1, b2, c1, c2, c3 = testModel toplevelNamespace = [a1, a2] resolver = RGen::ModelBuilder::ReferenceResolver.new setElementNames(resolver, [a1, a2, b1, b2, c1, c2, c3]) resolver.addJob(createJob( :receiver => c2, :reference => ClassC.ecore.eReferences.find{|r| r.name == "refA"}, :namespace => b1, :string => "a1")) resolver.addJob(createJob( :receiver => c2, :reference => ClassC.ecore.eReferences.find{|r| r.name == "refB"}, :namespace => b1, :string => "b1")) resolver.addJob(createJob( :receiver => c2, :reference => ClassC.ecore.eReferences.find{|r| r.name == "refCs"}, :namespace => b1, :string => "b1.c1")) resolver.addJob(createJob( :receiver => c2, :reference => ClassC.ecore.eReferences.find{|r| r.name == "refCs"}, :namespace => b1, :string => "a1.b1.c3")) resolver.resolve(toplevelNamespace) assert_equal a1, c2.refA assert_equal b1, c2.refB assert_equal [c1, c3], c2.refCs end def test_resolve_faulty a1, a2, b1, b2, c1, c2, c3 = testModel toplevelNamespace = [a1, a2] resolver = RGen::ModelBuilder::ReferenceResolver.new setElementNames(resolver, [a1, a2, b1, b2, c1, c2, c3]) resolver.addJob(createJob( :receiver => c2, :reference => ClassC.ecore.eReferences.find{|r| r.name == "refCs"}, :namespace => b1, :string => "b1.c5")) assert_raise RGen::ModelBuilder::ReferenceResolver::ResolverException do resolver.resolve(toplevelNamespace) end end def test_ambiguous_prefix a = ClassA.new(:name => "name1") b1 = ClassB.new(:name => "name1", :parentA => a) b2 = ClassB.new(:name => "target", :parentA => a) c1 = ClassC.new(:name => "name21", :parentB => b1) c2 = ClassC.new(:name => "name22", :parentB => b1) toplevelNamespace = [a] resolver = RGen::ModelBuilder::ReferenceResolver.new setElementNames(resolver, [a, b1, b2, c1, c2]) resolver.addJob(createJob( :receiver => c2, :reference => ClassC.ecore.eReferences.find{|r| r.name == "refCs"}, :namespace => b1, :string => "name1.name1.name21")) resolver.addJob(createJob( :receiver => c2, :reference => ClassC.ecore.eReferences.find{|r| r.name == "refB"}, :namespace => b1, :string => "name1.target")) resolver.resolve(toplevelNamespace) assert_equal [c1], c2.refCs assert_equal b2, c2.refB end endrgen-0.7.0/test/model_builder/builder_test.rb0000644000004100000410000002050212352210062021270 0ustar www-datawww-data$:.unshift File.dirname(__FILE__) + "/../lib" require 'test/unit' require 'rgen/ecore/ecore' require 'rgen/ecore/ecore_builder_methods' require 'rgen/environment' require 'rgen/model_builder' require 'model_builder/statemachine_metamodel' class ModelBuilderTest < Test::Unit::TestCase def test_statemachine result = RGen::ModelBuilder.build(StatemachineMetamodel) do statemachine "Airconditioner" do state "Off", :kind => :START compositeState "On" do state "Heating" do transition :as => :outgoingTransition, :targetState => "Cooling", :statemachine => "Airconditioner" end state "Cooling" do end end transition :sourceState => "On.Cooling", :targetState => "On.Heating" do _using Condition::TimeCondition do timeCondition :as => :condition, :timeout => 100 end Condition::TimeCondition.timeCondition :as => :condition, :timeout => 10 end end _using Condition do statemachine "AirconExtension" do s = state "StartState" transition :sourceState => s, :targetState => "Airconditioner.Off" end end end assert result.is_a?(Array) assert_equal 2, result.size sm1 = result[0] assert sm1.is_a?(StatemachineMetamodel::Statemachine) assert_equal "Airconditioner", sm1.name assert_equal 2, sm1.state.size offState = sm1.state[0] assert offState.is_a?(StatemachineMetamodel::State) assert_equal "Off", offState.name assert_equal :START, offState.kind onState = sm1.state[1] assert onState.is_a?(StatemachineMetamodel::CompositeState) assert_equal "On", onState.name assert_equal 2, onState.state.size hState = onState.state[0] assert hState.is_a?(StatemachineMetamodel::State) assert_equal "Heating", hState.name cState = onState.state[1] assert cState.is_a?(StatemachineMetamodel::State) assert_equal "Cooling", cState.name assert_equal 1, hState.outgoingTransition.size hOutTrans = hState.outgoingTransition[0] assert hOutTrans.is_a?(StatemachineMetamodel::Transition) assert_equal cState, hOutTrans.targetState assert_equal sm1, hOutTrans.statemachine assert_equal 1, hState.incomingTransition.size hInTrans = hState.incomingTransition[0] assert hInTrans.is_a?(StatemachineMetamodel::Transition) assert_equal cState, hInTrans.sourceState assert_equal sm1, hInTrans.statemachine assert_equal 2, hInTrans.condition.size assert hInTrans.condition[0].is_a?(StatemachineMetamodel::Condition::TimeCondition::TimeCondition) assert_equal 100, hInTrans.condition[0].timeout assert hInTrans.condition[1].is_a?(StatemachineMetamodel::Condition::TimeCondition::TimeCondition) assert_equal 10, hInTrans.condition[1].timeout sm2 = result[1] assert sm2.is_a?(StatemachineMetamodel::Statemachine) assert_equal "AirconExtension", sm2.name assert_equal 1, sm2.state.size sState = sm2.state[0] assert sState.is_a?(StatemachineMetamodel::State) assert_equal "StartState", sState.name assert_equal 1, sState.outgoingTransition.size assert sState.outgoingTransition[0].is_a?(StatemachineMetamodel::Transition) assert_equal offState, sState.outgoingTransition[0].targetState assert_equal sm2, sState.outgoingTransition[0].statemachine end def test_dynamic numStates = 5 env = RGen::Environment.new result = RGen::ModelBuilder.build(StatemachineMetamodel, env) do sm = statemachine "SM#{numStates}" do (1..numStates).each do |i| state "State#{i}" do transition :as => :outgoingTransition, :targetState => "State#{i < numStates ? i+1 : 1}", :statemachine => sm end end end end assert_equal 11, env.elements.size assert_equal "SM5", result[0].name state = result[0].state.first assert_equal "State1", state.name state = state.outgoingTransition.first.targetState assert_equal "State2", state.name state = state.outgoingTransition.first.targetState assert_equal "State3", state.name state = state.outgoingTransition.first.targetState assert_equal "State4", state.name state = state.outgoingTransition.first.targetState assert_equal "State5", state.name assert_equal result[0].state[0], state.outgoingTransition.first.targetState end def test_multiref result = RGen::ModelBuilder.build(StatemachineMetamodel) do a = transition transition "b" transition "c" state :outgoingTransition => [a, "b", "c"] end assert result[0].is_a?(StatemachineMetamodel::Transition) assert result[1].is_a?(StatemachineMetamodel::Transition) assert !result[1].respond_to?(:name) assert result[2].is_a?(StatemachineMetamodel::Transition) assert !result[2].respond_to?(:name) state = result[3] assert state.is_a?(StatemachineMetamodel::State) assert_equal result[0], state.outgoingTransition[0] assert_equal result[1], state.outgoingTransition[1] assert_equal result[2], state.outgoingTransition[2] end module TestMetamodel extend RGen::MetamodelBuilder::ModuleExtension # these classes have no name class TestA < RGen::MetamodelBuilder::MMBase end class TestB < RGen::MetamodelBuilder::MMBase end class TestC < RGen::MetamodelBuilder::MMBase end TestA.contains_many 'testB', TestB, 'testA' TestC.has_one 'testB', TestB end def test_helper_names result = RGen::ModelBuilder.build(TestMetamodel) do testA "_a" do testB "_b" end testC :testB => "_a._b" end assert result[0].is_a?(TestMetamodel::TestA) assert result[1].is_a?(TestMetamodel::TestC) assert_equal result[0].testB[0], result[1].testB end def test_ecore result = RGen::ModelBuilder.build(RGen::ECore, nil, RGen::ECore::ECoreBuilderMethods) do ePackage "TestPackage1" do eClass "TestClass1" do eAttribute "attr1", :eType => RGen::ECore::EString eAttr "attr2", RGen::ECore::EInt eBiRef "biRef1", "TestClass2", "testClass1" contains_1toN 'testClass2', "TestClass2", "tc1Parent" end eClass "TestClass2" do eRef "ref1", "TestClass1" end end end assert result.is_a?(Array) assert_equal 1, result.size p1 = result.first assert p1.is_a?(RGen::ECore::EPackage) assert_equal "TestPackage1", p1.name # TestClass1 class1 = p1.eClassifiers.find{|c| c.name == "TestClass1"} assert_not_nil class1 assert class1.is_a?(RGen::ECore::EClass) # TestClass1.attr1 attr1 = class1.eAllAttributes.find{|a| a.name == "attr1"} assert_not_nil attr1 assert_equal RGen::ECore::EString, attr1.eType # TestClass1.attr2 attr2 = class1.eAllAttributes.find{|a| a.name == "attr2"} assert_not_nil attr2 assert_equal RGen::ECore::EInt, attr2.eType # TestClass2 class2 = p1.eClassifiers.find{|c| c.name == "TestClass2"} assert_not_nil class2 assert class2.is_a?(RGen::ECore::EClass) # TestClass2.ref1 ref1 = class2.eAllReferences.find{|a| a.name == "ref1"} assert_not_nil ref1 assert_equal class1, ref1.eType # TestClass1.biRef1 biRef1 = class1.eAllReferences.find{|r| r.name == "biRef1"} assert_not_nil biRef1 assert_equal class2, biRef1.eType biRef1Opp = class2.eAllReferences.find {|r| r.name == "testClass1"} assert_not_nil biRef1Opp assert_equal class1, biRef1Opp.eType assert_equal biRef1Opp, biRef1.eOpposite assert_equal biRef1, biRef1Opp.eOpposite # TestClass1.testClass2 tc2Ref = class1.eAllReferences.find{|r| r.name == "testClass2"} assert_not_nil tc2Ref assert_equal class2, tc2Ref.eType assert tc2Ref.containment assert_equal -1, tc2Ref.upperBound tc2RefOpp = class2.eAllReferences.find{|r| r.name == "tc1Parent"} assert_not_nil tc2RefOpp assert_equal class1, tc2RefOpp.eType assert !tc2RefOpp.containment assert_equal 1, tc2RefOpp.upperBound end endrgen-0.7.0/test/model_builder/ecore_internal.rb0000644000004100000410000002342712352210062021605 0ustar www-datawww-dataePackage "ECore", :eSuperPackage => "" do eClass "EObject", :abstract => false, :interface => false, :eSubTypes => ["EAnnotation"], :instanceClassName => "RGen::ECore::EObject" eClass "EModelElement", :abstract => false, :interface => false, :eSubTypes => ["EAnnotation", "ENamedElement", "ETypeArgument", "EFactory"], :instanceClassName => "RGen::ECore::EModelElement" do eReference "eAnnotations", :containment => true, :resolveProxies => false, :eOpposite => "EAnnotation.eModelElement", :upperBound => -1, :eType => "EAnnotation" end eClass "EAnnotation", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EAnnotation" do eAttribute "source", :eType => "" eReference "eModelElement", :eOpposite => "EModelElement.eAnnotations", :eType => "EModelElement" eReference "details", :containment => true, :resolveProxies => false, :upperBound => -1, :eType => "EStringToStringMapEntry" eReference "contents", :containment => true, :resolveProxies => false, :upperBound => -1, :eType => "EObject" eReference "references", :upperBound => -1, :eType => "EObject" end eClass "ENamedElement", :abstract => false, :interface => false, :eSubTypes => ["ETypedElement", "EClassifier", "EEnumLiteral", "EPackage"], :instanceClassName => "RGen::ECore::ENamedElement" do eAttribute "name", :eType => "" end eClass "ETypedElement", :abstract => false, :interface => false, :eSubTypes => ["EStructuralFeature", "EOperation", "EParameter"], :instanceClassName => "RGen::ECore::ETypedElement" do eAttribute "lowerBound", :defaultValueLiteral => "0", :eType => "" eAttribute "ordered", :defaultValueLiteral => "true", :eType => "" eAttribute "unique", :defaultValueLiteral => "true", :eType => "" eAttribute "upperBound", :defaultValueLiteral => "1", :eType => "" eAttribute "many", :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "" eAttribute "required", :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "" eReference "eType", :eType => "EClassifier" end eClass "EStructuralFeature", :abstract => false, :interface => false, :eSubTypes => ["EAttribute", "EReference"], :instanceClassName => "RGen::ECore::EStructuralFeature" do eAttribute "changeable", :defaultValueLiteral => "true", :eType => "" eAttribute "defaultValue", :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "" eAttribute "defaultValueLiteral", :eType => "" eAttribute "derived", :defaultValueLiteral => "false", :eType => "" eAttribute "transient", :defaultValueLiteral => "false", :eType => "" eAttribute "unsettable", :defaultValueLiteral => "false", :eType => "" eAttribute "volatile", :defaultValueLiteral => "false", :eType => "" eReference "eContainingClass", :eOpposite => "EClass.eStructuralFeatures", :eType => "EClass" end eClass "EAttribute", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EAttribute" do eAttribute "iD", :defaultValueLiteral => "false", :eType => "" eReference "eAttributeType", :changeable => false, :derived => true, :transient => true, :volatile => true, :lowerBound => 1, :eType => "EDataType" end eClass "EClassifier", :abstract => false, :interface => false, :eSubTypes => ["EDataType", "EClass"], :instanceClassName => "RGen::ECore::EClassifier" do eAttribute "defaultValue", :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "" eAttribute "instanceClass", :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "" eAttribute "instanceClassName", :eType => "" eReference "ePackage", :eOpposite => "EPackage.eClassifiers", :eType => "EPackage" end eClass "EDataType", :abstract => false, :interface => false, :eSubTypes => ["EGenericType", "EEnum"], :instanceClassName => "RGen::ECore::EDataType" do eAttribute "serializable", :eType => "" end eClass "EGenericType", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EGenericType" do eReference "eClassifier", :eType => "EDataType" eReference "eParameter", :eOpposite => "EParameter.eGenericType", :eType => "EParameter" eReference "eTypeArguments", :containment => true, :eOpposite => "ETypeArgument.eGenericType", :upperBound => -1, :eType => "ETypeArgument" end eClass "ETypeArgument", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::ETypeArgument" do eReference "eClassifier", :eType => "EDataType" eReference "eGenericType", :eOpposite => "EGenericType.eTypeArguments", :eType => "EGenericType" end eClass "EEnum", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EEnum" do eReference "eLiterals", :containment => true, :resolveProxies => false, :eOpposite => "EEnumLiteral.eEnum", :upperBound => -1, :eType => "EEnumLiteral" end eClass "EEnumLiteral", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EEnumLiteral" do eAttribute "literal", :eType => "" eAttribute "value", :eType => "" eReference "eEnum", :eOpposite => "EEnum.eLiterals", :eType => "EEnum" end eClass "EFactory", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EFactory" do eReference "ePackage", :resolveProxies => false, :eOpposite => "EPackage.eFactoryInstance", :transient => true, :lowerBound => 1, :eType => "EPackage" end eClass "EOperation", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EOperation" do eReference "eContainingClass", :eOpposite => "EClass.eOperations", :eType => "EClass" eReference "eParameters", :containment => true, :resolveProxies => false, :eOpposite => "EParameter.eOperation", :upperBound => -1, :eType => "EParameter" eReference "eExceptions", :upperBound => -1, :eType => "EClassifier" end eClass "EPackage", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EPackage" do eAttribute "nsPrefix", :eType => "" eAttribute "nsURI", :eType => "" eReference "eClassifiers", :containment => true, :eOpposite => "EClassifier.ePackage", :upperBound => -1, :eType => "EClassifier" eReference "eSubpackages", :containment => true, :eOpposite => "eSuperPackage", :upperBound => -1, :eType => "EPackage" eReference "eSuperPackage", :eOpposite => "eSubpackages", :eType => "EPackage" eReference "eFactoryInstance", :eOpposite => "EFactory.ePackage", :eType => "EFactory" end eClass "EParameter", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EParameter" do eReference "eOperation", :eOpposite => "EOperation.eParameters", :eType => "EOperation" eReference "eGenericType", :containment => true, :eOpposite => "EGenericType.eParameter", :eType => "EGenericType" end eClass "EReference", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EReference" do eAttribute "container", :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "" eAttribute "containment", :defaultValueLiteral => "false", :eType => "" eAttribute "resolveProxies", :defaultValueLiteral => "true", :eType => "" eReference "eOpposite", :eType => "EReference" eReference "eReferenceType", :changeable => false, :derived => true, :transient => true, :volatile => true, :lowerBound => 1, :eType => "EClass" end eClass "EStringToStringMapEntry", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EStringToStringMapEntry" do eAttribute "key", :eType => "" eAttribute "value", :eType => "" end eClass "EClass", :abstract => false, :interface => false, :instanceClassName => "RGen::ECore::EClass" do eAttribute "abstract", :eType => "" eAttribute "interface", :eType => "" eReference "eIDAttribute", :resolveProxies => false, :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "EAttribute" eReference "eAllAttributes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EAttribute" eReference "eAllContainments", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EReference" eReference "eAllOperations", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EOperation" eReference "eAllReferences", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EReference" eReference "eAllStructuralFeatures", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EStructuralFeature" eReference "eAllSuperTypes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EClass" eReference "eAttributes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EAttribute" eReference "eReferences", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EReference" eReference "eOperations", :containment => true, :resolveProxies => false, :eOpposite => "EOperation.eContainingClass", :upperBound => -1, :eType => "EOperation" eReference "eStructuralFeatures", :containment => true, :resolveProxies => false, :eOpposite => "EStructuralFeature.eContainingClass", :upperBound => -1, :eType => "EStructuralFeature" eReference "eSuperTypes", :eOpposite => "eSubTypes", :upperBound => -1, :eType => "EClass" eReference "eSubTypes", :eOpposite => "eSuperTypes", :upperBound => -1, :eType => "EClass" end end rgen-0.7.0/test/model_builder/test_model/0000755000004100000410000000000012352210062020416 5ustar www-datawww-datargen-0.7.0/test/model_builder/test_model/statemachine1.rb0000644000004100000410000000132212352210062023467 0ustar www-datawww-datastatemachine "Airconditioner" do state "Off", :kind => :START compositeState "On" do state "Heating" do transition :as => :outgoingTransition, :targetState => "Cooling", :statemachine => "Airconditioner" end state "Cooling" do end end transition :sourceState => "On.Cooling", :targetState => "On.Heating" do _using Condition::TimeCondition do timeCondition :as => :condition, :timeout => 100 end Condition::TimeCondition.timeCondition :as => :condition, :timeout => 10 end end _using Condition do statemachine "AirconExtension" do s = state "StartState" transition :sourceState => s, :targetState => "Airconditioner.Off" end end rgen-0.7.0/test/model_builder/ecore_original_regenerated.rb0000644000004100000410000002314412352210062024136 0ustar www-datawww-dataePackage "ecore", :nsPrefix => "ecore", :nsURI => "http://www.eclipse.org/emf/2002/Ecore" do eClass "EAttribute" do eAttribute "iD" eReference "eAttributeType", :changeable => false, :derived => true, :transient => true, :volatile => true, :lowerBound => 1 end eClass "EAnnotation" do eAttribute "source" eReference "details", :containment => true, :resolveProxies => false, :upperBound => -1 eReference "eModelElement", :resolveProxies => false, :transient => true eReference "contents", :containment => true, :resolveProxies => false, :upperBound => -1 eReference "references", :upperBound => -1 end eClass "EClass" do eAttribute "abstract" eAttribute "interface" eReference "eSuperTypes", :unsettable => true, :upperBound => -1 eReference "eOperations", :containment => true, :resolveProxies => false, :upperBound => -1 eReference "eAllAttributes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1 eReference "eAllReferences", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1 eReference "eReferences", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1 eReference "eAttributes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1 eReference "eAllContainments", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1 eReference "eAllOperations", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1 eReference "eAllStructuralFeatures", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1 eReference "eAllSuperTypes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1 eReference "eIDAttribute", :resolveProxies => false, :changeable => false, :derived => true, :transient => true, :volatile => true eReference "eStructuralFeatures", :containment => true, :resolveProxies => false, :upperBound => -1 eReference "eGenericSuperTypes", :containment => true, :resolveProxies => false, :unsettable => true, :upperBound => -1 eReference "eAllGenericSuperTypes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1 end eClass "EClassifier", :abstract => true do eAttribute "instanceClassName", :unsettable => true, :volatile => true eAttribute "instanceClass", :changeable => false, :derived => true, :transient => true, :volatile => true eAttribute "defaultValue", :changeable => false, :derived => true, :transient => true, :volatile => true eAttribute "instanceTypeName", :unsettable => true, :volatile => true eReference "ePackage", :changeable => false, :transient => true eReference "eTypeParameters", :containment => true, :upperBound => -1 end eClass "EDataType" do eAttribute "serializable", :defaultValueLiteral => "true" end eClass "EEnum" do eReference "eLiterals", :containment => true, :resolveProxies => false, :upperBound => -1 end eClass "EEnumLiteral" do eAttribute "value" eAttribute "instance", :transient => true eAttribute "literal" eReference "eEnum", :resolveProxies => false, :changeable => false, :transient => true end eClass "EFactory" do eReference "ePackage", :resolveProxies => false, :transient => true, :lowerBound => 1 end eClass "EModelElement", :abstract => true do eReference "eAnnotations", :containment => true, :resolveProxies => false, :upperBound => -1 end eClass "ENamedElement", :abstract => true do eAttribute "name" end eClass "EObject" eClass "EOperation" do eReference "eContainingClass", :resolveProxies => false, :changeable => false, :transient => true eReference "eTypeParameters", :containment => true, :upperBound => -1 eReference "eParameters", :containment => true, :resolveProxies => false, :upperBound => -1 eReference "eExceptions", :unsettable => true, :upperBound => -1 eReference "eGenericExceptions", :containment => true, :resolveProxies => false, :unsettable => true, :upperBound => -1 end eClass "EPackage" do eAttribute "nsURI" eAttribute "nsPrefix" eReference "eFactoryInstance", :resolveProxies => false, :transient => true, :lowerBound => 1 eReference "eClassifiers", :containment => true, :upperBound => -1 eReference "eSubpackages", :containment => true, :upperBound => -1 eReference "eSuperPackage", :changeable => false, :transient => true end eClass "EParameter" do eReference "eOperation", :resolveProxies => false, :changeable => false, :transient => true end eClass "EReference" do eAttribute "containment" eAttribute "container", :changeable => false, :derived => true, :transient => true, :volatile => true eAttribute "resolveProxies", :defaultValueLiteral => "true" eReference "eOpposite" eReference "eReferenceType", :changeable => false, :derived => true, :transient => true, :volatile => true, :lowerBound => 1 eReference "eKeys", :upperBound => -1 end eClass "EStructuralFeature", :abstract => true do eAttribute "changeable", :defaultValueLiteral => "true" eAttribute "volatile" eAttribute "transient" eAttribute "defaultValueLiteral" eAttribute "defaultValue", :changeable => false, :derived => true, :transient => true, :volatile => true eAttribute "unsettable" eAttribute "derived" eReference "eContainingClass", :resolveProxies => false, :changeable => false, :transient => true end eClass "ETypedElement", :abstract => true do eAttribute "ordered", :defaultValueLiteral => "true" eAttribute "unique", :defaultValueLiteral => "true" eAttribute "lowerBound" eAttribute "upperBound", :defaultValueLiteral => "1" eAttribute "many", :changeable => false, :derived => true, :transient => true, :volatile => true eAttribute "required", :changeable => false, :derived => true, :transient => true, :volatile => true eReference "eType", :unsettable => true, :volatile => true eReference "eGenericType", :containment => true, :resolveProxies => false, :unsettable => true, :volatile => true end eDataType "EBigDecimal", :instanceClassName => "java.math.BigDecimal" eDataType "EBigInteger", :instanceClassName => "java.math.BigInteger" eDataType "EBoolean", :instanceClassName => "boolean" eDataType "EBooleanObject", :instanceClassName => "java.lang.Boolean" eDataType "EByte", :instanceClassName => "byte" eDataType "EByteArray", :instanceClassName => "byte[]" eDataType "EByteObject", :instanceClassName => "java.lang.Byte" eDataType "EChar", :instanceClassName => "char" eDataType "ECharacterObject", :instanceClassName => "java.lang.Character" eDataType "EDate", :instanceClassName => "java.util.Date" eDataType "EDiagnosticChain", :serializable => false, :instanceClassName => "org.eclipse.emf.common.util.DiagnosticChain" eDataType "EDouble", :instanceClassName => "double" eDataType "EDoubleObject", :instanceClassName => "java.lang.Double" eDataType "EEList", :serializable => false, :instanceClassName => "org.eclipse.emf.common.util.EList" do eTypeParameter "E" end eDataType "EEnumerator", :serializable => false, :instanceClassName => "org.eclipse.emf.common.util.Enumerator" eDataType "EFeatureMap", :serializable => false, :instanceClassName => "org.eclipse.emf.ecore.util.FeatureMap" eDataType "EFeatureMapEntry", :serializable => false, :instanceClassName => "org.eclipse.emf.ecore.util.FeatureMap$Entry" eDataType "EFloat", :instanceClassName => "float" eDataType "EFloatObject", :instanceClassName => "java.lang.Float" eDataType "EInt", :instanceClassName => "int" eDataType "EIntegerObject", :instanceClassName => "java.lang.Integer" eDataType "EJavaClass", :instanceClassName => "java.lang.Class" do eTypeParameter "T" end eDataType "EJavaObject", :instanceClassName => "java.lang.Object" eDataType "ELong", :instanceClassName => "long" eDataType "ELongObject", :instanceClassName => "java.lang.Long" eDataType "EMap", :serializable => false, :instanceClassName => "java.util.Map" do eTypeParameter "K" eTypeParameter "V" end eDataType "EResource", :serializable => false, :instanceClassName => "org.eclipse.emf.ecore.resource.Resource" eDataType "EResourceSet", :serializable => false, :instanceClassName => "org.eclipse.emf.ecore.resource.ResourceSet" eDataType "EShort", :instanceClassName => "short" eDataType "EShortObject", :instanceClassName => "java.lang.Short" eDataType "EString", :instanceClassName => "java.lang.String" eClass "EStringToStringMapEntry", :instanceClassName => "java.util.Map$Entry" do eAttribute "key" eAttribute "value" end eDataType "ETreeIterator", :serializable => false, :instanceClassName => "org.eclipse.emf.common.util.TreeIterator" do eTypeParameter "E" end eClass "EGenericType" do eReference "eUpperBound", :containment => true, :resolveProxies => false eReference "eTypeArguments", :containment => true, :resolveProxies => false, :upperBound => -1 eReference "eRawType", :changeable => false, :derived => true, :transient => true, :lowerBound => 1 eReference "eLowerBound", :containment => true, :resolveProxies => false eReference "eTypeParameter", :resolveProxies => false eReference "eClassifier" end eClass "ETypeParameter" do eReference "eBounds", :containment => true, :resolveProxies => false, :upperBound => -1 end end rgen-0.7.0/test/model_builder/builder_context_test.rb0000644000004100000410000000362612352210062023044 0ustar www-datawww-data$:.unshift File.dirname(__FILE__)+"/../lib" require 'test/unit' require 'rgen/ecore/ecore' require 'rgen/model_builder/builder_context' class BuilderContextTest < Test::Unit::TestCase module BuilderExtension1 module PackageA def inPackAExt 3 end module PackageB def inPackBExt 5 end end end end class BuilderContext def inBuilderContext 7 end end def test_extensionContainerFactory aboveRoot = RGen::ECore::EPackage.new(:name => "AboveRoot") root = RGen::ECore::EPackage.new(:name => "Root", :eSuperPackage => aboveRoot) packageA = RGen::ECore::EPackage.new(:name => "PackageA", :eSuperPackage => root) packageB = RGen::ECore::EPackage.new(:name => "PackageB", :eSuperPackage => packageA) packageC = RGen::ECore::EPackage.new(:name => "PackageBC", :eSuperPackage => packageA) factory = RGen::ModelBuilder::BuilderContext::ExtensionContainerFactory.new(root, BuilderExtension1, BuilderContext.new) assert_equal BuilderExtension1::PackageA, factory.moduleForPackage(packageA) packAExt = factory.extensionContainer(packageA) assert packAExt.respond_to?(:inPackAExt) assert !packAExt.respond_to?(:inPackBExt) assert_equal 3, packAExt.inPackAExt assert_equal 7, packAExt.inBuilderContext assert_equal BuilderExtension1::PackageA::PackageB, factory.moduleForPackage(packageB) packBExt = factory.extensionContainer(packageB) assert !packBExt.respond_to?(:inPackAExt) assert packBExt.respond_to?(:inPackBExt) assert_equal 5, packBExt.inPackBExt assert_equal 7, packBExt.inBuilderContext assert_raise RuntimeError do # aboveRoot is not contained within root assert_nil factory.moduleForPackage(aboveRoot) end assert_nil factory.moduleForPackage(packageC) end endrgen-0.7.0/test/model_builder/statemachine_metamodel.rb0000644000004100000410000000225212352210062023301 0ustar www-datawww-data# a test metamodel used by the following tests module StatemachineMetamodel extend RGen::MetamodelBuilder::ModuleExtension module Condition extend RGen::MetamodelBuilder::ModuleExtension class Condition < RGen::MetamodelBuilder::MMBase end module TimeCondition extend RGen::MetamodelBuilder::ModuleExtension class TimeCondition < Condition has_attr 'timeout', Integer end end end class Statemachine < RGen::MetamodelBuilder::MMBase has_attr 'name' end class State < RGen::MetamodelBuilder::MMBase has_attr 'name' has_attr 'kind', RGen::MetamodelBuilder::DataTypes::Enum.new([:START]) end class CompositeState < State has_attr 'name' contains_many 'state', State, 'compositeState' end class Transition < RGen::MetamodelBuilder::MMBase many_to_one 'sourceState', State, 'outgoingTransition' many_to_one 'targetState', State, 'incomingTransition' has_many 'condition', Condition::Condition end Statemachine.contains_many 'state', State, 'statemachine' Statemachine.contains_many 'transition', Transition, 'statemachine' end rgen-0.7.0/test/model_builder/serializer_test.rb0000644000004100000410000000455412352210062022024 0ustar www-datawww-data$:.unshift File.dirname(__FILE__) + "/../lib" require 'test/unit' require 'rgen/ecore/ecore' # The following would also influence other tests... # #module RGen::ECore # class EGenericType < EObject # contains_many_uni 'eTypeArguments', EGenericType # end # class ETypeParameter < ENamedElement # end # class EClassifier # contains_many_uni 'eTypeParameters', ETypeParameter # end # class ETypedElement # has_one 'eGenericType', EGenericType # end #end # #RGen::ECore::ECoreInterface.clear_ecore_cache #RGen::ECore::EString.ePackage = RGen::ECore.ecore require 'rgen/environment' require 'rgen/model_builder/model_serializer' require 'rgen/instantiator/ecore_xml_instantiator' require 'rgen/model_builder' require 'model_builder/statemachine_metamodel' class ModelSerializerTest < Test::Unit::TestCase def test_ecore_internal File.open(File.dirname(__FILE__)+"/ecore_internal.rb","w") do |f| serializer = RGen::ModelBuilder::ModelSerializer.new(f, RGen::ECore.ecore) serializer.serialize(RGen::ECore.ecore) end end def test_roundtrip model = %{\ statemachine "Airconditioner" do state "Off", :kind => :START compositeState "On" do state "Heating" state "Cooling" state "Dumm" end transition "_Transition1", :sourceState => "On.Cooling", :targetState => "On.Heating" transition "_Transition2", :sourceState => "On.Heating", :targetState => "On.Cooling" end } check_roundtrip(StatemachineMetamodel, model) end module AmbiguousRoleMM extend RGen::MetamodelBuilder::ModuleExtension class A < RGen::MetamodelBuilder::MMBase end class B < RGen::MetamodelBuilder::MMBase end class C < B end A.contains_many 'role1', B, 'back1' A.contains_many 'role2', B, 'back2' end def test_roundtrip_ambiguous_role model = %{\ a "_A1" do b "_B1", :as => :role1 b "_B2", :as => :role2 c "_C1", :as => :role2 end } check_roundtrip(AmbiguousRoleMM, model) end private def build_model(mm, model) RGen::ModelBuilder.build(mm) do eval(model) end end def check_roundtrip(mm, model) sm = build_model(mm, model) f = StringIO.new serializer = RGen::ModelBuilder::ModelSerializer.new(f, mm.ecore) serializer.serialize(sm) assert_equal model, f.string end end rgen-0.7.0/test/model_builder/ecore_original.rb0000644000004100000410000003064312352210062021573 0ustar www-datawww-dataePackage "ecore", :nsPrefix => "ecore", :nsURI => "http://www.eclipse.org/emf/2002/Ecore" do eClass "EAttribute", :eSuperTypes => ["EStructuralFeature"] do eAttribute "iD" eReference "eAttributeType", :changeable => false, :derived => true, :transient => true, :volatile => true, :lowerBound => 1, :eType => "EDataType" end eClass "EAnnotation", :eSuperTypes => ["EModelElement"] do eAttribute "source" eReference "details", :containment => true, :resolveProxies => false, :upperBound => -1, :eType => "EStringToStringMapEntry" eReference "eModelElement", :resolveProxies => false, :eOpposite => "EModelElement.eAnnotations", :transient => true, :eType => "EModelElement" eReference "contents", :containment => true, :resolveProxies => false, :upperBound => -1, :eType => "EObject" eReference "references", :upperBound => -1, :eType => "EObject" end eClass "EClass", :eSuperTypes => ["EClassifier"] do eAttribute "abstract" eAttribute "interface" eReference "eSuperTypes", :unsettable => true, :upperBound => -1, :eType => "EClass" eReference "eOperations", :containment => true, :resolveProxies => false, :eOpposite => "EOperation.eContainingClass", :upperBound => -1, :eType => "EOperation" eReference "eAllAttributes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EAttribute" eReference "eAllReferences", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EReference" eReference "eReferences", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EReference" eReference "eAttributes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EAttribute" eReference "eAllContainments", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EReference" eReference "eAllOperations", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EOperation" eReference "eAllStructuralFeatures", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EStructuralFeature" eReference "eAllSuperTypes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EClass" eReference "eIDAttribute", :resolveProxies => false, :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "EAttribute" eReference "eStructuralFeatures", :containment => true, :resolveProxies => false, :eOpposite => "EStructuralFeature.eContainingClass", :upperBound => -1, :eType => "EStructuralFeature" eReference "eGenericSuperTypes", :containment => true, :resolveProxies => false, :unsettable => true, :upperBound => -1, :eType => "EGenericType" eReference "eAllGenericSuperTypes", :changeable => false, :derived => true, :transient => true, :volatile => true, :upperBound => -1, :eType => "EGenericType" end eClass "EClassifier", :abstract => true, :eSuperTypes => ["ENamedElement"], :eSubTypes => ["EClass", "EDataType"] do eAttribute "instanceClassName", :unsettable => true, :volatile => true eAttribute "instanceClass", :changeable => false, :derived => true, :transient => true, :volatile => true eAttribute "defaultValue", :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "EJavaObject" eAttribute "instanceTypeName", :unsettable => true, :volatile => true eReference "ePackage", :eOpposite => "EPackage.eClassifiers", :changeable => false, :transient => true, :eType => "EPackage" eReference "eTypeParameters", :containment => true, :upperBound => -1, :eType => "ETypeParameter" end eClass "EDataType", :eSuperTypes => ["EClassifier"], :eSubTypes => ["EEnum"] do eAttribute "serializable", :defaultValueLiteral => "true" end eClass "EEnum", :eSuperTypes => ["EDataType"] do eReference "eLiterals", :containment => true, :resolveProxies => false, :eOpposite => "EEnumLiteral.eEnum", :upperBound => -1, :eType => "EEnumLiteral" end eClass "EEnumLiteral", :eSuperTypes => ["ENamedElement"] do eAttribute "value" eAttribute "instance", :transient => true, :eType => "EEnumerator" eAttribute "literal" eReference "eEnum", :resolveProxies => false, :eOpposite => "EEnum.eLiterals", :changeable => false, :transient => true, :eType => "EEnum" end eClass "EFactory", :eSuperTypes => ["EModelElement"] do eReference "ePackage", :resolveProxies => false, :eOpposite => "EPackage.eFactoryInstance", :transient => true, :lowerBound => 1, :eType => "EPackage" end eClass "EModelElement", :abstract => true, :eSuperTypes => ["EObject"], :eSubTypes => ["EAnnotation", "EFactory", "ENamedElement"] do eReference "eAnnotations", :containment => true, :resolveProxies => false, :eOpposite => "EAnnotation.eModelElement", :upperBound => -1, :eType => "EAnnotation" end eClass "ENamedElement", :abstract => true, :eSuperTypes => ["EModelElement"], :eSubTypes => ["EClassifier", "EEnumLiteral", "EPackage", "ETypedElement", "ETypeParameter"] do eAttribute "name" end eClass "EObject", :eSubTypes => ["EModelElement", "EGenericType"] eClass "EOperation", :eSuperTypes => ["ETypedElement"] do eReference "eContainingClass", :resolveProxies => false, :eOpposite => "EClass.eOperations", :changeable => false, :transient => true, :eType => "EClass" eReference "eTypeParameters", :containment => true, :upperBound => -1, :eType => "ETypeParameter" eReference "eParameters", :containment => true, :resolveProxies => false, :eOpposite => "EParameter.eOperation", :upperBound => -1, :eType => "EParameter" eReference "eExceptions", :unsettable => true, :upperBound => -1, :eType => "EClassifier" eReference "eGenericExceptions", :containment => true, :resolveProxies => false, :unsettable => true, :upperBound => -1, :eType => "EGenericType" end eClass "EPackage", :eSuperTypes => ["ENamedElement"] do eAttribute "nsURI" eAttribute "nsPrefix" eReference "eFactoryInstance", :resolveProxies => false, :eOpposite => "EFactory.ePackage", :transient => true, :lowerBound => 1, :eType => "EFactory" eReference "eClassifiers", :containment => true, :eOpposite => "EClassifier.ePackage", :upperBound => -1, :eType => "EClassifier" eReference "eSubpackages", :containment => true, :eOpposite => "eSuperPackage", :upperBound => -1, :eType => "EPackage" eReference "eSuperPackage", :eOpposite => "eSubpackages", :changeable => false, :transient => true, :eType => "EPackage" end eClass "EParameter", :eSuperTypes => ["ETypedElement"] do eReference "eOperation", :resolveProxies => false, :eOpposite => "EOperation.eParameters", :changeable => false, :transient => true, :eType => "EOperation" end eClass "EReference", :eSuperTypes => ["EStructuralFeature"] do eAttribute "containment" eAttribute "container", :changeable => false, :derived => true, :transient => true, :volatile => true eAttribute "resolveProxies", :defaultValueLiteral => "true" eReference "eOpposite", :eType => "EReference" eReference "eReferenceType", :changeable => false, :derived => true, :transient => true, :volatile => true, :lowerBound => 1, :eType => "EClass" eReference "eKeys", :upperBound => -1, :eType => "EAttribute" end eClass "EStructuralFeature", :abstract => true, :eSuperTypes => ["ETypedElement"], :eSubTypes => ["EAttribute", "EReference"] do eAttribute "changeable", :defaultValueLiteral => "true" eAttribute "volatile" eAttribute "transient" eAttribute "defaultValueLiteral" eAttribute "defaultValue", :changeable => false, :derived => true, :transient => true, :volatile => true, :eType => "EJavaObject" eAttribute "unsettable" eAttribute "derived" eReference "eContainingClass", :resolveProxies => false, :eOpposite => "EClass.eStructuralFeatures", :changeable => false, :transient => true, :eType => "EClass" end eClass "ETypedElement", :abstract => true, :eSuperTypes => ["ENamedElement"], :eSubTypes => ["EOperation", "EParameter", "EStructuralFeature"] do eAttribute "ordered", :defaultValueLiteral => "true" eAttribute "unique", :defaultValueLiteral => "true" eAttribute "lowerBound" eAttribute "upperBound", :defaultValueLiteral => "1" eAttribute "many", :changeable => false, :derived => true, :transient => true, :volatile => true eAttribute "required", :changeable => false, :derived => true, :transient => true, :volatile => true eReference "eType", :unsettable => true, :volatile => true, :eType => "EClassifier" eReference "eGenericType", :containment => true, :resolveProxies => false, :unsettable => true, :volatile => true, :eType => "EGenericType" end eDataType "EBigDecimal", :instanceClassName => "java.math.BigDecimal" eDataType "EBigInteger", :instanceClassName => "java.math.BigInteger" eDataType "EBoolean", :instanceClassName => "boolean" eDataType "EBooleanObject", :instanceClassName => "java.lang.Boolean" eDataType "EByte", :instanceClassName => "byte" eDataType "EByteArray", :instanceClassName => "byte[]" eDataType "EByteObject", :instanceClassName => "java.lang.Byte" eDataType "EChar", :instanceClassName => "char" eDataType "ECharacterObject", :instanceClassName => "java.lang.Character" eDataType "EDate", :instanceClassName => "java.util.Date" eDataType "EDiagnosticChain", :serializable => false, :instanceClassName => "org.eclipse.emf.common.util.DiagnosticChain" eDataType "EDouble", :instanceClassName => "double" eDataType "EDoubleObject", :instanceClassName => "java.lang.Double" eDataType "EEList", :serializable => false, :instanceClassName => "org.eclipse.emf.common.util.EList" do eTypeParameter "E" end eDataType "EEnumerator", :serializable => false, :instanceClassName => "org.eclipse.emf.common.util.Enumerator" eDataType "EFeatureMap", :serializable => false, :instanceClassName => "org.eclipse.emf.ecore.util.FeatureMap" eDataType "EFeatureMapEntry", :serializable => false, :instanceClassName => "org.eclipse.emf.ecore.util.FeatureMap$Entry" eDataType "EFloat", :instanceClassName => "float" eDataType "EFloatObject", :instanceClassName => "java.lang.Float" eDataType "EInt", :instanceClassName => "int" eDataType "EIntegerObject", :instanceClassName => "java.lang.Integer" eDataType "EJavaClass", :instanceClassName => "java.lang.Class" do eTypeParameter "T" end eDataType "EJavaObject", :instanceClassName => "java.lang.Object" eDataType "ELong", :instanceClassName => "long" eDataType "ELongObject", :instanceClassName => "java.lang.Long" eDataType "EMap", :serializable => false, :instanceClassName => "java.util.Map" do eTypeParameter "K" eTypeParameter "V" end eDataType "EResource", :serializable => false, :instanceClassName => "org.eclipse.emf.ecore.resource.Resource" eDataType "EResourceSet", :serializable => false, :instanceClassName => "org.eclipse.emf.ecore.resource.ResourceSet" eDataType "EShort", :instanceClassName => "short" eDataType "EShortObject", :instanceClassName => "java.lang.Short" eDataType "EString", :instanceClassName => "java.lang.String" eClass "EStringToStringMapEntry", :instanceClassName => "java.util.Map$Entry" do eAttribute "key" eAttribute "value" end eDataType "ETreeIterator", :serializable => false, :instanceClassName => "org.eclipse.emf.common.util.TreeIterator" do eTypeParameter "E" end eClass "EGenericType", :eSuperTypes => ["EObject"] do eReference "eUpperBound", :containment => true, :resolveProxies => false, :eType => "EGenericType" eReference "eTypeArguments", :containment => true, :resolveProxies => false, :upperBound => -1, :eType => "EGenericType" eReference "eRawType", :changeable => false, :derived => true, :transient => true, :lowerBound => 1, :eType => "EClassifier" eReference "eLowerBound", :containment => true, :resolveProxies => false, :eType => "EGenericType" eReference "eTypeParameter", :resolveProxies => false, :eType => "ETypeParameter" eReference "eClassifier", :eType => "EClassifier" end eClass "ETypeParameter", :eSuperTypes => ["ENamedElement"] do eReference "eBounds", :containment => true, :resolveProxies => false, :upperBound => -1, :eType => "EGenericType" end end rgen-0.7.0/test/testmodel/0000755000004100000410000000000012352210062015451 5ustar www-datawww-datargen-0.7.0/test/testmodel/manual_testmodel.xml0000644000004100000410000000100312352210062021522 0ustar www-datawww-data before kitchen after kitchen within toms room after toms room rgen-0.7.0/test/testmodel/ea_testmodel.eap0000644000004100000410000461400012352210062020612 0ustar www-datawww-dataStandard Jet DBnb` Ugr@?~1y0̝cǟFN7]D^(`T{6߱wCϯ34ay[|*|OJl>`&_Љ$g'DeFx -{% &&&'''((()))***+++,&,',(-)-*-+.,.-..////00011122 2 3 3 3 444555666% !"#$$ $!$"999>>>E#E$E%J&JJNNNSSSVV V \ \ \ ___hhhmmmqqquuuyyy~~~       !"#$%&        ! a`VCS           2                   IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n VCS     2  ObjectIdSIDACM FInheritable ObjectId1111/ @m6*,@a2@t_connectortag//////////- h{@a2@t_connectorconstraint@BBB66666664 @VC%{@a2@t_complexitytypesL@>>>22222220 @S{@a2@t_clients@666*******( @Nr 1@a2@t_category++++++++++) J{@a2@t_cardinality@ :::......., @$6*,@a2@t_attributetag//////////- >{@a2@t_attributeconstraints@CCC77777775 @9 {@/I(nS@t_attribute888,,,,,,,* @)<@U<@rptUseCasesbyActor@@ @K??33333331 @'Z]<@Z]<@rptUseCaseNotes"@@H<<0000000. @&<@<@rptqryObjectNotes@@J>>22222220 @%l|-@l|-@qdf_simpleobjectE@===1111111/ @#^|-@^|-@qdf_operationE@:::......., @"^|-@t 1@qdf_objectE@777+++++++) @!l|-@l|-@qdf_diagramlinkE@<<<0000000. @ l|-@l|-@qdf_attributeE@:::......., @<@@q_ucmetrics@@D88,,,,,,,* @@l<@c<@q_tcf@@>22&&&&&&&$ @ֱ<@ֱ<@q_sumecf@@A55)))))))' @5<@s<@q_resource@@@C77+++++++) @=<@&{<@q_realizes1.@@D88,,,,,,,* @<@(pz@q_pkgobject@@@D88,,,,,,,* @VC?CS  C           ObjectId AttributeOrderName1Name2 ExpressionFlag ObjectIdAttribute  @@xj<@usysQueries@888,,,,,,,* @rA@U2@usys_system-@888,,,,,,,* @1QH{@I(nS@t_trxtypes@777+++++++) @G{@U2@t_testtypes@888,,,,,,,* @f)E{@U2@t_tcf@222&&&&&&&$ @, 1@E(nS@t_tasks((((((((((& C{@|\B(nS@t_stereotypes@:::......., @|)B{@e$@t_statustypes1@:::......., @wB{@U2@t_scenariotypes@<<<0000000. @dQ@'7s@t_rtf9@222&&&&&&&$ @_>{@U2@t_roleconstraint:@===1111111/ @[!={@U2@t_risktypes{@888,,,,,,,* @X8Xt*M@U2@t_resources@888,,,,,,,* @OFE@U2@t_propertytypes@<<<0000000. @J]@.N@U2@t_projectroles@;;;///////- @Em;{@U2@t_problemtypes@;;;///////- @A6:{@U2@t_primitives"@999-------+ @?2@2@t_paletteitem.........., =2@2@t_palette**********( 4hn@N(nS@t_package@666*******( @06*,@U2@t_operationtag//////////- ,E8{@U2@t_operationpres7@<<<0000000. @(x7{@U2@t_operationposts8@===1111111/ @"6{@/I(nS@t_operationparams@>>>22222220 @VC S             szRelationshipgrbitccolumnicolumnszObjectszColumnszReferencedObjectszReferencedColumn   szObjectszReferencedObjectszRelationshipumlpatternq@999-------+ @ AF(nS@AF(nS@t_templateu@777+++++++) @%F(nS@AF(nS@t_document@777+++++++) @%F(nS@%F(nS@t_secuserpermissionP@@@@44444442 @%F(nS@%F(nS@t_secusergroupK@;;;///////- @ %F(nS@%F(nS@t_secuser@666*******( @ %F(nS@%F(nS@t_secpoliciesK@:::......., @%F(nS@%F(nS@t_secpermissionX@ <<<0000000. @%F(nS@%F(nS@t_seclocks@ 777+++++++) @%F(nS@%F(nS@t_secgrouppermissionQ@AAA55555553 @E(nS@%F(nS@t_secgroupN@777+++++++) @_+k2@+k2@t_xref''''''''''% +/Ȫ<@ $@zz_q_orphans@@E99-------+ @X@|`n@usysOldTablesE@:::......., @`F{@U2@t_testclass#@888,,,,,,,* @pȌ@{@U2@t_rtfreportq888,,,,,,,* @Spl<{@U2@t_requiretypes@;;;///////- @C3{@U2@t_objecttrx-@888,,,,,,,* @/{@U2@t_objectrequires@===1111111/ @",{@U2@t_objectconstraint@???33333331 @ )"{@a2@t_mainttypesr@999-------+ @ {qg]SI?5T @p z ?@@@o{~ok\MI:+' xteVaRC  ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o  Tۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o     ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   6 6ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 6 5 5ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 5 4 4ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 4 3 3ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 3 2 2ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 2 1 1ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 1 0 0ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 0  @o{~ok\MI:+' xteVRC4J E Eۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o E $ $ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o $ > >ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o > 9 9ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 9 ) )ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o ) ( (ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o ( ' 'ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o ' & &ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o & % %ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o % $ $ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o $ # #ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o # " "ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o "  @tdg,ufm`wfvwr2 w,rakfbwfggruww,vfbxvfuhurxs$s`bl`hfdj`hu`oufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXt,brppfbwjrpvYt,brppfbwrut,d`w`w}sfvt,fbgt,josmfofpwvt,ofwirdt,rakfbwt,rakfbwuf`mj~fvt,rakfbwwfvwv t,s`bl`hfv!t,slhrakfbw2t,uf`mj~fvW2t,uf`mj~fvX2t,ufvrxubf2t,vxofbg2t,vxowbg2t,wbg2t,xbofwujbv2t,zjvjamfrakfbw2tdg,`wwujaxwf2 tdg,dj`hu`omjpl2 tdg,rakfbw2 tdg,rsfu`wjrp2 tdg,ufm`wfvwr2 tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd#o{@ov}vda%          IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        D @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2*+789 :!;"<#=$>%?&@'A($292>2E2J2N2S2V2\2l>m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$      B>E>+% Z]<@Z]<@TablesrptUseCaseNotes:+% <@<@TablesrptqryObjectNotes<+% l|-@l|-@Tablesqdf_simpleobject;+% l|-@l|-@Tablesqdf_relatesto8+% ^|-@^|-@Tablesqdf_operation8+% {qg]SI?U%@%{\%U%@%%Ȩ%@%=% @XI2 "D? % # $?H3                     $ %                !"#$%&      !" # $ %!&!!"""###$$ $ % % % &&&'''((())), &, ', (- )- *- +. ,. -. ./ ///00011122 2 3 3 3 444555666% !"#$$ $!$"999>>>E#E$E%J&JJNNNSSSVV V \ \ \ mmmrrrv          ! " # #'Q @ )+* ,-./#01+356@ 8"H P$IX ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '! '" '# '$ '% '& '' '( ' ') '+ ', '- ) ) ) ) ) ) ) )  )  ) ) ) '*) ))))))))) )) )))))))) )!)")#)$)%)&))')))*)+),)-).)/)0******* * ** )(-----+ @ @ w,brppfbwruw}sfvw,brppfbwru w,dj`hu`ow,dj`hu`orakfbwvw,dj`hu`ow}sfvw,dj`hu`ow,ofwujbw}sfvw,rakfbwofwujbv w,rakfbww,`wwujaxwfw,rakfbww,brppfbwru w,rakfbww,brppfbwruWw,rakfbww,ofwirdw,s`bl`hfw,dj`hu`ow,s`bl`hfw,dj`hu`ow}sfvw,s`bl`hfw,rakfbww,rakfbwbwruWbww,brppfbwruWbww,brppfbwru ,rakfbwofwujbv `hu`o j`hu`o @U2@Tablest_objecttypes8+% C3{@U2@Tablest_objecttrx6+% r2{@U2@Tablest_objecttests8+% )1{@RJ(nS@Tablest_objectscenarios<+% ;1{@U2@Tablest_objectrisks8+% ufN@U2@Tablest_objectresource;+% /{@U2@Tablest_objectrequires;+% Zb@U2@Tablest_objectproperties=+%  /{@E(nS@Tablest_objectproblems;+% ;R.{@U2@Tablest_objectmetrics:+% -{@g2@Tablest_objectfiles8+% -{@U2@Tablest_objecteffort9+% ",{@U2@Tablest_objectconstraint=+% %{@/I(nS@Tablest_object3+% !#{@a2@Tablest_metrictypes8+% f"{@a2@Tablest_method3+%  )"{@a2@Tablest_mainttypes7+% AF(nS@AF(nS@Tablest_lists2+% $@E(nS@Tablest_issues3+% 5NU@c@Tablest_implement6+% '2@'2@Tablest_image2+% 0!{@Fu@Tablest_html1+% 8 {@a2@Tablest_glossary5+%K w,`wwujaxwfw,brppfbwru w,brppfbwru w,brppfbwruw,dj`hu`ow,dj`hu`ow,dj`hu`orakfbwvw,dj`hu`ow}sfvw,ofwirdw,rakfbww,rakfbwofwujbv kfbwwu|{w,rakfbww}sfv{w,rbg{w,rsfu`wjrp{ w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$w,sujojwjzfv$w,suramfow}sfv$w,surkfbwurmfv$ w,sursfuw}w}sfv$ w,uftxjufw}sfv$ w,ufvrxubfv$ w,ujvlw}sfv$ w,urmfbrpvwu`jpw$w,uwg$w,uwgufsruw$w,uxmfv=w,vbfp`ujrw}sfv$w,vbujsww,vfbhurxs w,vfbhurxssfuojvvjrp w,vfbmrblv w,vfbsfuojvvjrpw,vfbsrmjbjfvw,vfbxvfuw,vfbxvfuhurxsw,vfbxvfusfuojvvjrpw,vw`wxvw}sfv$v$w,w`vlv$w,wbg$w,wfosm`wfw,wfvwbm`vv$w,wfvwsm`pvw,wfvww}sfv$w,wu|w}sfv$w,xoms`wwfupw,|ufg w,|ufgv}vwfow,|ufgxvfuxv}v,v}vwfo$xv}vrmdw`amfv$xv}vtxfujfv$xv}vw`amfv$~~,t,josmfofpwvX$~~,t,rusi`pv$`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd.Wf\XdY`^gYbgZfX`aV`V`]X\\b_^b]da0$.XaYbaa\\`WdfZZba_Wfgg`]X_Yg[d^`b0.ZX^Zb]_W`^W_ZZb^aV`dZWabbd[YYf\`0.[Vfg[`VWg^X^ZX`Vaa\^`\Y_`V`d`dY^0.^Z_g`W\bg]VZZXbZ^Wd[]WZV_YX^X`[d0.^f_X^VVW\gWaZ^^d^fd\V_\`^YafgbXX0.d]Z^bgYgbd^dZ`YXaf\aX``Wb[gWXWfX0s`bl`hfdj`hu`os`bl`hfdj`hu`ow}sfvs`bl`hfrakfbww,dj`hu`ow}sfvw,dj`hu`o W@ @w,brppfbwruw}sfv w,dj`hu`ow,dj`hu`ow}sfvw,ofwujbw}sfv w,rakfbw w,rakfbww,rakfbww,rakfbww,s`bl`hfw,s`bl`hfw,s`bl`hfU2@usys_system-@888,,,,,,,* @1QH{@I(nS@t_trxtypes@777+++++++) @G{@U2@t_testtypes@888,,,,,,,* @f)E{@U2@t_tcf@222&&&&&&&$ @, 1@E(nS@t_tasks((((((((((& C{@|\B(nS@t_stereotypes@:::......., @|)B{@e$@t_statustypes1@:::......., @wB{@U2@t_scenariotypes@<<<0000000. @dQ@'7s@t_rtf9@222&&&&&&&$ @_>{@U2@t_roleconstraint:@===1111111/ @[!={@U2@t_risktypes{@888,,,,,,,* @X8Xt*M@U2@t_resources@888,,,,,,,* @OFE@U2@t_propertytypes@<<<0000000. @J]@.N@U2@t_projectroles@;;;///////- @Em;{@U2@t_problemtypes@;;;///////- @A6:{@U2@t_primitives"@999-------+ @?2@2@t_paletteitem.........., =2@2@t_palette**********( 4hn@N(nS@t_package@666*******( @06*,@U2@t_operationtag//////////- ,E8{@U2@t_operationpres7@<<<0000000. @(x7{@U2@t_operationposts8@===1111111/ @"6{@/I(nS@t_operationparams@>>>22222220 @"Q]Eg/Dc!fC`\BAeAguD<@ '-{ @q_packages@@C77+++++++) @ <@ <@q_objecttests@@@F::......., @~<@ɫs 1@q_object@@A55)))))))' @8<@[S<@q_method@@A55)))))))' @ާ<@<@q_ecf@@>22&&&&&&&$ @d<@d<@q_datatypes[@@ D88,,,,,,,* @ <@$<@q_connections3@ @G;;///////- @ +<@<@q_connections2@ @ G;;///////- @ <@3<@q_attribute@ @@ D88,,,,,,,* @mu@a2@MSysModules2----------+ mu@mu@MSysModules,,,,,,,,,,* 1@a2@MSysAccessObjects22222222220   n@s@AdminPS2&&&&&&&&&$  lu@lu@UserDefined,,,,,,,,,,*  |@wIOk@AccessLayout*@ @ NE99-------+ @ Dmu@ Dmu@SysRel''''''''''%  Dmu@ Dmu@Scripts((((((((((&  Dmu@ Dmu@Reports((((((((((&  Dmu@ Dmu@Modules((((((((((& Qa1@Qa1@DataAccessPages0000000000. lu@lu@MSysRelationships22222222220 lu@a2@MSysQueries,,,,,,,,,,* lu@a2@MSysACEs))))))))))' lu@lu@MSysObjects,,,,,,,,,,* lu@[X1@MSysDb@Q333'''''''% @lu@lu@Relationships.........., lu@lu@Databases**********( lu@lu@Tables''''''''''% VC-N--  DataID AOIndex @ I1T}S@I1T}S@UserDefined***********  I1T}S@I1T}S@SummaryInfo***********  I1T}S@I1T}S@AccessLayout+++++++++++ I1T}S@I1T}S@SysRel%%%%%%%%%%% I1T}S@I1T}S@Scripts&&&&&&&&&&& I1T}S@I1T}S@Reports&&&&&&&&&&& I1T}S@I1T}S@Modules&&&&&&&&&&& I1T}S@I1T}S@Forms$$$$$$$$$$$ I1T}S@I1T}S@DataAccessPages........... I1T}S@I1T}S@MSysRelationships22222222220 I1T}S@I1T}S@MSysQueries,,,,,,,,,,* I1T}S@I1T}S@MSysACEs))))))))))' I1T}S@I1T}S@MSysObjects,,,,,,,,,,* I1T}S@I1T}S@MSysDb''''''''''% I1T}S@I1T}S@Relationships.........., I1T}S@I1T}S@Databases**********( I1T}S@I1T}S@Tables''''''''''% a{q@@ @  d`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bfvov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd $*0Ii/=j0=j0 Forms =j0=j0ReportsRoot Entryl0PropDataࡱ>   *x0 $*0 @ @ =j0l0Blob CustomGroups =j0=j0Databases =j0l00 =j0l0Cmdbars=j0=j0DataAccessPages =j0=j0Scripts=j0=j0VBA  Forms Modules  =j0=j0Databases =j0=j00 ijMSysDb  $*0PROJECT/_VBA_PROJECTVBAp@k0kl0PROJECTwm   DirDataAcessVBADataustomGroups ij0ij0VBAProject87k0kl0AcessVBADataC ij0ij0VBAProject87k087k0DirData $*0ر0* pHddb2@= d  = J<  DAO>DAO *\G{00025E01-:0C  0046}#5.0#0#C:\Program Files\Common Microsoft Shared\w350`.DLL# 3.51 Object LibrXaryH DPB="BAB80CB3E8B4E8B4E8" GC="9795219623AE01AF01AFFE" [Host Extender Info] &H00000001={3832D640-CF90-11CF-8E43-00A0C911005A};VBE;&H00000000 [Workspace] 0 =j0=j0DaID="{B037F666-3984-44A7-B246-B64B4733A8F2}" Name="db2" HelpContextID="0" VersionCompatible32="393222000" CMG="DDDF6B48952199219921992199"=j0Reports=j0=j0ijMSysDbPropData Forms =j0Root Entryl0 '()*+,-./012345   !"#$%& $*020430-0000-0000-C000-000000000046}#2.0#0#C:\WINNT\System32\Stdole2.tlb#OLE AutomationZ*\G{0002E157-0000-0000-C000-0'046}#5.0#0#C:\Program Files\Common Files\Microsoft Shared\DAO\DAO350.DLL#Microsoft DAO 3.51 Object Library*\G{000&iles\Microsoft Office\Office10\msacc.olb#Microsoft Access 10.0 Object Library*\G{00025E01-0000-0000-C000-000000000%ROS~1\VBA\VBA6\VBE6.DLL#Visual Basic For Applications*\G{4AFFC9A0-5F99-101B-AF4E-00AA003F0F07}#9.0#0#C:\Program F$lity +E  GC="9795219623AE01AF01AFFE" [Hoam *\G{000204EF-0000-0000-C000-000000000046}#4.0#9#C:\PROGRA~1\COMMON~1\MIC#i" !Us@tdole>fstdole^f\^X043[W-^2^WINNT\System32\S12.tlb#OLE Automation/VBIDE> VBIDECCE157C5.3PVBA \6E6EX T.OLBHRVisual Basic for A pplic1s Extensibdir    $AccessVBAWin16~Win32MacVBA6#db2DAOstdole`VBIDEAH   Basic for Applic,x+*ations Extensibility 5.3 = )00000000046}#5.3#0#C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB#Microsoft Visual Basic for Applic(s @ @ @ @ @       !"#$%&'()*+,       E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n VCEN __A__DataID @ I1T}S@I1T}S@UserDefined***********  I1T}S@I1T}S@SummaryInfo***********  I1T}S@I1T}S@AccessLayout+++++++++++ I1T}S@I1T}S@SysRel%%%%%%%%%%% I1T}S@I1T}S@Scripts&&&&&&&&&&& I1T}S@I1T}S@Reports&&&&&&&&&&& I1T}S@I1T}S@Modules&&&&&&&&&&& I1T}S@I1T}S@Forms$$$$$$$$$$$ I1T}S@I1T}S@DataAccessPages........... I1T}S@I1T}S@MSysRelationships22222222220 I1T}S@I1T}S@MSysQueries,,,,,,,,,,* I1T}S@I1T}S@MSysACEs))))))))))' I1T}S@I1T}S@MSysObjects,,,,,,,,,,* I1T}S@I1T}S@MSysDb''''''''''% I1T}S@I1T}S@Relationships.........., I1T}S@I1T}S@Databases**********( I1T}S@I1T}S@Tables''''''''''% {VCe2N            FlagsFormModuleNameReplicationVersionTypeTypeInfoVersion&T&Index1ufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd{qg @ @      @ >           !222222222 2 !2 "2 #2 $2 %2&2'2(2)292 LVAL "i_VBA_PROJECTa^ *\G{000204EF-0000-0000-C000-000000000046}#3.0#9#C:\Program Files\Common Files\Microsoft Shared\VBA\vba332.dll#Visual Basic For Applications*\G{4AFFC9A0-5F99-101B-AF4E-00AA003F0F07}#8.0#0#C:\Program Files\Microsoft Office\Office\MSACC8.OLB#Microsoft Access 8.0 Object Library*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#C:\Program Files\Common Files\Microsoft Shared\DAO\DAO350.DLL#Microsoft DAO 3.51 Object Library LZ9 Hx(jKVKo7AccessAnd As.Debug=dim@DoDelseGendHendifRfSFalseUForZFunction`IfdInputkintegeru lineinputyLongzloopNewNextNLVAL #otOutputSetsubThenToWendWhileWriteVBAWin16~Win32MacDAOdb2Module1b _EvaluatecopyDB~db\dbnewrs_ Recordsetnei`sql"rsOldBrsNewcnt+ CurrentDbS OpenDatabase` OpenRecordset|BOFyEOF tablename` ExecuteYMoveNextL!AddNewaFields7Count0vUpdateStrerrStopMsgBoxRmod_housekeepingJlistqry4 _B_var_set TableDefs%iItemz _B_var_forjL QueryDefs& renametableU]table _B_var_SubqdfQueryDef Parameters`sting0cZ replacetablee_B_var_replacetableLnewtable%_B_var_FunctionOrepExactsOldsNewt _B_var_ifPprevcharnextchars _B_var_Midplim _B_var_LeftQ testexactFROM~ PackageINNERe replaceExactB_B_var_replaceExact |DiagramObjects_B_var_DiagramObjects|_B_var_Package sFinda _B_var_WhileIf fixQueriesX9 fixtables#NewName#RefreshCollect queryname renamequery)query%newqueryfixCode[ropenfile_B_var_openfiledi\ _B_var_disfile8a _B_var_sfile%%dm\ _B_var_dm _B_var_OpenlsourceGg^ _B_var_Outputs _B_var_NameXfixFilesd _B_var_As5 _B_var_Closenewdir\ olddirY;ValueK _B_var_Str _B_str_ErrorR _B_var_olddir _B_var_Write  MoveFirstNqs^ _B_var_qsfiscodeט_B_var_fiscodeڌChrK~ _B_str_Chrm# _B_var_Chr\;ch\ _B_var_cht IsChildOfK3 PackageID*LVALID] dbOpenTableBvret _B_var_ret&Index Object_ID08ObjectPackage_ID Package_IDst curPackageParentID~ _B_var_do_B_var_Package_ID Parent_IDfE modReportsdN0 dir0* pHddb2@= d  LZ9 J<  DAO>DAO *\G{00025E01-:0C  0046}#4.0#0#C:\Program Files\Common Microsoft Shared\w350`.DLL# 3.51 Object LibrXaryHD  VCqNBB          ( PropertyID ElementIDPropertyVALUENOTESea_guid BCBD  ElementKey PrimaryKeyBB"!MSysDb2#@ov}vda%          IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n .m>yJ7$ Yt=|aC t;^,x t_objectObject_1  t_connector  t_object      t_objectt_connector0@(+  t_connectorObject_1.@(+  t_connector.Connector_ID0 g DestIDt_object.Object_ID0 o DestName t_object.Name- o DestTypet_object.Object_Type4 o t_connector.Connector_Type2 g SourceTypeObject_1.Object_Type6 o SourceName Object_1.Name/ o SourceIDObject_1.Object_ID2 o t_objectObject_1  t_connector  t_object      t_objectt_connector0@(+  t_connectorObject_1.@(+  t_connector.Connector_ID0 g DestIDObject_1.Object_ID0 o DestName Object_1.Name- o DestTypeObject_1.Object_Type4 o t_connector.Connector_Type2 g SourceTypet_object.Object_Type6 o SourceName t_object.Name/ o SourceIDt_object.Object_ID2 o t_objectObject_1  t_connector  t_object      t_attribute.Name( ' t_attribute.Object_ID- ' t_objectt_attribute*@(+  t_attribute.Type( g t_attribute.Scope) g t_attribute.Name( g t_attribute.Object_ID- g t_attribute  t_object     LVAL%xJK_/yO(uK&wMe7 ' ' 't_object.Object_ID = t_connector.End_Object_IDt_objecttypes.Object_Type = t_object.Object_Type(((t_connector.Connector_Type)="Realisation"))t_package.Package_ID = t_object.Package_IDt_object.Object_ID = t_connector.Start_Object_IDt_objecttypes.Object_Type = t_object.Object_Typet_package.Package_ID = t_object.Package_IDObject_1.Object_Type = t_objecttypes.Object_Typet_package.Package_ID = Object_1.Package_IDt_object.Package_ID = t_package.Parent_IDt_objecttests.Object_ID = t_object.Object_ID(((t_objecttypes.DesignObject)=True))t_package.Package_ID = t_object.Package_IDt_objecttypes.Object_Type = t_object.Object_Typet_package.Package_ID = t_object.Package_IDt_object.Classifier = t_object_1.Object_IDt_object.Object_ID = t_diagramobjects.Object_IDt_object.Object_ID = t_method.Object_IDt_diagram.Diagram_ID = t_object.Diagram_ID(((t_connector.Connector_Type)="Realisation"))t_object.Object_ID = t_connector.Start_Object_IDObject_1.Package_ID = t_package.Package_IDt_connector.End_Object_ID = Object_1.Object_IDt_objecttypes.Object_Type = t_object.Object_Typeselect Datatype as Name from t_primitivesselect Name from t_object where Object_Type='Class' (((t_connector.DiagramID)=0 Or (t_connector.DiagramID)=[t_diagramobjects].[Diagram_ID]))t_connector.End_Object_ID = DiagramObjects_1.Object_IDt_diagramobjects.Diagram_ID = DiagramObjects_1.Diagram_IDt_diagramobjects.Object_ID = t_connector.Start_Object_IDt_object.Object_ID = t_connector.Start_Object_IDt_connector.End_Object_ID = Object_1.Object_IDt_object.Object_ID = t_connector.Start_Object_IDt_connector.End_Object_ID = Object_1.Object_IDt_object.Object_ID = t_connector.Start_Object_IDt_connector.End_Object_ID = Object_1.Object_IDt_object.Object_ID = t_attribute.Object_ID1[uA vcP-v<taN;(n>vcP=r t_package.Package_ID, gt_package t_objectObject_1 t_connector t_object t_objecttypes  G G  ExValue[Weight]*[Value]/ o t_ecf.Notes# g t_ecf.Value# g t_ecf.Weight$ gt_ecf.Description) g t_ecf.ECFID# gt_ecf   X7YZ_____2)@ (" 7X7YZ_____15@ (" 7 G  G   t_connector.SeqNo) 'X@ ( 't_connectorDiagramObjects_16@ (3' t_diagramobjectsDiagramObjects_19@(8, t_diagramobjectst_connector8@(3' t_diagramobjects.Diagram_ID3 g t_connector.*% gt_diagramobjectsDiagramObjects_1,, t_connector t_diagramobjects    t_objectt_connector0@(+  t_connectorObject_1.@(+   t_connector.Notes) g  DestIDt_object.Object_ID0 o DestName t_object.Name- o DestTypet_object.Object_Type4 o t_connector.Stereotype. g t_connector.Connector_Type2 g SourceTypeObject_1.Object_Type6 o SourceName Object_1.Name/ o SourceIDObject_1.Object_ID2 o ConNamet_connector.Name/ o*V\{KjOf6hM*]#}@ @t_object.Object_ID* gt_diagramobjects.ObjectStyle4 gt_diagramobjects.Diagram_ID3 gt_diagramobjects.RectBottom3 gt_diagramobjects.RectRight2 gt_diagramobjects.RectLeft1 gt_diagramobjects.RectTop0 gt_objectt_object_1 t_diagramobjects t_object t_package     t_method.Name% ' t_method.Object_ID* 't_objectt_method'@(( t_diagramt_object*@()  t_method.Type% gt_method.Scope& g t_method.Name% gt_method.Object_ID* gt_diagram.Diagram_ID, gt_method t_object t_diagram    t_package.Package_ID, '.@( 't_objectt_connector0@(+ Object_1t_package*@() t_connectorObject_1.@(+ t_objecttypest_object0@ (-!  t_objecttypes.DesignObject2 g ImplementorTypet_object.Object_Type; oImplementorName t_object.Name4 oImplementedByIDt_object.Object_ID9 oConnectort_connector.Connector_Type; oObjectTypeObject_1.Object_Type6 oObjectName Object_1.Name/ oObjectIDt_connector.End_Object_ID9 oPackaget_package.Name- o, @ @ @ @ @ @ @ ' ' ' ' ' ' ' '  '  ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '! '" '# '$ '% '& '' '( ' ') '+ ', '- ) ) ) ) ) ) ) )  )  ) ) ) '*) ))))))))) )) )))))))) )!)")#)$)%)&))')))*)+),)-).)/)0******* * ** )(-----+ @+. @ @ @ @ @ @ @  )  ) ) ) '*) ))))))))) )) )))))))) )!)")#)$)%)&))')))*)+),)-).)/)0******* * ** * * * *  *)(*********** * ***** *!*"*#*$*%*&*'*(*)- - - - - ----- - - - - -------*'(tFZ(i6d4oAZ+sB   /t_object.RunState) g.t_object.ea_guid( g-t_object.Classifier+ g,t_object.GenLinks) g+t_object.GenOption* g*t_object.Scope& g)t_object.Phase& g(t_object.Header2( g't_object.Header1( g&t_object.GenFile( g%t_object.GenType( g$t_object.PDATA5' g#t_object.PDATA4' g"t_object.PDATA3' g!t_object.PDATA2' g t_object.PDATA1' gt_object.Bordercolor, gt_object.Fontcolor* gt_object.BorderWidth, gt_object.Tagged' gt_object.Abstract) gt_diagramobjects.Sequence1 gt_object.Status' gPackageNamet_package.Name1 ot_object.ModifiedDate- gt_object.CreatedDate, gt_object.Backcolor* gt_object.BorderStyle, gt_object.Style& gt_object.Effort' gt_object.Complexity+ gt_object.NType& gt_object.Stereotype+ gt_object.Package_ID+ g t_object.Note% g t_object.Version( g t_object.Author' g t_object.Alias& g t_object.Name% gt_object.Object_Type, g,0 @ @ @ @ @ @ @* *  *)(*********** * ***** *!*"*#*$*%*&*'*(*)- - - - - ----- - - - - ---------- -!-"-#-$-%-&-'-(- )-!*-"+-#,-$--%.-&/-'0/1/2/3/4/5/6/7/// / */ / ///////////// ////// /!/-m?u> uU: r9}jJ/`+Q t_objecttests.CheckBy- g t_objecttests.RunBy+ g t_objecttests.Results- g t_objecttests.DateRun- g t_objecttests.Status, g t_objecttests.AcceptanceCriteria8 gt_objecttests.InputData/ gt_objecttests.Notes+ gt_objecttests.TestType. gt_objecttests.TestClass/ gt_objecttests.Test* gt_objecttests.Object_ID/ gt_object.Package_ID+ gt_object t_objecttests  G G  %@( 't_packaget_object*@() t_objecttypest_object0@(-! t_objecttypes.DesignObject2 gPackaget_package.Name- oTypet_object.Object_Type0 o t_object.Name% gt_object.Object_ID* gt_object t_objecttypes t_package  G G  t_packaget_object*@() t_objectt_object_1*@(* t_objectt_diagramobjects/@(0$ 7t_object.Multiplicity- g6t_object.PackageFlags- g5t_object.StateFlags+ g4t_object.IsActive) g3t_object.IsSpec' g2t_object.IsLeaf' g1t_object.IsRoot' g0ClassNamet_object_1.Name0 o.3 @ @ @ @ @ @ @- -!-"-#-$-%-&-'-(- )-!*-"+-#,-$--%.-&/-'0/1/2/3/4/5/6/7/// / */ / ///////////// ////// /!/"/#/$/%/&/' /( /) /* /+ /,1/11111111 1 1 1 1 111111111111111111 1  1! 1" 1# 1$1%1&1'1(1)1-oL,h6U!~b.l?R%g4jt_object.CreatedDate, gt_object.Bordercolor, gt_object.Fontcolor* gt_object.BorderWidth, gt_object.BorderStyle, gt_object.Backcolor* gt_object.Style& gt_object.Effort' g t_object.Complexity+ g t_object.NType& g t_object.Stereotype+ g t_object.Package_ID+ g t_object.Note% gt_object.Version( gt_object.Author' gt_object.Alias& g t_object.Name% gt_object.Diagram_ID+ gt_object.Object_Type, gt_object.Object_ID* gPackaget_package.Name- ot_package t_object  G G  (((t_objecttypes.ImageID)>0))5 'Object_1t_objecttypes0@(-! t_packageObject_1*@() t_objectt_packaget_object.Name = t_package.NameG t_objectt_package)@() Object_1.Object_Type, gObject_1.Stereotype+ gt_package.Package_ID, gt_object.Object_ID* gt_objecttypes.ImageID- g Object_1.Name% gt_objecttypes t_objectObject_1 t_package t_object   t_objecttestst_object,@(-!  XTGF^ Fp)D4C}5BUA0\zzzt{@a2@t_constants(@%888,,,,,,,* @v(>{@4s@t_connectortypes(@%===1111111/ @r6*,@a2@t_connectortag//////////- m{@a2@t_connectorconstraint@BBB66666664 @ VC%{@a2@t_complexitytypesL@>>>22222220 @S{@a2@t_clients@666*******( @Nr 1@a2@t_category++++++++++) J{@a2@t_cardinality@ :::......., @ $6*,@a2@t_attributetag//////////- >{@a2@t_attributeconstraints@CCC77777775 @9 {@kYs@t_attribute888,,,,,,,* @)<@U<@rptUseCasesbyActor@@ @K??33333331 @ 'Z]<@Z]<@rptUseCaseNotes"@@H<<0000000. @&<@<@rptqryObjectNotes@@J>>22222220 @%l|-@l|-@qdf_simpleobjectE@===1111111/ @#^|-@^|-@qdf_operationE@:::......., @"^|-@t 1@qdf_objectE@777+++++++) @!l|-@l|-@qdf_diagramlinkE@<<<0000000. @ l|-@l|-@qdf_attributeE@:::......., @<@@q_ucmetrics@@D88,,,,,,,* @@l<@c<@q_tcf@@>22&&&&&&&$ @ֱ<@ֱ<@q_sumecf@@A55)))))))' @5<@s<@q_resource@@@C77+++++++) @=<@&{<@q_realizes1.@@D88,,,,,,,* @<@(pz@q_pkgobject@@@D88,,,,,,,* @06 @ @ @ @ @ @ @/$/%/&/' /( /) /* /+ /,1/11111111 1 1 1 1 111111111111111111 1  1! 1" 1# 1$1%1&1'1(1)1*1+1,4444444444  4 !4 "4 #4 $4%4&4'4414444444444444 4!4"4#4$4%44&4(4)4*4+4,4-4.5554'%/n@Z'`1vcP=*Rh/zgTA. @ @ t_object.Name% gt_connector t_object t_objecttypes t_package  G G  .@"( 't_packaget_object*@!() t_objectt_connector0@ (+ t_objecttypest_object0@(-! t_objecttypes.DesignObject2 gt_connector.Connector_Type2 gRealizedByIDt_object.Object_ID6 oObjectIDt_connector.End_Object_ID9 oPackaget_package.Name- oTypet_object.Object_Type0 o t_object.Name% gt_connector t_object t_objecttypes t_package  G G  t_packaget_object*@() 't_object.Phase& g&t_object.Header2( g%t_object.Header1( g$t_object.GenFile( g#t_object.GenType( g"t_object.Cardinality, g!t_object.Persistence, g t_object.Visibility+ gt_object.Concurrency, gt_object.PDATA5' gt_object.PDATA4' gt_object.PDATA3' gt_object.PDATA2' gt_object.PDATA1' gt_object.Tagged' gt_object.Abstract) gt_object.Status' gt_object.ModifiedDate- g0Sp>Y U!t=~kS Y/kt_ocf  G G  ExValue[Weight]*[Value]/ o t_tcf.Notes# g t_tcf.Value# g t_tcf.Weight$ gt_tcf.Description) g t_tcf.TCFID# gt_tcf   TCFSum([Weight]*[Value])0 ot_tcf   ECFSum([Weight]*[Value])0 ot_ecf   t_objectresourcet_object/@70$  t_objectresource.DateEnd0 g t_objectresource.DateStart2 g t_objectresource.PercentComplete8 gt_objectresource.Notes. gt_objectresource.Time- gt_objectresource.Role- gt_objectresource.Resource1 gt_object.Object_Type, g t_object.Name% gt_objectresource.Object_ID2 gt_object.Package_ID+ gt_object t_objectresource   .@7 't_packaget_object*@7) t_objectt_connector.@$(+ t_objecttypest_object0@#(-! t_objecttypes.DesignObject2 gt_connector.Connector_Type2 gRealizedByIDt_object.Object_ID6 oObjectIDt_connector.Start_Object_ID; oPackaget_package.Name- oTypet_object.Object_Type0 o38 @ @ @ @ @ @ @1,4444444444  4 !4 "4 #4 $4%4&4'4414444444444444 4!4"4#4$4%44&4(4)4*4+4,4-4.5555555555 4'5 5 5 55555555 5 5 555 555555 5!55"5$5%5&5'5(5)5*5#5+5-5.5/@@@@@@@@5,LVAL"yE~Zc?`"]3xP @ @ @1,44(((t_diagramobjects.Object_ID) Is Null))t_package.Package_ID = t_object.Package_IDt_object.Object_ID = t_diagramobjects.Object_ID(((q_implements.Package_ID) Is Null) AND ((Object_1.Abstract) Is Null Or (Object_1.Abstract)="0"))t_package.Package_ID = Object_1.Package_IDObject_1.Object_ID = q_implements.ObjectIDt_implement.Type = Object_1.Object_Typet_objecttypes.Object_Type = Object_1.Object_Type(((Object_1.Object_Type)="Actor") AND ((t_object.Object_Type)="Usecase") AND ((Object_1.Object_ID)=[Start_Object_ID]) AND ((t_object.Object_ID)=[End_Object_ID]))(((t_object.Object_Type)="Usecase"))t_package.Package_ID = t_diagram.Package_IDt_package.Package_ID = t_object.Package_IDt_object.Diagram_ID = t_diagram.Diagram_ID(((t_object.Note)<>"") AND ((t_object.Object_Type)="UseCAse"))t_package.Package_ID = t_diagram.Package_IDt_object.Diagram_ID = t_diagram.Diagram_IDt_package.Package_ID = t_object.Package_IDSelect * from q_connections2 where SourceID=[ID]Select * from q_connections where SourceID=[ID] (((t_operation.Object_ID)=[Object]))(((t_object.Object_ID)=[Object]))t_package.Package_ID = t_object.Package_IDt_object.Classifier = t_object_1.Object_IDt_object.Object_ID = t_diagramobjects.Object_ID(((t_diagramlinks.DiagramID)=[Dgm_ID]) AND ((t_diagramlinks.ConnectorID)=[Con_ID]))(((t_attribute.Object_ID)=[Object]))t_object.Object_Type = t_objecttypes.Object_Type(((t_object.Object_Type)="UseCase" Or (t_object.Object_Type)="Actor"))t_package.Package_ID = t_object.Package_IDt_ocf.ObjectType = t_object.Object_TypeVal([t_object].[Complexity])*Val([ComplexityWeight])t_objectresource.Object_ID = t_object.Object_ID(((t_connector.Connector_Type)="Realisation"))t_package.Package_ID = t_object.Package_ID6P @ @ @ @ @ @ @55555 4'5 5 5 55555555 5 5 555 555555 5!55"5$5%5&5'5(5)5*5#5+5-5.5/@@@@@@@@@@ @ 5,@ @ @@@@@@@@ @ @ @ @ @  @  @  @ @!@!@ !@!!@"!@#!@$!@"@%"@'"@("@)"@*"@+"@,"@-"@."@/"@0"@1"@2"H" H" H" H" H" H"H"H"H"H "@&VCN::   at  te2  tO2  ct2       2  2  2                  $  (      2        2   Object_IDNameScope Stereotype ContainmentIsStatic IsCollection IsOrderedAllowDuplicates LowerBound UpperBound ContainerNotesDerivedIDPos GenOptionLength PrecisionScaleConstStyle ClassifierDefaultTypeea_guidStyleEx :; :< := Name Object_ID PrimaryKey ::::::: :rimaryKey ::::::: :t_ob$ID O$  G$ $ # dt_operation.Name) /#$U}S@U}S@qdf_relatesto,,,,,,,,,,, #U}S@U}S@qdf_operation,,,,,,,,,,, "UUU}S@U}S@qdf_object))))))))))) !UUU}S@UUU}S@qdf_diagramlink...........  UUU}S@UUU}S@qdf_attribute,,,,,,,,,,, UUU}S@UUU}S@q_visibleobject........... T}S@T}S@q_ucmetrics*********** T}S@T}S@q_tcf$$$$$$$$$$$ T}S@T}S@FlagMSysQueriesFlag00,!! ExpressionMSysQueriesExpression<<2'' Name2MSysQueriesName222-"" Name1MSysQueriesName122-""AttributeMSysQueriesAttribute::1&& {qg]SI?U`"~R!n2 ~CQ! 'Object ' ' &t_packaget_diagram+@7* &t_objectt_diagram*@7) &t_packaget_object* @@9 `ddufvv           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2H'"0I"1I"2I"3I"4I"5I"6I"7I"I"I "I "I "@&#I #I#I#I#I# I# I# I#I $I$I$I$I$I$I$I%I%I%I%I %I!%I&I"&I$&I%&I&&I'&I(&I)&I*&I+&I,&I-&I.&I/&I0&I#'I1'I3'A'A'A'I2(A(A(A(A(A(A (A (A (A (A (A(A(A(A(A(A(A)A9<9VCN??      '     '  Object_ID ConstraintAttNameTypeNotesID' ' ?  PrimaryKey??S{qg3jAX9&w> t[H* ~kX?&v[8k1 "t_object.Object_ID* g"t_diagramobjects.ObjectStyle4 g"t_diagramobjects.Diagram_ID3 g"t_diagramobjects.RectBottom3 g"t_diagramobjects.RectRight2 g"t_diagramobjects.RectLeft1 g"t_diagramobjects.RectTop0 g"t_objectt_object_1 "t_diagramobjects "t_object "t_package "[Object] O" " !S@ 7 '!t_diagramlinks ! G!Con_ID O!Dgm_ID O! !  t_attribute.Name( ' t_attribute.Scope) ' t_attribute.Pos' ' $@7 ' t_attribute   G Object O    (((t_objecttypes.ImageID)>0))5 't_objectt_objecttypes0@7-! t_objecttypes.ImageID- gt_objecttypes.DesignObject2 gt_objecttypes.Description1 g t_object.*" gt_objecttypes t_object   F@7 't_packaget_object*@7) t_ocft_object'@7% t_object.Phase& gt_package.Package_ID, gt_package.Name& gComplexity4@7" o t_object.Name% gt_object.Object_Type, gt_object t_package 1vcG,e2l< {X<~R!gK+I| *ImplementedByID"") o*Connector""# o*ObjectTypeObject_1.Object_Type6 o*ObjectName Object_1.Name/ o*ObjectIDObject_1.Object_ID2 o*Packaget_package.Name- o*t_package.Package_ID, g*q_implements *t_objectObject_1 *t_objecttypes *t_package *t_implement * G* G* * )@7 ')t_object.Object_ID* g)Object_1.Object_ID* g) t_object.Note% g) t_object.Name% g)t_object.Object_Type, g)Object_1.Object_Type, g) Object_1.Name% g)Connector )t_objectObject_1 )t_object ) ) ($@7 '(t_packaget_diagram+@7* (t_packaget_object*@7) (t_objectt_diagram*@7) (TagIIf([Tagged]=0,'No','Yes')5 o(t_object.Complexity+ g( t_object.Note% g( t_object.Name% g(t_object.Object_Type, g(t_diagram.Diagram_Type. g(t_diagram Namet_diagram.Name4 o(t_package Namet_package.Name4 o(t_diagram (t_object (t_package ( ( '>@7 '' t_object.Note% g' t_object.Name% g{qg$           !222222222 2 !2 "2 #2 $2 %2&2'2(2)292>2$VCNFF      P( AuthorNameRolesNotesP(FG  PrimaryKeya{qE           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2'(tFZ(i6d4oAZ+sB   "/t_object.RunState) g".t_object.ea_guid( g"-t_object.Classifier+ g",t_object.GenLinks) g"+t_object.GenOption* g"*t_object.Scope& g")t_object.Phase& g"(t_object.Header2( g"'t_object.Header1( g"&t_object.GenFile( g"%t_object.GenType( g"$t_object.PDATA5' g"#t_object.PDATA4' g""t_object.PDATA3' g"!t_object.PDATA2' g" t_object.PDATA1' g"t_object.Bordercolor, g"t_object.Fontcolor* g"t_object.BorderWidth, g"t_object.Tagged' g"t_object.Abstract) g"t_diagramobjects.Sequence1 g"t_object.Status' g"PackageNamet_package.Name1 o"t_object.ModifiedDate- g"t_object.CreatedDate, g"t_object.Backcolor* g"t_object.BorderStyle, g"t_object.Style& g"t_object.Effort' g"t_object.Complexity+ g"t_object.NType& g"t_object.Stereotype+ g"t_object.Package_ID+ g" t_object.Note% g" t_object.Version( g" t_object.Author' g" t_object.Alias& g" t_object.Name% g"t_object.Object_Type, g4m?u> lN/zgR?n2 ~CQ!'Object ' ' &t_packaget_diagram+@7* &t_objectt_diagram*@7) &t_packaget_object*@7) &t_object.Complexity+ g& t_object.Note% g& t_object.Name% g&t_object.Object_Type, g&t_diagram.Diagram_Type. g&t_diagram Namet_diagram.Name4 o&t_package Namet_package.Name4 o&t_diagram &t_object &t_package & & %(((t_object.Object_ID)=[ID]))5 '% t_object.*" g%t_object %ID O% % $X7YZ_____20@7" 7$X7YZ_____10@7" 7$ G$ID O$  G$ $ # dt_operation.Name) /# t_operation.Scope) '# dt_operation.Pos( /#$@7 '#t_operation # G#Object O# # "!@ 7 '"t_packaget_object*@ 7) "t_objectt_object_1*@ 7* "t_objectt_diagramobjects/@ 70$ "7t_object.Multiplicity- g"6t_object.PackageFlags- g"5t_object.StateFlags+ g"4t_Object.IsActive) g"3t_Object.IsSpec' g"2t_Object.IsLeaf' g"1t_object.IsRoot' g"0ClassNamet_object_1.Name0 oVCNKK 2 CardinalityKM  PrimaryKeya{q J@@ @ @@@ @@  @@@@ `dojpd`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXt,brppfbwjrpvYt,brppfbwrut,d`w`w}sfvt,fbgt,josmfofpwvt,ofwirdt,rakfbwt,rakfbwuf`mj~fvt,rakfbwwfvwv t,s`bl`hfv!t,slhrakfbw2t,uf`mj~fvW2t,uf`mj~fvX2t,ufvrxubf2t,vxofbg2t,vxowbg2t,wbg2t,xbofwujbv2t,zjvjamfrakfbw2tdg,`wwujaxwf2 tdg,dj`hu`omjpl2 tdg,rakfbw2 tdg,rsfu`wjrp2 tdg,ufm`wfvwr2 tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd1..*1..10..10..*0*J@LVLVLVWLWLWLWL      IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n VCNOO        CategoryIDNameTypeNOTESOR  PrimaryKeyOOS{qg8X @ @ @ @ @ @ @@ 5,@ @ @@@@@@@@ @ @ @ @ @  @  @  @ @!@!@ !@!!@"!@#!@$!@"@%"@'"@("@)"@*"@+"@,"@-"@."@/"@0"@1"@2"H" H" H" H" H" H"H"H"H"H "H "H "H "H "H"H"H"H"H"H"H"H"H"H" H"!H""H"#H"$H"%H"&H"'H"(H ")H!"*H""+H#",H$"-H%".H&"/H'"0I"1I"2I"3I"4I"5I"6I"7I"I"I "I "I "@&#I #I#I#I#I# I# I# I#I $I$I>X @ @ @ @ @ @ @ @ @ @ @ @ @$I$I$I$I%I%I%I%I %I!%I&I"&I$&I%&I&&I'&I(&I)&I*&I+&I,&I-&I.&I/&I0&I#'I1'I3'A'A'A'I2(A(A(A(A(A(A (A (A (A (A (A(A(A(A(A(A(A)A)A)A)A)A)A)A)A)A)A)A)A )A*A!*A#*A$*A%*A&*A'*A(*A)*A**A+*A,*A-*A.*A/*A0** * ****** *A"+ + + + ++++++++++++ N           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2VCZN TT  W(    W(2  2  W(2  2  W(2    W(Name OrganisationPhone1Phone2MobileFaxEmailRolesNotes(W(WTU  PrimaryKeya{q S           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2VC NWW 2  Complexity NumericWeightWWZWW[  NumericWeight PrimaryKey{qPQ @ @ @ @ @ @ @"H "H "H"H"H"H"H"H"H"H"H"H" H"!H""H"#H"$H"%H"&H"'H"(H ")H!"*H""+H#",H$"-H%".H&"/H'"0I"1I"2I"3I"4I"5I"6I"7I"I"I "I "I "@&#I #I#I#I#I# I# I# I#I $I$I$I$I$I$I$I%I%I%I%I %I!%I&I"&I$&I%&I&&I'&I(&I)&I*&I+&I,&I-&I.&I/&I0&I#'I1'I3'A'A'A'I2(A(A(A(A(A(A (A (A (A (A (A(A(A(A(A(A(A)A)A)A)AV@@ @ @@@ @@  @@@@`dojpd`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXt,brppfbwjrpvYt,brppfbwrut,d`w`w}sfvt,fbgt,josmfofpwvt,ofwirdt,rakfbwt,rakfbwuf`mj~fvt,rakfbwwfvwv t,s`bl`hfv!t,slhrakfbw2t,uf`mj~fvW2t,uf`mj~fvX2t,ufvrxubf2t,vxofbg2t,vxowbg2t,wbg2t,xbofwujbv2t,zjvjamfrakfbw2tdg,`wwujaxwf2 tdg,dj`hu`omjpl2 tdg,rakfbw2 tdg,rsfu`wjrp2 tdg,ufm`wfvwr2 tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfdV.Low V.High Medium LowHigh Extreme V @YYYYYY       IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n V f|wufofYijhiYmr{YofdjxoYzijhiYzmr{YVCR NQ5O]]      2    2  2  2  2  2  2 2 2  2     2    2  2    2     2    2  2  2  2 ! 2 !" 2"# #$  $% $%& (&' ,'( 0() 4)* 8*+ <+, @,- D-. H ./ 2 /0  01 2 12  23  3 4  4!5  5"6 6#7 L 7#8 ( 8$9  9%:  O:&; ;&< <&= =&> >&?  ?&@ ac @'A le A(B tc B)C  C C*D ie D+E trE,F F,G  G,H reH-I P I-J li J.K le K/L P L0M ti M1N si N2O en O3 ss P4 Is Connector_IDName DirectionNotesConnector_TypeSubType SourceCard SourceAccess SourceElementDestCard DestAccess DestElementSourceRoleTypeSourceRoleNoteSourceContainmentSourceIsAggregateSourceIsOrderedSourceQualifier DestRoleType DestRoleNoteDestContainmentDestIsAggregate DestIsOrdered DestQualifierStart_Object_ID End_Object_IDTop_Start_Label Top_Mid_Label Top_End_LabelBtm_Start_Label Btm_Mid_Label Btm_End_Label Start_EdgeEnd_EdgePtStartXPtStartYPtEndXPtEndYSeqNo HeadStyle LineStyle RouteStyleIsBold L {qg]SI?58vD"^9Et@t@C958PackageObjectModel1.01Proposed46Java1.0Public{06C9C958-C14A-41f4-89A9-6873CCED37A7}vvvpmmmmiiiiiiiiigg__^^^[[[9Et@t@C958PackageHouseExampleModel1.01Proposed46Java1.0Public{06C9C958-C14A-41f4-89A9-6873CCED37A7}|||vssssooooooooommeedddaaaPI%Oݿb9D,m@6))@ID aClassMeetingPlace1.01Proposed00Java1.0Public{CB9E84D4-9064-49d0-BF1E-EE53C05853EF}uuuollllhhhhhhggggf^^]]]ZZZNI%Ob9C,a3*@|j*@ Note1.0F@1Proposedidref1=4;1.0Public{9D7C072D-2F74-4348-B1D9-BA3CFA72FC6F}}}}wttttnnnnnneeeee]]\\PMMMMI%ݿb9B,sEn@׍n@ ClassPerson1.01Proposed00Java1.0Public{2F1D9CC6-F38F-4a34-B3C4-B92915108384}oooiffffbbbbbbaaaa`XXWWWTTTNI%Ob9A+c@sEn@atioClassBathroom1.01Proposed00Java1.0Public{244CC9E5-1F81-4164-9215-C048EC679543}qqqkhhhhddddddccccbZZYYYVVVNI%Ob9?,Nk@Nk@VaPackageRooms1.01Proposed43Java1.0Public{F9D8C6E3-4DAD-4aa2-AD47-D0ABA4E93E08}pppjggggcccccccccaaYYXXXUUUPI%Oݿb9>+z@X\@naliClassKitchen1.01Proposed00Java1.0Public{9CE44C59-37E4-4117-8C05-F87C4DC33529}pppjggggccccccbbbbaYYXXXUUUNI%Ob9=+otz@%W\@ClassRoom1.01Proposed00Java1.0Public{14DB5E54-CD7B-4c84-998C-44960049D7E0}mmmgdddd``````____^VVUUURRRNI%Ob9<,~z@4(rQ @ClassHouse1.0dummy1Proposed00Java1.0Public{436D81AD-A9B0-44d8-8AD1-86BB0808DA32}sssmjjjjffffffeeeed\\[VVSSSNI%Ob\ @ ____ _ _ _GGGGGGo{ #\ @  `hhufh`wjrpG`hhufh`wjrpG`hhufh`wjrpG`hhufh`wjrpG`hhufh`wjrp_`vvrbj`wjrpG`vvrbj`wjrp_`vvrbj`wjrp_`vvrbj`wjrp_dfsfpdfpb}Ghfpfu`mj~`wjrp_hfpfu`mj~`wjrp_hfpfu`mj~`wjrp_o{\ @ GGGGGG_______o{ \ @ <_<_<_=_=_A_D_GGGGGGGGGGPGo{\.VYV[X_WWY\X[ZZ]X^b\a[fW]ZXgfd][Y0_.W\WagZg`^gZ^ZZWg`gWgdY\VWZd[]`Wg0_.YgVf__Z_`]Z_Z_[^_`WaZVfYgVfWXY_Y0G._\WYf_dd^]V_Zf_f_Xd^Xg\b`_^Y[^[W0G._ddad_^[d_d[ZV^b`^gZZVV^[gXf^f[a0G._gVggW]^YVVgZ[gZaYWg_\YY`g]]VfZZ0_.`_WWXdWbdba\ZVZVaZ\\d[g[\V^_^aYY0_.`gd\\`a\YY]aZ_b[_g`_Vbg`gfa]]``]0G.bYdW^d_XY`[bZWWX__[^_X\`X[_a`fXZ0_.d]][aXbWb]`gZ`W_`Zd[]aY`b^W\\\Zb0G.f^XZ\_WdX`f]Zb_b^ZV^^^W`Xa^[[W\g0_.gW[`XaX[Vd`_ZXVY^gb_X[\Z[\WVa[f[0_.ggXfbdXVXXggZ]YZ_daZ^YW\`_^ddbW\0Go{\ @ ____ _ _ _GGGGGGo{\ @ <_=_>G>_>_>_A_B_HGLGMGNGOGVCN  (  L(  vd  L  v PropertyID ElementID BaseClassTagValueNotesPA  PrimaryKeyVCNnn     &2   ConnectorID ConstraintConstraintTypeNotes&'nond&np&$nq ObjectConstraintConstraintObjectID PrimaryKeynnE{qg]m           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2mmVCqNss          ( PropertyID ElementIDPropertyVALUENOTESea_guid stsu  ElementKey PrimaryKeyss{qg rS           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2rSVCNww  2  2Connector_Type DescriptionoeooeoTecwy  PrimaryKey.rB PrimaryKeya{qv|Z:&|fP:@@@ @@  @@@`dojpd`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXt,brppfbwjrpvYt,brppfbwrut,d`w`w}sfvt,fbgt,josmfofpwvt,ofwirdt,rakfbwt,rakfbwuf`mj~fvt,rakfbwwfvwv t,s`bl`hfv!t,slhrakfbw2t,uf`mj~fvW2t,uf`mj~fvX2t,ufvrxubf2t,vxofbg2t,vxowbg2t,wbg2t,xbofwujbv2t,zjvjamfrakfbw2tdg,`wwujaxwf2 tdg,dj`hu`omjpl2 tdg,rakfbw2 tdg,rsfu`wjrp2 tdg,ufm`wfvwr2 tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2InterruptFlowInterruptFlowObjectFlowObjectFlow PackagePackageConnectorComposite Connector ManifestManifest DelegateDelegate AssemblyAssembly DeploymentDeployment ControlFlowControlFlow UseCaseUseCaseStateFlowStateFlow SequenceSequence RealisationRealisation NoteLinkNoteLink NestingNestingInstantiationInstantiationGeneralizationGeneralizationERLinkERLink DependencyDependency CollaborationCollaborationAssociationAssociation AggregationAggregation v   @`hhufh`wjrpx`vvfoam}x`vvrbj`wjrpxbrmm`aru`wjrpxbrppfbwruxbrpwurmgmr{x dfmfh`wfxdfsfpdfpb}xdfsmr}ofpwxfumjplxhfpfu`mj~`wjrpxjpvw`pwj`wjrpxjpwfuuxswgmr{xo`pjgfvwxpfvwjphxprwfmjplxrakfbwgmr{xs`bl`hfxuf`mjv`wjrpx vftxfpbfx vw`wfgmr{x xvfb`vfx Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n VCN{{ 2   ConstantName ConstantValue{}  PrimaryKeya{q bzz@@ @ @@@ @@  @@@@ @`dojpd`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXt,brppfbwjrpvYt,brppfbwrut,d`w`w}sfvt,fbgt,josmfofpwvt,ofwirdt,rakfbwt,rakfbwuf`mj~fvt,rakfbwwfvwv t,s`bl`hfv!t,slhrakfbw2t,uf`mj~fvW2t,uf`mj~fvX2t,ufvrxubf2t,vxofbg2t,vxowbg2t,wbg2t,xbofwujbv2t,zjvjamfrakfbw2tdg,`wwujaxwf2 tdg,dj`hu`omjpl2 tdg,rakfbw2 tdg,rsfu`wjrp2 tdg,ufm`wfvwr2 tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfdTCF_TWF0.01 TCF_TC0.6 ProjectNameDOJ HoursPerUCP20 ECF_EWF-0.03 ECF_EC1.4 CompanyNameSparx Systems z  bros`p}p`of|fbg,fb|fbg,f{g|irxuvsfuxbs|surkfbwp`of|wbg,wb|wbg,w{g| IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n VCN   2  P( Constraint DescriptionNotesP(  PrimaryKeyS{qg!Gh)JFF84Eo+COBf}yA/OC3{@U2@t_objecttrx-@2888,,,,,,,* @r2{@.T@t_objecttests@O:::......., @)1{@RJ(nS@t_objectscenarios@1>>>22222220 @;1{@U2@t_objectrisks@0:::......., @/{@U2@t_objectrequires@/===1111111/ @Zb@U2@t_objectpropertiesi@/???33333331 @ /{@E(nS@t_objectproblemsS@.===1111111/ @;R.{@҈s@t_objectmetrics@.<<<0000000. @-{@g2@t_objectfiles@-:::......., @",{@U2@t_objectconstraint@-???33333331 @%{@޿s@t_objecti*555)))))))' @!#{@҈s@t_metrictypes@):::......., @ )"{@a2@t_mainttypesr@)999-------+ @AF(nS@AF(nS@t_listse@444(((((((& @$@mT@t_issuesV@M555)))))))' @5NU@c@t_implement2@%888,,,,,,,* @'2@'2@t_image((((((((((& 8 {@a2@t_glossary@&777+++++++) @1b@1b@t_genopt))))))))))' AF(nS@vF(nS@t_files@444(((((((& @}{@a2@t_efforttypes@:::......., @ %F(nS@uT@t_document@777+++++++) @{@ 8s@t_diagramtypes@;;;///////- @ {@oʠs@t_diagramobjects<@===1111111/ @|-@/I(nS@t_diagramlinks//////////- {@oʠs@t_diagram@ '666*******( @ ~B/{@a2@t_constrainttypes@%>>>22222220 @~> g]SI?5ProcessA process that must occur-!Pre-conditionA starting state that must be met;/Post-conditionAn ending state that must be met;/InvariantA state the object must always be in:. ~@jpz`uj`pwsrvwbrpdjwjrpsufbrpdjwjrpsurbfvv     IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n VC\N   2  2  2             !      '  2  '   Type ProductNameDataTypeSizeMaxLenMaxPrecMaxScale DefaultLen DefaultPrec DefaultScaleUserPDATA1PDATA2PDATA3PDATA4 HasLength GenericType DatatypeID''  PrimaryKeya{q q'On)DW<Z w-LDDLSQLServer7ntextntext<7777772(%  DDLSQLServer7ncharnchar<7777772(% DDLSQLServer7moneycurrency?7777772(% DDLSQLServer7intinteger<5555552(% DDLSQLServer7imagebinary=7777772(% 55DDLSQLServer7floatfloat<7777772(% &DDLSQLServer7decimaldecimal@9999992(% DDLSQLServer7datetimeDateTimeB::::::2(% @DDLSQLServer7charchar:6666662(% DDLSQLServer7bitboolean<5555552(% @ DDLSQLServer7binarybinary>8888882(% DDLOracleBFILEblob7333333.(% DDLOracleBLOBblob6222222.(% DDLOracleNCLOBntext8333333.(% cessDDLOracleCLOB2222222.(%  DDLOracleLONGlong6222222.(% " DDLOracleLONG RAWbinary<666666.(%  DDLOracleRAWbinary7111111.(%  DDLOracleROWIDuniqueidentifierC333333.(% DDLOracleDATEdatetime:222222.(% &DDLOracleNUMBERnumber:444444.(% ~~DDLOracleFLOATfloat8333333.(% 2DDLOracleNVARCHARnvarchar>666666.(% 2DDLOracleNCHARnchar8333333.(% 2DDLOracleVARCHARvarchar<555555.(% 2DDLOracleVARCHAR2varchar=666666.(% DDLOracleCHARchar6222222.(% ;bu&>DTr&Mfycess6CodeVisualcess6CodeVisual BasicDateDateTimeA9999995)% cess5CodeVisual BasicCurrencyCurrencyE======5)% cess4CodeVisual BasicByteByte=9999995)% cess3CodeVisual BasicBooleanBooleanC<<<<<<5)% 2DDLMSAccessYesNoboolean<5555550(% 1DDLMSAccessCountercounter>7777770(% 0DDLMSAccessDoubledouble<6666660(% /DDLMSAccessSinglefloat;6666660(% .DDLMSAccessLonglong84444440(% -DDLMSAccessIntegerinteger>7777770(% ,DDLMSAccessCurrencycurrency@8888880(% +DDLMSAccessDateTimedatetime@8888880(% *DDLMSAccessMemotext84444440(% 2)DDLMSAccessTextchar84444440(%  "@2'DDLSQLServer7varbinaryvarbinaryD;;;;;;2(% @2&DDLSQLServer7varcharvarchar@9999992(% %DDLSQLServer7tinyinttinyint@9999992(% $DDLSQLServer7timestamptimestampD;;;;;;2(% #DDLSQLServer7texttext:6666662(% "DDLSQLServer7smallmoneymoneyA<<<<<<2(% !DDLSQLServer7smallintsmallintB::::::2(%  DDLSQLServer7smalldatetimedatetimeG??????2(% DDLSQLServer7realreal:6666662(% &DDLSQLServer7numericnumeric@9999992(% 2DDLSQLServer7nvarcharnvarcharB::::::2(% 7`4]M~6dN wcessQCodeDelphiBooleanBoolean=666666/)% cessPCodeJavadoubleDouble9333333-)% cessOCodeJavafloatFloat7222222-)% cessNCodeJavalongLong5111111-)% cessMCodeJavabooleanBoolean;444444-)% cessLCodeJavashortShort7222222-)% cessKCodeJavaintInteger7000000-)% cessJCodeJavacharChar5111111-)% cessICodeJavabyteByte5111111-)% cessHCodeC++unsigned longUlong>999999,)% cessGCodeC++unsigned short:::::::,)% cessFCodeC++unsigned intUint<888888,)% cessECodeC++unsigned char9999999,)% cessDCodeC++void0000000,)% cessCCodeC++doubleDouble8222222,)% cessBCodeC++floatFloat6111111,)% cessACodeC++longLong4000000,)% cess@CodeC++shortShort6111111,)% cess?CodeC++intInteger6//////,)% cess>CodeC++charChar4000000,)% cess=CodeVisual BasicVariantVariantC<<<<<<5)% cess<CodeVisual BasicStringStringA;;;;;;5)% cess;CodeVisual BasicSingle;;;;;;;5)% cess:CodeVisual BasicObject;;;;;;;5)% cess9CodeVisual BasicLongLong=9999995)% cess8CodeVisual BasicIntegerIntegerC<<<<<<5)% cess7CodeVisual BasicDoubleDoubleA;;;;;;5)% 9v1V }:g&KLB{cessmCodeC#floatFloat5000000+)% cesslCodeC#charChar3//////+)% cesskCodeC#ulongUlong5000000+)% cessjCodeC#longLong3//////+)% cessiCodeC#uintUint3//////+)% cesshCodeC#intInteger5......+)% cessgCodeC#ushortUshort7111111+)% cessfCodeC#shortShort5000000+)% cesseCodeC#byteByte3//////+)% cessdCodeC#sbyte0000000+)% cesscCodeC#void///////+)% cessbCodeDelphiWordWord7333333/)% cessaCodeDelphiVariantVariant=666666/)% cess`CodeDelphiVariantVariant=666666/)% cess_CodeDelphiReal3333333/)% cess^CodeDelphiStringString;555555/)% cess]CodeDelphiSmallInt7777777/)% cess\CodeDelphiShortInt7777777/)% cess[CodeDelphiSingle5555555/)% cessZCodeDelphiLongWordUlong<777777/)% cessYCodeDelphiLongInt6666666/)% cessXCodeDelphiIntegerInteger=666666/)% cessWCodeDelphiExtended7777777/)% cessVCodeDelphiDoubleDouble;555555/)% cessUCodeDelphiCurrencyCurrency?777777/)% cessTCodeDelphiCharChar7333333/)% cessSCodeDelphiCardinal7777777/)% cessRCodeDelphiByteByte7333333/)% )w2ZDv.ZQ ~zA9mDDDLDB2TIMESTAMPtimestamp=444444+(% DDLDB2TIMEtime3//////+(% essA pro that must oDDLDB2SMALINT2222222+(% ODDLDB2REALreal3//////+(% !DDLDB2INTEGERinteger9222222+(% DDLDB2DOUBLEdouble7111111+(% DDLDB2DECIMALdecimal9222222+(% DDLDB2DATEdate3//////+(% DDLDB2CLOBtext3//////+(%  DDLDB2CHARACTERchar8444444+(%  DDLDB2BLOBblob3//////+(% ~DDLDB2BIGINTbigint7111111+(% }CodeVBNetDecimal5555555.)% |CodeVBNetDatetimeDateTime>666666.)% {CodeVBNetSingleSingle:444444.)% zCodeVBNetObject4444444.)% yCodeVBNetDateDate6222222.)% xCodeVBNetDoubleDouble:444444.)% wCodeVBNetBooleanBoolean<555555.)% vCodeVBNetByteByte6222222.)% uCodeVBNetCharChar6222222.)% tCodeVBNetLongLong6222222.)% sCodeVBNetShortShort8333333.)% rCodeVBNetStringString:444444.)% qCodeVBNetIntegerInteger<555555.)% cesspCodeC#decimalFloat7222222+)% cessoCodeC#boolBoolean6//////+)% cessnCodeC#doubleDouble7111111+)% 4t.Qz3V <8CBeev DDLInterBasenc DDLInterBasencharnchar;6666661(% DDLSQL Server 2000bitbooleanA::::::7(% @2DDLSQL Server 2000varbinaryvarbinaryI@@@@@@7(% &&& DDLSQL Server 2000numericnumericE>>>>>>7(% DDLSQL Server 2000sql_variantsqlvariantLBBBBBB7(% &&& DDLSQL Server 2000decimaldecimalE>>>>>>7(% DDLMySqlTEXTtext5111111-(%  "2DDLMySqlVARCHARvarchar;444444-(%  DDLMySqlCHARchar5111111-(% `DDLMySqlTIMEtime5111111-(% DDLMySqlDATETIMEdatetime=555555-(% DDLMySqlDATEdate5111111-(%  DDLMySqlDECIMALdecimal;444444-(% 5 DDLMySqlNUMERICnumeric;444444-(% 5 DDLMySqlREALreal5111111-(% 5 DDLMySqlDOUBLE PRECISIONdoubleC======-(% 5 DDLMySqlDOUBLEdouble9333333-(% DDLMySqlFLOATfloat7222222-(% DDLMySqlBIGINTbigint9333333-(% DDLMySqlMEDIUMINTinteger=666666-(% DDLMySqlINTEGERinteger;444444-(% DDLMySqlSMALLINTsmallint=555555-(% DDLMySqlTINYINTtinyint;444444-(% DDLMySqlBOOLboolean8111111-(% DDLMySqlBITboolean7000000-(%  DDLDB2VARCHARvarchar9222222+(% mB!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B    !"#$%& ' ( ) * +,-./0123456789:;<=>?@ A B C D EFGHIJKLMNOPQRSTUVWXYZ[ \ ] ^ _ `abcdefghijklmnopqrstuvw x y z { |}~ !!!!!!!!!! ! ! ! ! !!!!!!!!!!""""""""" " " """"""""""````````` ` ` ` ` ``````````"     !!!!!!!!!! ! ! ! ! !!!!!!!!!!""""""""" " VC 1N      SI2    2        2             $       at     XM(  ,   st    P Diagram_ID Package_IDParentID Diagram_TypeNameVersionAuthor ShowDetailsNotes StereotypeAttPubAttPriAttPro OrientationcxcyScale CreatedDate ModifiedDateHTMLPath ShowForeign ShowBorderShowPackageContentsPDATALockedea_guidTPos SwimlanesStyleEx cgIPeIPm yy    Diagram_ID Diagram_TypeIDX_GUID Package_IDParentID PrimaryKeytypest_diagramagram {qg]SI@@F9999pp/*Zd@ZHl@TEXTLogicalLogical Model1.0Geoffrey SparksPHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=/*Zd@ZHl@TEXTLogicalLogical Model1.0Geoffrey SparksPHideRel=0;ShowTags=0;ShowReqs=0;Sh/*Zd@ZHl@TEXTLogicalLogical Model1.0Geoffrey SparksPHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=0;///*Zd@ZHl@TEXTLogicalLogical Model1.0Geoffrey SparksPHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=0;OpParams=1;ShowSeqNotes=0;ScalePrintImage=0;PaperSize=9;ShowIcons=1;SuppressCollabNumber=0;HideProps=0;HideParents=0;UseAlias1.nd@l@_objStatechartObjectModel1.0PHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=0;OpParams=1;ShowSeqNotes=0;ScalePrintImage=0;PaperSize=9;ShowIcons=1;SuppressCollabNumber=0;HideProps=0;HideParents=0;UseAlias=0;HideAtts=0;HideOps=0;HideStereo=0;HideElemStereo=0;FormName=;{7C41101B-9CC4-4760-984A-D71FD9C2E4BB}locked=false;orientation=0;width=0;names=false;color=0;bold=false;fcol=0;;cls=0;e@& X2JJIIIIF;10.ndA@&@tObjObjectHouseExampleModel1.0PHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=0;OpParams=1;ShowSeqNotes=0;ScalePrintImage=0;PaperSize=9;ShowIcons=1;SuppressCollabNumber=0;HideProps=0;HideParents=0;UseAlias=0;HideAtts=0;HideOps=0;HideStereo=0;HideElemStereo=0;FormName=;{2DBA38A4-BB85-46dc-A5ED-C43AD3050EC4}locked=false;orientation=0;width=0;names=false;color=0;bold=false;fcol=0;;cls=0;e@0 Z4LLKKKKH71 ,nd @Tv:)@TEXTLogicalHouseMetamodel1.0PHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=0;OpParams=1;ShowSeqNotes=0;ScalePrintImage=0;PaperSize=9;ShowIcons=1;SuppressCollabNumber=0;HideProps=0;HideParents=0;UseAlias=0;HideAtts=0;HideOps=0;HideStereo=0;HideElemStereo=0;FormName=;{2FBE7B3F-756C-46a0-90EE-93429FDA065D}locked=false;orientation=0;width=0;names=false;color=0;bold=false;fcol=0;;cls=0;e@2 X2JJIIIIF81  01/ / / / / / / / / / /  mrhjb`m rakfbwvw`wfbi`uwrhjb`m mrhjb`m mrhjb`m mrhjb`m mrhjb`m mrhjb`m mrhjb`m vw`wfbi`uww`wfbi`uww`wfbi`uwxvfb`vfreignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n .Xda`Y^`Zaa^[Z\db`[fdbZY`dYV[VfbZ0.Xgaf]aYg][\bZ\`V_Vff_YZX_gd`V\[d0 .]bZWWVWa_bbZZ]\V_^Z`d]Wgd_bXfZaa0.dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 .dYgXYdYdg]g[ZZag_][ZVb\ZWfa^`]Ya0 , ..* * * * * * * * * * *              01/ / / / / / / / / / / VC N    '       DiagramID ConnectorIDGeometryStyleHiddenPath Instance_ID'''''''  ConnectorID DiagramID PrimaryKeyE{qg]@@ @ bbbb b b bb b b b bb  !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~ @ bbbbbbbb0b 0b 0b 0b 0b @ bbbbbb b b  b b b bbVCN               Diagram_ID Object_IDRectTopRectLeft RectRight RectBottomSequence ObjectStyle Instance_IDTo  DiagramIDObjectID PrimaryKey-81D5-714093282A5D} DiagramIDObjectID PrimaryKeyS{qg@  @ @ 0 0 0000 !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~ @ @<=>ABCD G H LMNOP @ @        VCN   S2  4  Diagram_TypeName Package_IDShT  PackageID PrimaryKeyeID PrimaryKeygramTypes PackageID PrimaryKey{q|_E'pB @ @@@ @@  @@@@@@ @`dojpd`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXt,brppfbwjrpvYt,brppfbwrut,d`w`w}sfvt,fbgt,josmfofpwvt,ofwirdt,rakfbwt,rakfbwuf`mj~fvt,rakfbwwfvwv t,s`bl`hfv!t,slhrakfbw2t,uf`mj~fvW2t,uf`mj~fvX2t,ufvrxubf2t,vxofbg2t,vxowbg2t,wbg2t,xbofwujbv2t,zjvjamfrakfbw2tdg,`wwujaxwf2 tdg,dj`hu`omjpl2 tdg,rakfbw2 tdg,rsfu`wjrp2 tdg,ufm`wfvwr2 tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2CompositeStructureCompositeStructure)ObjectObject TimingTiming PackagePackage InteractionOverviewInteractionOverview+CollaborationCollaborationUse CaseUse Case View StatechartStatechartSequenceSequence LogicalLogical View DeploymentDeploymentCustomCustom ComponentComponentAnalysisAnalysis ActivityActivity  @ @     Type DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n @@@`bwjzjw}`p`m}vjvbrmm`aru`wjrp brosrpfpwbrosrvjwfvwuxbwxufbxvwrodfsmr}ofpwjpwfu`bwjrprzfuzjf{ mrhjb`mrakfbw s`bl`hf vftxfpbfvw`wfbi`uwwjojph xvfb`vfVCN   (  d      (  2      d  N2    DocIDDocNameNotesStyle ElementID ElementType StrContent BinContentDocTypeAuthorVersionIsActiveSequenceDocDate  PrimaryKeyE{qg]@           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~VCKN   2    ECFID DescriptionWeightValueNotesDgmDbcIRt  NumericWeight PrimaryKey{qMV#g@@ @ @@@ @@  @@@@@@`dojpd`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXt,brppfbwjrpvYt,brppfbwrut,d`w`w}sfvt,fbgt,josmfofpwvt,ofwirdt,rakfbwt,rakfbwuf`mj~fvt,rakfbwwfvwv t,s`bl`hfv!t,slhrakfbw2t,uf`mj~fvW2t,uf`mj~fvX2t,ufvrxubf2t,vxofbg2t,vxowbg2t,wbg2t,xbofwujbv2t,zjvjamfrakfbw2tdg,`wwujaxwf2 tdg,dj`hu`omjpl2 tdg,rakfbw2 tdg,rsfu`wjrp2 tdg,ufm`wfvwr2 tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,b@ECF08Difficult programming language44ECF07Part-time workers''@@ECF06Stable requirements))?@ECF05Motivation ?@ECF04Lead analyst capability--?@ECF03Object-oriented experience00?@ECF02Application experience,,?@ECF01Familiar with Rational Unified Process<< @@@ IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n @ fbgVWfbgVXfbgVYfbgVZfbgV[fbgV\fbgV]fbgV^VC?N  '      EffortType Description NumericWeightNotes'''''  NumericWeight PrimaryKey{q@@@@ @ @@@ @@  @@@@@@`dojpd`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXt,brppfbwjrpvYt,brppfbwrut,d`w`w}sfvt,fbgt,josmfofpwvt,ofwirdt,rakfbwt,rakfbwuf`mj~fvt,rakfbwwfvwv t,s`bl`hfv!t,slhrakfbw2t,uf`mj~fvW2t,uf`mj~fvX2t,ufvrxubf2t,vxofbg2t,vxowbg2t,wbg2t,xbofwujbv2t,zjvjamfrakfbw2tdg,`wwujaxwf2 tdg,dj`hu`omjpl2 tdg,rakfbw2 tdg,rsfu`wjrp2 tdg,ufm`wfvwr2 tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2?TransitionImplementation, acceptance testingThe Transition phase revolves around the implementation of the project and the acceptance testing carried out by the end user5 ?ElaborationRefine specification. Set up projectThe elaboration phase is concerned with refining the sstem specification, setting up project infrastructure and agreeing on the body of work to be completed.8 ?DesignDesigning specificationsProcss of developing system designI' ?ConstructionDesign and build system componentsThe construction phase is concerned with designing and building the components necessary to implement the ystem as specified.7 ?CodingDeveloping codeCode writing* ?AnalysisAnalysing SystemAnalysis)!  @    IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n @`p`m}vjvbrdjphbrpvwuxbwjrpdfvjhpfm`aru`wjrpwu`pvjwjrpVCQN  2  2  d        FileID AppliesToCategoryNameFileNotesFileDateFileSizenn  PrimaryKeyS{qg           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~VClN     AppliesToOption{q@@%LVALȆ5@@ @ @@@ @@  @@@@@@@ @`dojpd`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXnKill=0;nLang=1;bConstructor=1;bConInline=0;sConScope=Public;bCpyConstructor=0;bCpyConInline=0;sCpyConScope=Public;bDestructor=1;bDesVirtual=1;bDesInline=0;sDesScope=Public;CHeader=.h;CBody=.cpp;JBody=.java;VBody=.cls;VBNetBody=.vb;sAssocName=m_$LinkClass;bGetSet=1;bGenInterfaces=1;JCol=Vector;CCol=[];VCol=Collection;bVMultiuse=1;bVPersist=0;bVDatabind=0;bVDatasource=0;bVGlobal=0;bVCreatable=1;bVExpnKill=0;nLang=1;bConstructor=1;bConInline=0;sConScope=Public;bCpyConstructor=0;bCpyConInline=0;sCpyConScope=Public;bDestructor=1;bDesVirtual=1;bDesInline=0;sDesScope=Public;CHeader=.h;CBody=.cpp;JBody=.java;VBody=.cls;VBNetBody=.vb;sAssocName=m_$LinkClass;bGetSet=1;bGenInterfaces=1;JCol=Vector;CCol=[];VCol=Collection;bVMultiuse=1;bVPersist=0;bVDatabind=0;bVDatasource=0;bVGlobal=0;bVCreatable=1;bVExposed=0;sMTS=0;sCRefType=*;sCGetPrefix=Get;sCSetPrefix=Set;sJGetPrefix=get;sJSetPrefix=set;sCSGetPrefix=Get;sCSSetPrefix=Set;sVVersion=6.0;CSBody=.cs;DBody=.pas;bJInnerClasses=1;sJCollection=;_AFX_NO_DEBUG_CRT;_AFX_NO_OCC_SUPPORT;_AFX_OLD_EXCEPTIONS;_AFX_PACKING;_AFXDLL;_DEBUG;_MSC_VER;_UNICODE;AFX_CDECL;AFX_COMDAT;AFX_DATA;AFX_DATADEF;AFX_NOVTABLE;AFXAPI;APICALL;BEGIN_INTERFACE_PART ^ END_INTERFACE_PART;BEGIN_PARAM_MAP ^ END_PARAM_MAP;CONTROLLER_API;DECLARE_DYNAMIC();DECLARE_DYNCREATE();DECLARE_INTERFACE_MAP();DECLARE_MESSAGE_MAP();defined();PASCAL;SWLAPI;WINAPI;CMACROz@ClassQ@VC N       TermTypeMeaning GlossaryIDO  PrimaryKeyS{qg RLVAL Lyn@ @ @ @ @ @ @ @ @          A relationship between two use cases in which one use case 'includes' the behaviour. This is indicated where there a specific business use cases which are used from many other places - for example updating a train record may be part of many larger business processes.A relationship between two use cases in which one use case 'extends' the behavior of another. Typically this represents optional behavior in a use case scenario - for example a user may optionally request a list or report at some point in a performing a business use case. A model of the system as it will be physically deployedA view of the proposed hardware that will make up the new system, together with the physical components that will execute on that hardware. Includes specifications for machine, operating system, network links, backup units &etc.A person or a company that requests An entity to transport goods on their behalf.The component model provides a detailed view of the various hardware and software components that make up the proposed system. It shows both where these components reside and how they inter-relate with other components. Component requirements detail what responsibilities a component has to supply functionality or behavior within the system.A logical entity encapsulating data and behaviour. A class is a template for an object - the class is the design, the object the runtime instance.A relationship between two or more entities. Implies a connection of some type - for example one entity uses the services of another, or one entity is connected to another over a network link.A defined period of time whereby performance reports may be extracted. (normally 4 week periods). P)Y1 Use CaseTechnicalZ@"  Includes RelationshipTechnical @/#Extends RelationshipTechnical@."Deployment ModelTechnical7@*Deployment ArchitectureTechnical@1%CustomerBusinessQ@! Component ModelTechnicalV@)ClassTechnical@ AssociationTechnical@%Accounting PeriodsBusinessb@+LVAL A Use Case represents a discrete unit of interaction between a user (human or machine) and the system. A Use Case is a single unit of meaningful work; for example creating a train, modifying a train and creating orders are all Use Cases. Each Use Case has a description which describes the functionality that will be built in the proposed system. A Use Case may 'include' another Use Case's functionality or 'extend' another Use Case with its own behaviour. Use Cases are typically related to 'actors'. An actor is a human or machine entity that interacts with the system to perform meaningful work.; `bbrxpwjphsfujrdv`vvrbj`wjrpbm`vvbrosrpfpwordfmbxvwrofudfsmr}ofpw`ubijwfbwxufdfsmr}ofpwordfmf|wfpdvufm`wjrpvijsjpbmxdfvufm`wjrpvijsxvfb`vf VCiN 2  TypeTemplate{q }LVALu #NAME# #TYPE# #COMPLEX# #PACKAGE#
#ITEM# #TYPE#   #NOTE#  

#ROWS#
#ObjectDetail#
#ITEM# #TYPE#   #NOTE#  

Untitled Enterprise Architect

Use Case Report: #NAME#
Author: #AUTHOR#
Date Prepared: #DATE#
Comments: #COMMENT#

 

oQ6UCMetricsCF@ UCMetrics UCMetricsRow@ ObjectDetailLine@Object@Diagram@ObjectDetail@ UseCaseDiagram@LVAL Enterprise Achitect Diagram Template #PROJECT#

#REPORT#: #NAME#  
Package: #PACKAGE#  
Author: #AUTHOR#   Date: #DATE#
Comments: #COMMENT#  

 



Entity List



#ENTITIES#

End of Report


#IMAGEMAP# LVAL^ #CFID_TITLE# #CFID_NAME# #CFID_WEIGHT# #CFID_VALUE# #CFID_EXVALUE#
Type: #TYPE#  
Stereotype: #STEREO#  
Author: #AUTHOR#  
Date: #DATE#  
Package: #PACKAGE#  
Notes: #NOTE#  

LVAL Untitled

Enterprise Architect : Use Case Metrics Report



Use Case Metrics

Use Case : Root Package #NAME#
Date Prepared: #DATE#
Unique Use Case Points #UUCP#
Total Package Estimate (hours) #ESTIMATE#

 

Estimate Summary

Use Case Points (UCP) = #UCPCALC# #UCPRESULT#
Work Effort (hours) = #EFFORTCALC# #EFFORT#

 


View

Technical Complexity Summary

Environmental Factors Summary

Unique Use Cases and Actors

Technical Complexity Details

Environmental Factors Detail 


 

Technical Complexity FactorsLVAL

Factor Weight
Unadjusted TCF Value (UTV) #UTV#
TCF Weight Factor (TWF) #TWF#
TCF Constant (TC) #TC#
Technical Complexity Factor (TCF) = TC + (TWF*UTV) #TCF#

 

Environmental Factors

Factor Weight
Unadjusted ECF Value (UEV) #UEV#
ECF Weight Factor (EWF) #EWF#
ECF Constant (EC) #EC#
Environmental Complexity Factor (ECF) = EC + (EWF*UEV) #ECF#

 

Unique Use Cases and Actors

#UUCAA#
Name Type Complexity Package

 

 

Technical Complexity Factors

#TCFDATA#

 

 

Environmental Complexity Factors

#ECFDATA#

 

 

VCN       ImageIDNameTypeImage{qVCDN  2Type{\(FW}S@W}S@t_implement*********** W}S@W}S@t_image&&&&&&&&&&& W}S@W}S@t_html%%%%%%%%%%% W}S@W}S@t_glossary))))))))))) W}S@W}S@t_genopt''''''''''' W}S@W}S@t_files&&&&&&&&&&& W}S@W}S@t_efforttypes,,,,,,,,,,, W}S@W}S@t_ecf$$$$$$$$$$$ W}S@W}S@t_document))))))))))) :W}S@:W}S@t_diagramtypes----------- :W}S@:W}S@t_diagramobjects/////////// :W}S@:W}S@t_diagramlinks----------- :W}S@:W}S@t_diagram((((((((((( +sV}S@:W}S@t_datatypes*********** ~+sV}S@+sVComponent UseCaseRequirement VCN        2            2  2 dIssue IssueDateOwnerStatusNotesResolver DateResolved ResolutionIssueIDCategoryPrioritySeverity IssueType   PrimaryKeyC{qg]O9[N            <ProducaddressPrivateNot Specified1100String{A8DF581B-9AC6-4f75-AB48-8FAEDFC6E068} volatile=0;xRLLKKKJJJIH;;4-PVCN  2  d     ListIDCategoryNameNValNotes  PrimaryKeyS{qg.Xaf[VXfZf]bYZW[f^[YZVg\V_g][`XXZ0T.Y\b[Xb[\[^YgZ^[WaVbW`XZg]^_\[bfZ0T.[YW^daYYZ]`^ZWb[_VbZbX[bVYf^b`_]0T.]^WX_YVZYZ`^Z^Ya_[g\adgdVg_bWgW^0T._]\daWf`]Wf^ZYXg_gdb_Y[d^]V\gZgg0T.gX`bW]a^^Z]`Z`b[^gW`X]VaWgX`gV]Y0T222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~     VC>N '  2    MaintType Description NumericWeightNotes  NumericWeight PrimaryKey{q            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~     VC*N     2  2 Object_IDNameScopeTypehNe  Object_ID PrimaryKeyF3CF-4E2A-B0A0-A7266C98C7DB} Object_ID PrimaryKey{q|  @@@ @  @ `dojpd`w``bbfvvs`hfvd`w`a`vfvgruov ordxmfv ufm`wjrpvijsvufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vordxmfvov}vordxmfvXov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsvt,`wwujaxwft,brppfbwjrpvt,brppfbwjrpvXt,brppfbwjrpvYt,brppfbwrut,d`w`w}sfvt,fbgt,josmfofpwvt,ofwirdt,rakfbwt,rakfbwuf`mj~fvt,rakfbwwfvwv t,s`bl`hfv!t,slhrakfbw2t,uf`mj~fvW2t,uf`mj~fvX2t,ufvrxubf2t,vxofbg2t,vxowbg2t,wbg2t,xbofwujbv2t,zjvjamfrakfbw2tdg,`wwujaxwf2 tdg,dj`hu`omjpl2 tdg,rakfbw2 tdg,rsfu`wjrp2 tdg,ufm`wfvwr2 tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd#x@ @@  @tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfvw,ofwirdw,ofwujbw}sfvw,rakfbww,rakfbwbrpvwu`jpww,rakfbwfggruww,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$ w,sujojwjzfv$ w,suramfow}sfv$ w,surkfbwurmfv$ w,sursfuw}w}sfv$ w,uftxjufw}sfv$w,ufvrxubfv$w,ujvlw}sfv$w,urmfbrpvwu`jpw$w,uwg$w,uwgufsruw$w,uxmfv$w,vbfp`ujrw}sfv$w,vbujsw$w,vfbhurxs$w,vfbhurxssfuojvvjrp$`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~     VC;N   2   Metric Description NumericWeightNotes  NumericWeight PrimaryKeyght PrimaryKey{q@@Zmntdg,ufm`wfvwr2 ?TeamStaffing, team dynamicsResource turnover5$ ?ProgressIteration, planning, actualsMeasures such as function points, SLOC, scenarios, test cases. Measp- ?CostBudget, cost, expenditureCost per day, percentage expended.H& ?ChangeChange control, stabilityChange requests, 9( ?BreakageConvergence, rework, software scrapReworked SLOC per change. N4       IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n @auf`l`hfbi`phfbrvwsurhufvvwf`o VCePN9%9                2             2                $  (  0    2     8                   2   2   2 !  !2 !" "2 "# # #$ $ $% % %& &2 &' ' '( ( () ))* < *+ +(+, @ ,- - -.  .(./ D/0 01 12 23  34  4 4 5  5 5!6 62 6"7  7 7#8  8 8$9  9 Object_ID Object_Type Diagram_IDNameAliasAuthorVersionNote Package_ID StereotypeNType ComplexityEffortStyle Backcolor BorderStyle BorderWidth Fontcolor Bordercolor CreatedDate ModifiedDateStatusAbstractTaggedPDATA1PDATA2PDATA3PDATA4PDATA5 Concurrency Visibility Persistence CardinalityGenTypeGenFileHeader1Header2PhaseScope GenOptionGenLinks Classifierea_guidParentIDRunStateClassifier_guidTPosIsRootIsLeafIsSpecIsActive StateFlags PackageFlags MultiplicityStyleEx ActionFlags EventFlags*sa scsDte epSrRetSr SrIgetSrIIDX_GUID Object_ID Package_ID#$' ( , 6 , 6 6 6 6 6 {qg]SI?5 @ o{@ @@  @ tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfvw,ofwirdw,ofwujbw}sfv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfdLVALȺqg                t_diagramobjects.Diagram_ID=222t_packaget_objectt_object_1t_diagramobjectst_objectt_objectt_package*@%?t_objectt_object_1*@&?t_objectt_diagramobjects/@, ?Bt_object.Classifier_guid,3At_object.Cardinality(3@t_object.Visibility'3?t_object.Concurrency(3> t_object.TPos!3=t_object.StyleEx$3<t_object.Persistence(3;t_object.ParentID%3:t_object.Multiplicity)3this aggregation is navigable from room to house (EA does not show it)this aggregation is navigable from room to house (EA does not show it) """"Tf{  9P,6))@d0)@InterfaceCookingPlace1.0interface1Proposed1Java1.0Public{E21E535F-E300-4405-A917-28FFB4B2DB6E}{xxxxttttttttttskkjaa^^^RI%Ob9O.!Ce@@Aor.EObjectWetRoom1.01Proposed0Java1.0Public{783325F8-9AA7-4836-A0D9-DDA9103CDC71}{244CC9E5-1F81-4164-9215-C048EC679543}pppjggggccccccccccbZZYYYVVVOI%Ob.9N.?@q@BagraObjectSomeone1.01Proposed0Java1.0Public{960E757D-3D81-43e2-BA2E-5F7341421EA5}{2F1D9CC6-F38F-4a34-B3C4-B92915108384}pppjggggccccccccccbZZYYYVVVOI%Ob.9M.d@T`@>_IDCObjectHotRoom1.01Proposed0Java1.0Public{9907C98A-7E63-47dc-8A4D-ED020B68C41D}{9CE44C59-37E4-4117-8C05-F87C4DC33529}pppjggggccccccccccbZZYYYVVVOI%Ob.9L.G@@P@=ctorObjectYellowRoom1.01Proposed0Java1.0Public{5D770C43-247F-41e6-BC35-93C5A9204E76}{14DB5E54-CD7B-4c84-998C-44960049D7E0}sssmjjjjffffffffffe]]\\\YYYOI%Ob.9@@@VaPackageHouseMetamodel1.01Proposed44Java1.0Public{A1B83D59-CAE1-422c-BA5F-D3624D7156AD}yyysppppllllllllljjbbaaa^^^PI%Oݿb9H.*%@k@=t_1.ObjectGreenRoom1.01Proposed0Java1.0Public{597D270D-65EB-4941-908B-A42419BD7C3F}{14DB5E54-CD7B-4c84-998C-44960049D7E0}rrrliiiieeeeeeeeeed\\[[[XXXOI%Ob.9G.q2@@<ObjectSomeonesHouse1.01Proposed0Java1.0Public{3D59084A-BBC6-4d6b-B8E5-9A764D27563B}{436D81AD-A9B0-44d8-8AD1-86BB0808DA32}œvvvpmmmmiiiiiiiiiih``___\\\OI%Ob.+N                      !!""##$$%%&&''(())**++,-./01234 5 6 7 8 9:;<=>?@ABt_a=enterPublicvoid00Sequential00{A8C01177-4523-44c4-87F7-F2B8F9F3C915}TT......--,,,"!! o{N.V\b_b_[^bWZ`ZWgZ^_`_\^]YbbfdY]`]0^.WZda[f[Zbd]aZb^Z__^bZZ_\VVZ_d]fV0^ .XZZbb_f[Wg^WZW\Z_XW[bVZ^fb\]_[ZY0^ .XgWd_bb\gY^gZ`YZaYbZa_X_W[WV^Y^Z0^.Yd[_V^Z`aab\Zd\aa^f[_`]\ZdX][\Ya0.ZY\d^W`d`_aVZZd^^`dW^\aaV^V^d`YX0^.[_]dX]Vd\[faZ_ZW_V^a`ZXZW_ad]bYg0.[d]]VbZYXZ]gZWf\abY[_Yb[`_XVZf]\0.]^YYX[g^_``]Z^Y\`Vd_dd`_WVYbdb]W0 ._\Vf][]dYd^WZYfXa`Xf[g]YZWZXWf`[0 .__V]b_^`]f\YZ]db^`ZdfdVXVa\^bZWd0._bfZZb[_Y]fZZWW]^bV[g^]bZdbYY[X_0^ ._d]bV]XdXg]ZZYZ^aWd_a`Ybg`]Xgb\g0^.`Wa^Yd[_b`fWZXXba`[gdY\XZd]W[\`d0^ .ba_f^ZdZ_V\ZZ_dVagWfff[YbV[^[Yfg0^.fXWf[Y[gfYVVZZV[`_W]X^ggaZaXda\f0 .g_d^b\fYZd`dZ``X`dZ]dV`a`Zf_YfV^0^ .gbVVdX^Zbg_WZY]faY]gZVZYaZY[VWbb0.gbVVdX^Zbg_WZY]faY]gZVZYaZY[VWbb0.gbVVdX^Zbg_WZY]faY]gZVZYaZY[VWbb0.gbVVdX^Zbg_WZY]faY]gZVZYaZY[VWbb0.gbVVdX^Zbg_WZY]faY]gZVZYaZY[VWbb0.gbVVdX^Zbg_WZY]faY]gZVZYaZY[VWbb0.gbVVdX^Zbg_WZY]faY]gZVZYaZY[VWbb0@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n o{o @ @<^=^ >^ ?^ @^ A^ B^C^D^E^GHLMN O P =^ =^ =^ =^ =^ =^ =^ o{o @ @^ ^+^ +^ +^ ,^,^ ,^,^,^, ..... . ^ ^ ^ ^ ^ ^ ^ VCN     .(   '  2 Object_ID ConstraintConstraintTypeWeightNotesStatus2099E~v#d'd' ObjectConstraintConstraintObjectID PrimaryKeyE{qg]           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~     VCTN          Object_IDEffort EffortTypeEValueNotes ObjectID PrimaryKey{qg            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~     VC N      '2     '   Object_IDFileNameTypeNoteFileSizeFileDate  PrimaryKeyS{qg           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~     VCN   pe  t_    es Object_IDMetric MetricTypeEValueNotes48;:=A ObjectIDObjectMetricsMetric PrimaryKey&{4284C791-A819-44C8-B0AD-41BCCD533E6A}ObjectIDObjectMetricsMetric PrimaryKeyC{qg]]            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~     VCN      '   '2          2    b2 2 Object_IDProblem ProblemType DateReportedStatus ProblemNotes ReportedBy ResolvedBy DateResolvedVersion ResolverNotesPrioritySeverity'''''' ObjectIDObjectRequiresRequirement PrimaryKey 7 {qg]S9           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~      vrofwijph9dfgfbwvrofwijphVCpN          ( PropertyID Object_IDPropertyValueNotesea_guid   Object_ID PrimaryKey{qg@            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~     VCN          2    2  002  "#2  ReqID Object_ID RequirementReqTypeStatusNotes Stability DifficultyPriority LastUpdate(0(0( 0(0(0 (0(0  (0(0 ObjectIDObjectRequiresRequirement PrimaryKeyReqID{qg]           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~     VCN                or    " Object_IDResourceRoleTimeNotesPercentComplete DateStartDateEndHistory ExpectedHours ActualHours2 ObjectID PrimaryKey{qg]            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~      VCPN          Object_IDRiskRiskTypeEValueNotes ObjectID PrimaryKey{qg           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~      VCN     '    '    ( Object_IDScenario ScenarioTypeEValueNotes XMLContentea_guidePctme ttr ObjectID PrimaryKey{qg]           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~      VC1N    ef   l    V   cr  In    2  ec Object_IDTest TestClassNotes InputDataAcceptanceCriteriaDateRunResultsRunByCheckByTestTypeStatus     ObjectID PrimaryKey  {qg]SIII           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~      @ @ @ @ @@ @@brosrpfpwf|fbxw`amfbrosrpfpwgjmfbrosrpfpwmjau`u} brosrpfpww`amf brpvwu`jpwjpz`uj`pw brpvwu`jpwsrvwbrpdjwjrp brpvwu`jpwsufbrpdjwjrp dfsfpdfpb}`bbfvvdfsfpdfpb}ajpddfsfpdfpb}b`mmdfsfpdfpb}dfujzfdfsfpdfpb}gujfpddfsfpdfpb}josruwdfsfpdfpb}jpvw`pbfrgdfsfpdfpb}jpvw`pwj`wfdfsfpdfpb}sr{fuw}sfdfsfpdfpb}ufgjpfdfsfpdfpb}vfpddfsfpdfpb}wu`bfdfsfpdfpb}xvf hfpfu`mj~`wjrpjosmfofpw`wjrp hxjfmfofpwaxwwrp hxjfmfofpwbifblar| hxjfmfofpwbroarar| hxjfmfofpwd`wfhxjfmfofpwdj`mrhhxjfmfofpwdursdr{phxjfmfofpwgruohxjfmfofpwimjpf hxjfmfofpwmjvwhxjfmfofpwmjvwzjf{hxjfmfofpws`pfmhxjfmfofpwu`djrhxjfmfofpwufsruwhxjfmfofpww`ahxjfmfofpwwf|war|hxjfmfofpwwjofhxjfmfofpwwuffmjvwrrrrrrrrrrrrrnnffeeebSSPI#oݿ`7'@XJw7@ction poPackageSecurity ManagementGeoffrey Sparks1.01Proposed03091.0Public{31DF0209-02FF-4fba-A408-13CCDFFDC5E8}~vvuuurccPI#o`9'@x E@n poPackageUse Case ModelGeoffrey Sparks1.01Proposed020351.0Protected{9026BE2C-C92B-4c29-994E-749633230A32}~~~~~~~~~~~~~zyqqpppm^^PI%o`N7'@un2@ction poNoteNoteGeoffrey Sparks1.0*@1Proposed1.0Public{FD060C26-64A8-4400-93F1-3EBBD20AA618}{xxxxxxxxxxxxxxxppooc`QQMI#ݿ`7'5@@$ܯ@ction poNodeCD StackerGeoffrey Sparks1.0cd-rom1Proposed01.0Public{AA3F097F-41D9-41e0-A293-1F0AA68F10CF}|yyyyyyyyyyyyyyxppoiifWWMI#o`VCN   d  '    ' Object_IDTRXTRXTypeWeightNotess'd''d'd d'd! ObjectConstraintConstraintObjectID PrimaryKeyE{qg]           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       VC;:N##:  2     Object_Type Description DesignObjectImageID#&#' ImageID PrimaryKey{q@ C!Gr$FNBD`C;BUAx-@BZ}S@BZ}S@t_stereotypes,,,,,,,,,,,)B{@e$@t_statustypes1@;:::......., @%F(nS@%F(nS@t_secuserpermissionP@@@@44444442 @%F(nS@%F(nS@t_secusergroupK@;;;///////- @%F(nS@%F(nS@t_secuser@666*******( @%F(nS@%F(nS@t_secpermissionX@ <<<0000000. @%F(nS@%F(nS@t_seclocks@777+++++++) @%F(nS@%F(nS@t_secgrouppermissionQ@AAA55555553 @AF(nS@AF(nS@t_scriptk@555)))))))' @B{@U2@t_scenariotypes@;<<<0000000. @vF(nS@vF(nS@t_rulesi@444(((((((& @Ȍ@{@U2@t_rtfreportq:888,,,,,,,* @n>{@U2@t_roleconstraint:@9===1111111/ @j!={@U2@t_risktypes{@9888,,,,,,,* @g8Xt*M@U2@t_resources@8888,,,,,,,* @bpl<{@U2@t_requiretypes@8;;;///////- @Y]@.N@U2@t_projectroles@6;;;///////- @Tm;{@U2@t_problemtypes@6;;;///////- @P6:{@U2@t_primitives"@7999-------+ @N2@2@t_paletteitem.........., L2@2@t_palette**********( Chn@[,s@t_package@7666*******( @?6*,@U2@t_operationtag//////////- 7x7{@U2@t_operationposts8@5===1111111/ @26{@/I(nS@t_operationparams@5>>>22222220 @+]5{@/I(nS@t_operation@4888,,,,,,,* @(С4{@h*@t_ocf@2222&&&&&&&$ @":zX>&{gQ6}mWG3N(tJ h2[4ParameterUML Activity Parameter" ExpansionNodeUML Expansion Node"ExitPointUML Exit Point EntryPointUML Entry Point InteractionOccurrenceInteractionOccurrence-ActionAction ActivityPartitionActivityPartition%DeploymentSpecificationDeploymentSpecification1ExceptionHandlerExceptionHandler#ActivityRegionActivityRegionMessageEndpointMessageEndpoint!CollaborationOccurrenceCollaborationOccurrence1PartPart ProvidedInterfaceProvidedInterface%ActivityParameterActivityParameter%ActionPinActionPin ObjectNodeObjectNode LoopNodeLoopNode ConstraintConstraint DiagramFrameDiagramFrameRequiredInterfaceRequiredInterface%ExpansionRegionExpansionRegion!InterruptibleActivityRegionInterruptibleActivityRegion9TimeLineTimeLine InteractionStateInteractionState#InteractionFragmentInteractionFragment)UMLDiagramUML Diagram ArtifactUML Artifact PortUML PortUserUser  UseCaseUseCase  TextText  SynchronizationSynchronization! StateNodeStart End State  StateState Chart ObjectSequenceSequence   ScreenInterface Screen RequirementRequirementReportSystem report PackagePackage ObjectObject  NoteNote   NodeNode LabelLabel  IssueIssue InterfaceInterface  GUIElementUser interface object" EventEvent  EntityEntity  DecisionDecision   ComponentComponent CollaborationCollaboration ClassClass ChangeChange BoundaryBoundary  AssociationAssociation ActorActor  ActivityActivity  r"@ @ @ @ @ @ @ @%%%% %%%%%%%%%% %%%%% %%%% %!%"%#%$%%%&%'%(%)%*%+%,%-%.%/%0%1%2%3%4%5%6%7%8%9 % % %% %%% %%%       E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n X"@  @  @    @`bwjrp%4`bwjrpsjp%*`bwjzjw}%`bwjzjw}s`u`ofwfu%+`bwjzjw}s`uwjwjrp%3`bwjzjw}ufhjrp%0`bwru%`uwjg`bw%`vvrbj`wjrp%arxpd`u}%bi`phf%bm`vv%brmm`aru`wjrp%brmm`aru`wjrprbbxuufpbf%.brosrpfpw%brpvwu`jpw%'dfbjvjrp%dfsmr}ofpwvsfbjgjb`wjrp%2dj`hu`ogu`of%&fpwjw}% fpwu}srjpw%6fzfpw% f|bfswjrpi`pdmfu%1f|jwsrjpw%7f|s`pvjrpprdf%8f|s`pvjrpufhjrp%$hxjfmfofpw% jpwfu`bwjrpgu`hofpw% jpwfu`bwjrprbbxuufpbf%5jpwfu`bwjrpvw`wf%!jpwfug`bf% jpwfuuxswjamf`bwjzjw}ufhjrp%#jvvxf% m`afm%mrrsprdf%(ofvv`hffpdsrjpw%/prdf%prwf%rakfbw%rakfbwprdf%)s`bl`hf%s`u`ofwfu%9s`uw%-sruw%surzjdfdjpwfug`bf%,ufsruw%uftxjufdjpwfug`bf%%uftxjufofpw%vbuffp%vftxfpbf%vw`wf%vw`wfprdf%v}pbiurpj~`wjrp%wf|w%wjofmjpf%"xomdj`hu`o%xvfb`vf%xvfu%VCmN)) 2  ObjectTypeComplexityWeight{((CX}S@CX}S@t_ocf$$$$$$$$$$$ "CX}S@CX@UseCase ?Actor VCVN,,      2      2    2      0(          0(     0(  2  0(     0(  2  0( OperationID Object_IDNameScopeType ReturnArray StereotypeIsStatic ConcurrencyNotes BehaviourAbstract GenOption SynchronizedPosConstStylePureThrows ClassifierCodeIsRootIsLeafIsQuery StateFlagsea_guidStyleEx0(0(0 ,-(0(0 ,.(0(0,/(0(0(01 Name Object_ID OperationID PrimaryKey ,, ,, ,,, , , , {qg]SI?5@ @@+fpwfu"           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+=+o{+VCSN 33     &    0(        2  pe2  p OperationIDNameTypeDefaultNotesPosConstStyleKind Classifierea_guidStyleEx(0(034(0(0350(0(36  OperationIDParam PrimaryKey33 337 {qg]S@ 2PP          !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2PP2suoXPsuoXPVCAN88        OperationID PostConditionTypeNotese898:  OperationID PrimaryKey88{qg7           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7VC@N<<     2   OperationID PreConditionTypeNotes<=<>  OperationID PrimaryKey<<{qg@ ;           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;VCqN@@          ( PropertyID ElementIDPropertyVALUENOTESea_guid @A@B  ElementKey PrimaryKey@@{qg?R           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?RVC.N DD   ty       2(          2      2      2  (     ,  0 Package_IDName Parent_ID CreatedDate ModifiedDateNotesea_guidXMLPath IsControlled LastLoadDate LastSaveDateVersion ProtectedPkgOwner UMLVersionUseDTDLogXMLCodePath NamespaceTPos PackageFlags BatchSave BatchLoadtrAP itiDH eea diDeTDIenhBdoaaDJTLk_iTswDK IDX_GUID Package_IDParentID PrimaryKeyDDyKeyDDyKeyDDyKeyDD{qg] CǑǑǑǑǑǑǑǑǑǑǑǑǑǑ"/@` @` @nization! Statecharts{F663169F-AB8B-486c-8C80-D321521271FE}ffffffff@@5 _` ` @` @nization! Statecharts{F663169F-AB8B-486c-8C80-D321521271FE}ffffffff@@5 _` @` @nization! Statecharts{F663169F-AB8B-486c-8C80-D321521271FE}ffffffff@@5 _` @` @nization! Statecharts{F663169F-AB8B-486c-8C80-D321521271FE}ffffffff@@5 _` @` @nization! Statecharts{F663169F-AB8B-486c-8C80-D321521271FE}ffffffff@@5 _@@nization! Component Model{F7BFABE8-CCDD-4fc1-84EE-344E8F5B028B}@@nization! Component Model{F7BFABE8-CCDD-4fc1-84EE-344E8F5B028B}vvvvvvvvPD5  @@nization! User Interface{2A62409A-B7B0-49ef-94A0-27407C3C34FA}uuu @@nization! User Interface{2A62409A-B7B0-49ef-94A0-27407C3C34FA}uuuuu @@nization! User Interface{2A62409A-B7B0-49ef-94A0-27407C3C34FA}uuuu @@nization! User Interface{2A62409A-B7B0-49ef-94A0-27407C3C34FA}uuuuuuuuOC5   @.@@eotype  ObjectModel{06C9C958-C14A-41f4-89A9-6873CCED37A7}ffffffff@@5 _.@@eotype  HouseExampleModel{06C9C958-C14A-41f4-89A9-6873CCED37A7}llllllllFF5 _,@@HouseMetamodel{A1B83D59-CAE1-422c-BA5F-D3624D7156AD}iiiiiiiiCC5 _+,`@`@ProjVer EADiffViewsFRooms{F9D8C6E3-4DAD-4aa2-AD47-D0ABA4E93E08}````````::5 _UseCase  hronization! Views{B216CC15-6D9C-4c10-9015-96740F924D1C}````````::5 GLVAL &&SX=8;SY=5;EX=8;EY=5;EDGE=4;$LLB=;LLT=;LMT=;LMB=;LRT=CX=43:CY=15:OX=0:OY=0:HDN=0:BLD=0EDGE=1;$LLB=;LLT=;LMT=;LMB=CX=77:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LRT=;LRB=;EDGE=4;$LLB=;LLT=;LMT=;LMB=;LRT=CX=43:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LRB=CX=26:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;EX=37;EY=3;EDGE=1;$LLB=;LLT=;LMT=;LMB=;LRT=;LRB=;EDGE=1;$LLB=;LLT=;LMT=;LMB=;LRT=;LRB=;SX=8;SY=5;EX=8;EY=5;EDGE=3;$LLB=;LLT=;LMT=;LMB=;LRT=CX=61:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LRB=CX=16:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;SX=-24;SY=-16;EDGE=4;$LLB=;LLT=;LMT=;LMB=;LRT=;LRB=;\¬   QQ>PnRDSource -> DestinationDependencyPublicPublicUnspecifiedUnspecifiedimplementsimplements0{9613E9DD-8709-4e9e-92D8-2F6CA9835851}ӭzzztttjjUU5 QOGdiagSource -> DestinationAggregationStrongPublicPublicUnspecifiedUnspecified0SX=36;SY=-9;EX=45;EY=-9;{FF2ECD20-22FF-4734-9DB4-8316A98DDC16}roomܶ{{ujjUU5 QNGdiagUnspecifiedAssociationPublicPublicUnspecifiedUnspecified0{AFD66AB6-337B-49c5-9FA9-0CFAFEB77AA7}homewwwwwqqqkkk``UU5 QMGdiagSource -> DestinationAggregationStrongPublicPublicUnspecifiedUnspecified0{9DDBD985-D9D5-408c-A8F4-40085F2E8E5B}roomĞ{{ujjUU5 QHGdiagSource -> DestinationAggregationStrongPublicPublicUnspecifiedUnspecified0{3F0E9949-A749-4958-9A1B-40E3F0E12393}roomĞ{{ujjUU5 QLGRDSource -> DestinationAggregationStrongPublicPublicUnspecifiedUnspecified0{D775B2C1-C7AF-4a19-A4D5-7B3AC816664C}roomĞ{{ujjUU5 XC.V\b_b_[^bWZ`ZWgZ^_`_\^]YbbfdY]`]0E.`Wa^Yd[_b`fWZXXba`[gdY\XZd]W[\`d0E.aXW\bbW[\d_bZbWV_VW[_\]ZVg_XZdWb0E.g_d^b\fYZd`dZ``X`dZ]dV`a`Zf_YfV^0E.g_d^b\fYZd`dZ``X`dZ]dV`a`Zf_YfV^0E.ffgXXg``ZfZZZY`^_^bV_dbVg^[\W\Wf0E.ffgXXg``ZfZZZY`^_^bV_dbVg^[\W\Wf0E.gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E .gg_d[aWgb[_aZda\`[bgZ\XV`\d`b_a]0E CE+E,E.E.E*G*G*G*G*G*G*G*G*G*G*G*G*G*G*GseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n CEEE,E,E G G G G G G G G G G G G G G GCE+E,E.E.E*G*G*G*G*G*G*G*G*G*G*G*G*G*G*GVCwNMM      PaletteIDNameType{VCbNOO   PaletteIDItemID @ @ @ @           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C${VCNQQ 2  2Datatype DescriptioneQS  PrimaryKeya{qZPr@ @@  @@@@@@tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfvw,ofwirdw,ofwujbw}sfvw,rakfbww,rakfbwbrpvwu`jpww,rakfbwfggruww,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$ `bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfdxmlXML Data stringcharacter stringlonglong numberintinteger doubledouble charcharacterbooleantrue/falseP @arrmf`pRbi`uRdrxamfRjpwRmrphRvwujphR|omR    IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n VC@NUU        ProblemType Description NumericWeightNotes<=UW<>UX  NumericWeight PrimaryKey{q@@Tn>@ @@  @@@@@tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfvw,ofwirdw,ofwujbw}sfvw,rakfbww,rakfbwbrpvwu`jpww,rakfbwfggruww,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$ w,sujojwjzfv$ `bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd?UserUser caused problemProblems caused by user7 @SWSoftwareSoftware related issues* ?PerformPerformancePerformance related problems7 ?NetworkNetwork problemsNetwork issues.  ?HWHardware related T VVVVV     IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n T i{Vpfw{rulVsfugruoVv{VxvfuVVC NZZ      P(Role DescriptionNotessP(Z]  PrimaryKeyZZS{qg  Y _8|Q%@ @@  @@@@@tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfvw,ofwirdw,ofwujbw}sfvw,rakfbww,rakfbwbrpvwu`jpww,rakfbwfggruww,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$VB ProgrammerVisual Basic Programming&&Use Case ModellerUse Case modelling %%Solution ArchitectLead Technical and Project Architect/@\C7Project ManagerManage scheduleManage the project schedule GJava ProgrammerJava programming DeveloperApplication development!! C++ ProgrammerProgramming in Visual C++((Business AnalystModel business processes))Application AnalystDefine and model the application structure>>LVALDefine and communicate application architectureJY@`ssmjb`wjrp`p`m}vw[axvjpfvv`p`m}vw[bsurhu`oofu[dfzfmrsfu[k`z`surhu`oofu[surkfbwo`p`hfu[vrmxwjrp`ubijwfbw[xvfb`vfordfmmfu[zasurhu`oofu[ ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n VCN__  2  2  P(Property DescriptionNotes_a  PrimaryKey__S{qg~^@ @@  @@@@@tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfvw,ofwirdw,ofwujbw}sfvw,rakfbww,rakfbwbrpvwu`jpww,rakfbwfggruww,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$ w,sujojwjzfv$ w,suramfow}sfv$ w,surkfbwurmfv$ `bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd SoftwareSoftware component RolePerson role Used in entities-DatafieldDatabase field ^d`w`gjfmd`urmf`vrgw{`uf`        IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n VC@Ncc   2    Requirement Description NumericWeightNotes<=ce<>cf  NumericWeight PrimaryKey{q@ bT_-@ @@  @@@@@  tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfvw,ofwirdw,ofwujbw}sfvw,rakfbww,rakfbwbrpvwu`jpww,rakfbwfggruww,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakf?ValidateValidate a particular ruleThe system will validate a specific rule as supplied n the business requirements{+ ?TestingTesting requirementTesting requirement6# ?ReportThe system will roduce a reportThe system will have the facility to produce a report as requiredo. ?PrintingSystem printing requirementThe system will allow the user(s) to print out some artifact as required by the specification. , ?PerformancePerformance based requirementThe system must meet some erformance criteria^1 ?FunctionalFunctional RequirementComments here6) ?DisplaySystem will display in a specified formatInformation will be displayed in a particular wayj9 b @ddddddd  IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n b @ djvsm`}dgxpbwjrp`mdsfugruo`pbfdsujpwjphdufsruwdwfvwjphdz`mjd`wfdVCZN hh      2  2  2  2      Name OrganisationPhone1Phone2MobileFaxEmailRolesNotesphi  PrimaryKeya{qg           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$VC9Nkk   2   Risk Description NumericWeightNoteseklkm  NumericWeight PrimaryKey{q j           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$jVCNoo   d  '2    ' ConnectorID Constraint ConnectorEndConstraintTypeNotesopoqor ObjectConstraintConstraintObjectID PrimaryKeyooE{qg]n           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$nnVCiNtt 2  TypeTemplatett{q@@XLVAL q%)Zt@ @@  @\pard \fi-360\li1080\widctlpar\jclisttab\tx1080{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls1\adjustright {#TEXT# \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}{\i\b #TYPE# Description \par } { #NOTE#}{\par }\trowd \trgaph108\trleft-108\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx2844\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb \brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx5796\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx8748\pard\plain \widctlpar\intbl\adjustright \fs20\cgrid {Method\cell Type \cell Notes\cell } \pard \widctlpar\intbl\adjustright {\row }\pard \fi-360\li1080\nowidctlpar\jclisttab\tx1080{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls3\adjustright {#TEXT# \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}{\i Type:}{\tab\tab #TYPE# \par \i Status:} {\tab \tab #STATUS# \par \i Package:}{\tab #PACKAGE#\par \i Details:} {\tab\tab #DETAILS#} {\par\par #NOTE#}{\par }{\field{\*\fldinst { INCLUDEPICTURE "Images\\\\#PICTURE#" \\* MERGEFORMAT \\d }}{\fldrslt {\lang1024 }}}{ \par }\pard\plain \s15\sb120\sa120#INDENT#\widctlpar\adjustright \b\fs20\cgrid {Figure }{\field\flddirty{\*\fldinst { SEQ Figure \\* ARABIC }}{\fldrslt {\lang1024 1}}}{ : #FIGURE# \par }\pard\plain \s2\sb240\sa60\keepn\widctlpar\outlinelevel1\adjustright \b\i\f1\cgrid {#TEXT# \par} \pard\plain \widctlpar\adjustright \fs20\cgrid {\par}\pard\plain \s3\sb240\sa60\keepn\widctlpar\outlinelevel2\adjustright \f1\ul\cgrid {#TEXT# \par} \pard\plain \widctlpar\adjustright \fs20\cgridasv\A eG,H2_New@zDocHeader[} H1@zNormal<@zDocHeader1 { TableEnd$@z BlankLine6@z AttributeHdr@y MethodRow@y Requires{#REQUIREMENT#. #NOTES# }/ ListItem2@u AttributeRow@y Object_old1@u Object {\i\b #TYPE#: }{ #NOTE#} {\par }3MethodHDR@u ListItem@u Object2@uGIFp@uFigure@uDocHeader2 w H2@uH3@uLVAL x{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} {\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;} {\f149\froman\fcharset238\fprq2 Times New Roman CE;}{\f150\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f152\froman\fcharset161\fprq2 Times New Roman Greek;}{\f153\froman\fcharset162\fprq2 Times New Roman Tur;} {\f154\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f155\fswiss\fcharset238\fprq2 Arial CE;}{\f156\fswiss\fcharset204\fprq2 Arial Cyr;}{\f158\fswiss\fcharset161\fprq2 Arial Greek;}{\f159\fswiss\fcharset162\fprq2 Arial Tur;} {\f160\fswiss\fcharset186\fprq2 Arial Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128; \red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar\adjustright \fs20\cgrid \snext0 Normal;}{ \s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid \sbasedon0 \snext0 heading 1;}{\s2\sb240\sa60\keepn\widctlpar\adjustright \b\i\f1\cgrid \sbasedon0 \snext0 heading 2;}{\s3\sb240\sa60\keepn\widctlpar\adjustright \f1\ul\cgrid \sbasedon0 \snext0 heading 3;}{\s15\sb120\sa120\widctlpar\adjustright \b\fs20\cgrid \sbasedon0 \snext0 caption;}{\*\cs10 \additive Default Paragraph Font;}} {\*\listtable{\list\listtemplateid67698689\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360 \jclisttab\tx360 }{\listname ;}\listid1869176857}}{\*\listoverridetable{\listoverride\listid1869176857\listoverridecount0\ls1}} {\info{\author gsparks}{\operator gsparks}{\creatim\yr2000\mo3\dy29\hr21\minFLVALR45}{\revtim\yr2000\mo3\dy29\hr22\min14}{\version11}{\edmins2}{\nofpages1}{\nofwords0}{\nofchars0} {\*\company Sparx Systems}{\nofcharsws0}{\vern113}} \margl1080\margr1080\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade\viewkind4\viewscale100\pgbrdrhead\pgbrdrfoot \fet0\sectd \linex0\headery709\footery709\colsx709\endnhere\sectdefaultcl {\*\pnseclvl1 \pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 \pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}$LVALi4\trowd \trgaph108\trleft-108\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx2844\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb \brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx5796\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx8748\pard\plain \widctlpar\intbl\adjustright \fs20\cgrid {Attribute\cell Type \cell Notes\cell } \pard \widctlpar\intbl\adjustright {\row }\trowd \trgaph108\trleft-108\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \clvertalt\clbrdrt \brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx2844\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx5796\clvertalt\clbrdrt \brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx8748\pard \widctlpar\intbl\adjustright { #METHOD# \cell #TYPE# \cell #SCOPE# \cell }\pard \widctlpar\intbl\adjustright {\row }\trowd \trgaph108\trleft-108\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \clvertalt\clbrdrt \brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx2844\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx5796\clvertalt\clbrdrt \brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb \cellx8748\pard \widctlpar\intbl\adjustright { #ATTRIBUTE# \cell #TYPE# \cell #NOTES# \cell }\pard \widctlpar\intbl\adjustright {\row }LVALj'\pard\plain \s2\sb240\sa60\keepn\widctlpar\outlinelevel1\adjustright \b\i\f47\fs28\cf9\cgrid{#TEXT# \par} \pard\plain \widctlpar\adjustright \fs20\cgrid {\par}\pard\plain \s1\sb240\sa60\keepn\widctlpar\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid{#TEXT#\par } \pard\plain \widctlpar\adjustright \fs20\cgrid {\par}\pard\plain \widctlpar\adjustright \fs20\cgrid {#TEXT# \par}\pard \widctlpar\adjustright {\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\par }LVAL |{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} {\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;} {\f149\froman\fcharset238\fprq2 Times New Roman CE;}{\f150\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f152\froman\fcharset161\fprq2 Times New Roman Greek;}{\f153\froman\fcharset162\fprq2 Times New Roman Tur;} {\f154\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f155\fswiss\fcharset238\fprq2 Arial CE;}{\f156\fswiss\fcharset204\fprq2 Arial Cyr;}{\f158\fswiss\fcharset161\fprq2 Arial Greek;}{\f159\fswiss\fcharset162\fprq2 Arial Tur;} {\f160\fswiss\fcharset186\fprq2 Arial Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128; \red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar\adjustright \fs20\cgrid \snext0 Normal;}{ \s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid \sbasedon0 \snext0 heading 1;}{\s2\sb240\sa60\keepn\widctlpar\adjustright \b\i\f1\cgrid \sbasedon0 \snext0 heading 2;}{\s3\sb240\sa60\keepn\widctlpar\adjustright \f1\cgrid \sbasedon0 \snext0 heading 3;}{\s15\sb120\sa120\widctlpar\adjustright \b\fs20\cgrid \sbasedon0 \snext0 caption;}{\*\cs10 \additive Default Paragraph Font;}} {\*\listtable{\list\listtemplateid67698689 \listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid1114859770}{\list\listtemplateid67698699\listsimple {\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3880 ?;}{\levelnumLVALbers;}\f14\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid1693338663}{\list\listtemplateid67698689\listsimple{\listlevel \levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid1869176857}}{\*\listoverridetable{\listoverride\listid1869176857 \listoverridecount0\ls1}{\listoverride\listid1693338663\listoverridecount0\ls2}{\listoverride\listid1114859770\listoverridecount0\ls3}} {\info{\author gsparks}{\operator gsparks}{\creatim\yr2000\mo3\dy29\hr21\min45}{\revtim\yr2000\mo3\dy29\hr22\min14}{\version11}{\edmins2}{\nofpages1}{\nofwords0}{\nofchars0} {\*\company Sparx Systems}{\nofcharsws0}{\vern113}}\margl1080\margr1080\widowctrl\ftnbj\aenddoc\hyphcaps0\formshade\viewkind4\viewscale100\pgbrdrhead\pgbrdrfoot \fet0\sectd \linex0\headery709\footery709\colsx709\endnhere\sectdefaultcl {\*\pnseclvl1 \pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 \pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}LVAL ~{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} {\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f47\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Arial Bold Italic;}{\f125\froman\fcharset238\fprq2 Times New Roman CE;}{\f126\froman\fcharset204\fprq2 Times New Roman Cyr;} {\f128\froman\fcharset161\fprq2 Times New Roman Greek;}{\f129\froman\fcharset162\fprq2 Times New Roman Tur;}{\f130\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f131\fswiss\fcharset238\fprq2 Arial CE;}{\f132\fswiss\fcharset204\fprq2 Arial Cyr;} {\f134\fswiss\fcharset161\fprq2 Arial Greek;}{\f135\fswiss\fcharset162\fprq2 Arial Tur;}{\f136\fswiss\fcharset186\fprq2 Arial Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255; \red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;} {\stylesheet{\widctlpar\adjustright \fs20\cgrid \snext0 Normal;}{\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid \sbasedon0 \snext0 heading 1;}{\s2\sb240\sa60\keepn\widctlpar\adjustright \b\i\f47\fs28\cf9\cgrid \sbasedon0 \snext0 heading 2;}{\s3\sb240\sa60\keepn\widctlpar\adjustright \f1\cgrid \sbasedon0 \snext0 heading 3;}{\*\cs10 \additive Default Paragraph Font;}{\s15\sb120\sa120\widctlpar\adjustright \b\fs20\cgrid \sbasedon0 \snext0 caption;}}{\*\listtable {\list\listtemplateid67698689\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid1114859770} {\list\listtemplateid67698699\listsimple{\listlevel\levelnfc23\leveljc0\leveLVALlfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3880 ?;}{\levelnumbers;}\f0\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid1693338663} {\list\listtemplateid67698689\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid1869176857}} {\*\listoverridetable{\listoverride\listid1869176857\listoverridecount0\ls1}{\listoverride\listid1693338663\listoverridecount0\ls2}{\listoverride\listid1114859770\listoverridecount0\ls3}}{\info{\title Class Model}{\author gsparks} {\operator Geoffrey Sparks}{\creatim\yr2000\mo9\dy29\hr16\min21}{\revtim\yr2000\mo9\dy29\hr16\min21}{\version2}{\edmins1}{\nofpages4}{\nofwords370}{\nofchars2110}{\*\company Sparx Systems}{\nofcharsws2591}{\vern113}}\margl1080\margr1080 \widowctrl\ftnbj\aenddoc\hyphcaps0\formshade\viewkind4\viewscale100\pgbrdrhead\pgbrdrfoot \fet0\sectd \linex0\headery709\footery709\colsx709\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 \pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6 \pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}VC N                                      Ro TemplateID RootPackageFilenameDetailsProcessChildren ShowDiagramsHeading Requirements Associations Scenarios ChildDiagrams AttributesMethods ImageTypePagingIntro Resources ConstraintsTaggedShowTag ShowAliasPDATA1PDATA2PDATA3PDATA4(?( ?(?(? PrimaryKey RTFReportID{qg]  LVALn) @ @ @ @ @ @ @ @ @ @ @ @ @ @ @The Dynamic Model provides a view of business processes that impact the proposed system. It shows how actors carry out high level business tasks to meet business demands. Business processes that will be performed by the proposed system will be ultimately implemented by the Use Cases detailed in the Use Case model.The DRP model provides an overview of the proposed Disaster Recovery Procedures for the FMS application. The Development Environment model provides a detailed view of the various hardware and software components that are involved in the development of the application. It shows both where these components reside and how they inter-relate with other components. Component requirements detail what responsibilities a component has to supply functionality or behaviour within the system. The Deployment View provides a detailed model of the way components will be deployed across the system infrastructure. It details network capabilities, server specifications, hardware requirements and other information related to deploying the proposed system.The component model provides a detailed view of the various hardware and software components that make up the proposed system. It shows both where these components reside and how they inter-relate with other components. Component requirements detail what responsibilities a component has to supply functionality or behaviour within the system. The logical model is made up of the Domain Model - a high level model of business objects and relationships between objects suitable for analysing the business process, and the class model - a rigorous model of classes and their inter-relationships, suitable for building a software product.The system architecture model defines the overall hardware/software architecture used to implement the system.  X?f Use Case ModelC:\TEMP\Use Case Model.RTFUse Case Model@KKKKK?1 Release ManagementC:\Temp\ReleaseMan.RTFRelease Management@OOOOOC1 InterviewsD:\vblocal\projects\FMS\docs\interviews.RTFInterviewsHHHHHH> Dynamic ModelC:\Temp\DM.RTFDynamic Model;@=====1$ DRPC:\temp\DRP.RTFDRPj@***** Development ProductsC:\Temp\DevelopProducts.RTFDevelopment Environment~@[[[[[O8 DeploymentC:\Temp\Deployment.RTFDeployment Architecture@LLLLL@) Component ModelC:\Temp\Component.RTFComponent ModelY@HHHHH<- Class ModelC:\Temp\ClassModel.RTFClass Model#@AAAAA5* Architecture ModelC:\TEMP\Architecture.RTFArchitectureo@KKKKK?3 LVALTThe Use Case Model describes the proposed functionality of the new system. A Use Case represents a discrete unit of interaction between a user (human or machine) and the system. A Use Case is a single unit of meaningful work; for example creating a train, modifying a train and creating orders are all Use Cases. Each Use Case has a description which describes the functionality that will be built in the proposed system. A Use Case may 'include' another Use Case's functionality or 'extend' another Use Case with its own behaviour. Use Cases are typically related to 'actors'. An actor is a human or machine entity that interacts with the system to perform meaningful work.The Release Management model provides a detailed view of the various hardware and software components that are involved in the management of software versions released into the proposed production environment. It shows both where these components reside and how they inter-relate with other components. Component requirements detail what responsibilities a component has to supply functionality or behaviour within the system. H@@`ubijwfbwxufordfmbm`vvordfmbrosrpfpwordfmdfsmr}ofpwdfzfmrsofpwsurdxbwvdusd}p`ojbordfmjpwfuzjf{vufmf`vfo`p`hfofpwxvfb`vfordfm oreignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n H@@`ubijwfbwxufordfmbm`vvordfmbrosrpfpwordfmdfsmr}ofpwdfzfmrsofpwsurdxbwvdusd}p`ojbordfmjpwfuzjf{vufmf`vfo`p`hfofpwxvfb`vfordfm VCN    2    ri         c  RuleIDRuleNameRuleType RuleActiveErrorMsgFlagsRuleOCLNotesRuleXML(  PrimaryKey7 {qg]S           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$VCAN   2    ScenarioType Description NumericWeightNotesklkm  NumericWeight PrimaryKey{q E@ @@  @@@@@  @@tdg,vjosmfrakfbw2uswtu}rakfbwprwfv2uswxvfb`vfprwfv2uswxvfb`vfv2uswxvfb`vfva}`bwru2w,`wwujaxwf2w,`wwujaxwfbrpvwu`jpwv2w,`wwujaxwfw`h2w,`xwiruv2w,b`udjp`mjw}2w,b`wfhru}2w,bmjfpwv2w,brosmf|jw}w}sfv2w,brppfbwru2w,brppfbwrubrpvwu`jpw2w,brppfbwruw`h2w,brppfbwruw}sfv2w,brpvw`pwv2w,brpvwu`jpww}sfvw,d`w`w}sfvw,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfv w,hfprsw w,hmrvv`u} w,iwom w,jo`hf w,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfvw,ofwirdw,ofwujbw}sfvw,rakfbww,rakfbwbrpvwu`jpww,rakfbwfggruww,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$ w,sujojwjzfv$ w,suramfow}sfv$ w,surkfbwurmfv$ w,sursfuw}w}sfv$ w,uftxjufw}sfv$w,ufvrxubfv$w,ujvlw}sfv$?SimpleStandard scenarioUsed to describe ordinary usage?  ?Basic PathBasic execution pathThe standard execution path with no exceptionsU' ?AlternateAlternate pathwayPath of execution that includes exceptional conditions.Z#          IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n `mwfup`wfa`vjbs`wivjosmfVC8N   d   '     '  ScriptIDScriptCategory ScriptName ScriptAuthorNotesScript  PrimaryKeyE{qg]           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$VCN  (    P(dGroupID GroupName Description  PrimaryKeya{q           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$VCN  ( GroupID PermissionID  PrimaryKeya{q@           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$VCN  (  (   '  (   UserIDGroupID EntityTypeEntityID TimestampLockTypep  PrimaryKeya{qd  @@@ w,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$ w,si`vf>w,sujojwjzfv$ w,suramfow}sfv$ w,surkfbwurmfv$ w,sursfuw}w}sfv$ w,uftxjufw}sfv$w,ufvrxubfv$w,ujvlw}sfv$w,urmfbrpvwu`jpw$w,uwg$w,uwgufsruw$w,uxmfv$w,vbfp`ujrw}sfv$w,vbujsw$w,vfbhurxs$w,vfbhurxssfuojvvjrp$w,vfbmrblv$w,vfbsfuojvvjrp$w,vfbsrmjbjfv$w,vfbxvfu$w,vfbxvfuhurxs$ojvvjrp$w,vw`wxvw}sfv$w,vwfufrw}sfv$ w,w`vlvw,wbgw,wfosm`wfw,wfvwbm`vvw,wfvwsm`pvw,wfvww}sfvw,wu|w}sfvw,xoms`wwfupw,zfuvjrpw,|ufg w,|ufgv}vwfo w,|ufgxvfu xv}v,v}vwfo xv}vrmdw`amfv xv}vtxfujfvxv}vw`amfv~~,t,josmfofpwvX~~,t,rusi`pv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd.Wf\XdY`^gYbgZfX`aV`V`]X\\b_^b]da0.XaYbaa\\`WdfZZba_Wfgg`]X_Yg[d^`b0.ZX^Zb]_W`^W_ZZb^aV`dZWabbd[YYf\`0.[Vfg[`VWg^X^ZX`Vaa\^`\Y_`V`d`dY^0.^Z_g`W\bg]VZZXbZ^Wd[]WZV_YX^X`[d0.^f_X^VVW\gWaZ^^d^fd\V_\`^YafgbXX0.d]Z^bgYgbd^dZ`YXaf\aX``Wb[gWXWfX0s`bl`hfdj`hu`o VCN   2 PermissionIDPermissionName  PrimaryKey           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$a{q            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$VCN  d  PropertyValuesnm  PrimaryKeya{q           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$ VCN  (     '2  2  2   UserID UserLogin FirstNameSurname DepartmentPassword  PrimaryKeya{q           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$VCN  (  (UserIDGroupIDnm  PrimaryKeya{q@           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$VCN  ( UserID PermissionID  PrimaryKeya{q           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$VCdN 2  2Status Description{Wk\$u8F _){8MBZ}S@BZ}S@t_statustypes,,,,,,,,,,, BZ}S@BZ}S@t_secuserpermission22222222222 BZ}S@BZ}S@t_secusergroup----------- BZ}S@BZ}S@t_secuser((((((((((( BZ}S@BZ}S@t_secpolicies,,,,,,,,,,, BZ}S@BZ}S@t_secpermission........... BZ}S@BZ}S@t_seclocks))))))))))) BZ}S@BZ}S@t_secgrouppermission33333333333 PY}S@BZ}S@t_secgroup))))))))))) {Y}S@{Y}S@t_script''''''''''' {Y}S@{Y}S@t_scenariotypes........... {Y}S@{Y}S@t_rules&&&&&&&&&&& {Y}S@{Y}S@t_rtfreport*********** s{Y}S@{Y}S@t_rtf$$$$$$$$$$$ n{Y}S@{Y}S@t_roleconstraint/////////// jY}S@Y}S@t_risktypes*********** gY}S@Y}S@t_resources*********** bY}S@Y}S@t_requiretypes----------- ^Y}S@Y}S@t_propertytypes........... YY}S@Y}S@t_projectroles----------- TY}S@Y}S@t_problemtypes----------- PY}S@Y}S@t_primitives+++++++++++ NY}S@Y}S@t_paletteitem,,,,,,,,,,, LY}S@Y}S@t_palette((((((((((( CY}S@Y}S@t_package((((((((((( ?Y}S@Y}S@t_operationtag----------- ;Y}S@Y}S@t_operationpres........... 7Y}S@Y}S@t_operationposts/////////// 2Y}S@Y}S@t_operationparams00000000000 +Y}S@ImplementedFinished ValidatedApproved and Checked MandatoryRequired ApprovedItem is approved ProposedItem has been proposed VCwN  tw  b    g   k    n  2  d Stereotype AppliesTo Description MFEnabledMFPathMetafileStyleea_guid VisualType  PrimaryKeyE{qg] ?`}`Ys entityclassSpecifies a persistent element mainly concerned with managing its own state{B0B3F17A-BBEC-486a-A23E-468443A382F8}}}WWWW  controlclassSpecifies an element that controls the work and lifetimes of other objects{C1D3CDAA-9CF7-4e50-BBF9-305B041F9166}}}WWWW  clientscriptclassA collection of client-side scripts{BE5A8101-8017-4ba1-B32A-F21743C5748C}[[5555  client pageclassA class that represents a client based web page{EB561CD3-CD1D-44a2-98C0-32D4C2CA66E4}ff@@@@  boundaryclassSpecifies an element that is at the system boundary (eg. User Interface){5B299B21-E192-470d-8A00-4B179E0CAEB4}||VVVV  asp pageclassA microsoft active server page{0050D802-CC75-46b6-BE08-6AA35963D637}RR,,,,  work unitbusiness modelSubsystem with one or more entities{9D88DFA1-77C5-4ac4-89B6-AC9C3355F3AC}aa;;;;  organization unitbusiness modelSubsystem corresponding to an organizational unit of the actual business{7792B6AF-F382-41a9-A85A-C1ECF5AA4065}hhhh  object systembusiness modelContains business process objects, work units, organization units and relationships{74ABCB31-E01E-4700-BE74-D2C3DA4FC003}oooo workerbusiness classAn abstraction of a human that works within the system.{0554773B-12D5-4dae-B6BA-107351585EE4}rrLLLL internal workerbusiness classA worker that interacts with other workers and entities inside the system.{CF506705-0744-47e2-A100-0835D23C2AED}hhhh entitybusiness classPassive class accessed and manipulated by workers{A0118F54-FEED-4559-A444-BCD03E7D2D3F}llFFFF case workerbusiness classA worker who directly interacts with actors outside the system{25A76B9A-1151-43a5-9367-47CA52B1B6CC}~~XXXX  columnAttribTableA column attribute for a table{8FC0C414-E35D-48cf-A040-80BD687CBBAC}VV0000 subscribeassociationSource class will be notified when an event occurs in target{87A68C11-B758-4a24-8E27-3D7D1288DC05}wwQQQQ r3mb&?i~  threadclassA classifier whose instances represent a lightweight flow of control{3018C73A-0E89-44ac-A2F6-9ADED2D23285}vvPPPP  targetclassA class that represents a target{67F0C431-A00D-4527-A1F0-58D06F3B9426}RR,,,,  tableclassA class that represents a database table{887C800A-2CF5-406b-92A1-C126D02E9AAC}YY3333  stereotypeclassThe classifier is a stereotype that may be applied to other elements{35C40A6D-AD3A-467a-AB09-0D10C6FC06A3}zzTTTT  signalclassSpecifies an asynchronous stimulus communicated amongst instances{0D9E36E5-D341-4df1-ABB6-99A7B4AC54A3}ssMMMM  servletclassA java servlet component{E457EC8F-707F-457a-B938-DF02AF1AFD9E}KK%%%%  server pageclassA class that represents a server based web page{AA3C9E47-976D-4e8c-98CE-2B0B5A40D914}ff@@@@  script libraryclassA library ofsubroutines/functions for web pages{3B5AEF7D-F3A1-4377-9C56-8DDC8869CC8E}iiCCCC processclassA classifier whose instances represent a flow{B09D6F36-3092-40ab-8488-250B25BC7487}``::::  powertypeclassA classifier whose objects are all children of a given parent{A12DC7CD-CD71-4bc6-A72F-5495707C5F55}rrLLLL  jsp pageclassA java server page{6D5C46B2-BCFA-473e-A710-752DAB58BD25}FF   interfaceclassA collection of operations that specify a service of a class or component{8A0CBEB1-C8CB-4dc6-AEF7-9C728494D71B}~~XXXX  implementationClassclassImplementation of a class in some programming language{D21B65A5-D643-4448-969C-0FCF871003FD}uuOOOO framesetclassA class that represents a html frameset{46966B01-3488-4d25-BE9C-6FE3288AB643}[[5555  formclassA class that represents a html form{015767F4-001D-40be-B4D7-DEC5D0C1C612}SS----  exceptionclassAn event may be thrown or caught by operation{6CC47D9A-DB3A-48d8-8614-E33769001850}bb<<<<  enumerationclassSpecifies an enumerated type{BBDB4429-65FB-45e8-93E1-EE175B273D86}SS---- $p6:h"(%P calldependencySource invokes the target{450E0642-D103-4bbf-A765-590F0C30A26C}NN(((( binddependencySource instantiates target template using given parameters{AB633B10-8337-491e-BC44-CDE3C1BE5E77}ooIIII accessdependencyPublic contents of target are accessible to namespace of source{667F2AE0-ABDC-4b9d-AC72-3D9B97C176F7}vvPPPP preconditionconstraintA constraint that must hold before an element is invoked{112125B9-D901-4710-93B9-8DB6EB6F55EB}uuOOOO  postconditionconstraintA constraint must hold after the invocation of an element{A345D106-5C18-4b45-9643-C4C0A9D942C3}wwQQQQ invariantconstraintConstrain must always hold for associated element{D59F428C-DAD4-404f-AFA9-099B00D158E3}kkEEEE  tablecomponentA component that represents a database table{BE6BC1BF-7BEF-41da-8FD0-01D2177AA2B5}aa;;;; librarycomponentStatic or dynamic object library{879A9EF4-C3E3-4f76-B36E-2909E2B49A48}WW1111 filecomponentComponent represents a document containing source code{89D9F1DF-5FBC-4c00-9CAE-83D8ECE73C23}jjDDDD executablecomponentA component may be executed on a node{ABDC9952-B6AC-4beb-AD76-5557C6342A59}__9999  documentcomponentThe component represents a document{A7740FEF-AC1F-494a-ACA7-3A92083C6906}[[5555  responsibilitycommentSpecifies a contract by or an obligation of a class{049EA182-D4E6-4b7e-86EA-231638C35DE6}ooIIII requirementcommentSpecifies a desired feature, property or behaviour of system{4A0B325B-A5CF-4688-B397-A03972222A92}uuOOOO  metaclassclassifierA classifier whose objects are all classes{1CC4B777-25D8-4f94-8AA0-AD96560F8CCB}dd>>>>  web pageclassA html web page{16795158-864A-447c-806B-D9BB43547830}CC  utilityclassA class whose attributes and operations are all class-scoped{792813BD-82DE-4158-BCF5-A7911E938F80}ooIIII  typeclassAn abstract class specifying the structure but not implmentation of a set of objects{43D9B75C-9F6A-4654-AF05-C745B99D2436}^^^^ ,8*LYh UL formGUIElementA GUI screen{5AE27742-0F6C-4a0e-AF6A-109978FC2C3A}AA dropdownGUIElementA GUI element that forces user selection{D648D453-7E0D-4678-A5E5-A6BB1C192434}aa;;;;  dialogGUIElementA GUI screen{3CE69469-9BC4-49c8-A24A-560BA15CDB68}CC dateGUIElementA GUI element for date entry{13DBECC3-2E3C-4e1d-A35C-E9E17A5DB316}QQ++++ comboboxGUIElementA combobox GUI element{BA39BF7E-A756-4f2f-84F5-6668B0AC968F}OO))))  checkboxGUIElementA checkbox GUI element{8BCECA84-0AB2-4a99-B490-2B58C693C86E}OO))))  buttonGUIElementA button GUI element{CE56158E-4ECB-4ae5-9ED7-F10BBA5F2E43}KK%%%% implementationgeneralizationChild inherits implementation of parent but does not support its interfaces{D3286FFA-5439-4f48-B816-FB662B67A59B}hhhh usedependencyThe semantics of the source depend on the public part of the target{8F76FA58-C62F-4c57-86D6-A10B6DF95D78}wwQQQQ tracedependencyThe target is an historical ancestor of source{D1E8AF8A-5BB4-4708-812B-C965872E4CBC}dd>>>> senddependencyThe source sends the target an event{99D8D851-47E3-42dc-9F7E-B197E11D1DCD}YY3333 refinedependencySource is at a finer degree of abstraction than source{235277D9-F2F1-497d-A0DF-BBA9BC8C84A7}mmGGGG powertypedependencyA classifier whose objects are all children of a given parent{AE32C1ED-A942-464a-90CF-27A368B466C1}wwQQQQ  instantiatedependencyOperations on the source class create instances of the target class{43D85F8A-F3A4-4497-A990-FA9A6B2C0397}YYYY  instanceOfdependencyThe source object is an instance of the target{7328C624-9F43-46f2-ABA3-2ED5F9E4AA8D}iiCCCC  importdependencyPublic contents of target are imported into source namespace{18A56F14-6392-4e01-BAAA-FDBEE5F316A3}ssMMMM frienddependencySource is given special visibility of target{DB9D189A-260D-4e03-B3B7-795C36E1C4B0}cc==== derivedependencySource may be computed from target{E3666EE3-D8C4-4c71-A02A-D1A5CC90AB45}YY3333:MR -\h analysis systemmodelContains analysis classes - entities, boundaries and control elements{4BD26565-AE89-4e1c-B67B-CC996F70EF7D}ZZZZ destroymessageTarget is destroyed by event or message{278990B3-3173-45dc-8B73-011B066507D9}\\6666 createmessageTarget is created by event or message{D445B2C5-746B-444e-A3F6-5D1539CDB6D9}YY3333 copymessageTarget is exact but independent copy of source{EBAD9054-BD6A-4813-806C-C498882A3A0F}``::::  becomemessageTarget is same as source but later in time{AE2887BF-2A06-4b44-A96C-0F3DA8747308}^^8888 selflink endThe corresponding object is visible because it is the dispatcher{36F0B3D7-5C4F-455f-B659-1E37BE3EF94C}ssMMMM  parameterlink endThe corresponding element is visible because it is a parameter{65FADACF-BA12-424e-8DBF-340075C596C5}vvPPPP  locallink endThe corresponding object is visible in local scope{36E6EE9B-F4AC-40fc-A256-8C25E3128681}ff@@@@ globallink endCorresponding object is visible because of enclosing scope{94BDAA38-C0E7-4d86-867C-7CF815034D8D}ooIIII treelistGUIElementA List of Information with a tree structure{99AE9A68-9B98-48d9-B873-A2632B1B0084}dd>>>>  timeGUIElementA GUI element for time entry{37B2CA08-252D-4131-9DD8-7926D815CC42}QQ++++ textboxGUIElementA GUI element for user text entry{EE384EC6-2C73-43a6-BA3E-B9204CB920D4}YY3333 tabGUIElementA tab control GUI element{ED02F4C5-8473-4639-AB8C-0735FE1CC09D}MM'''' reportGUIElementA List of Information with an expandable text field{02146B0C-09B1-4d31-8D4E-EE300575F033}jjDDDD radioGUIElementA radio button GUI element{FB9993C0-A3AA-4415-BBCA-36E119EB6FEE}PP**** panelGUIElementA GUI element for grouping other controls{D2D62A7A-8EE3-4cc2-80F3-5BD9E526F8E3}__9999 listviewGUIElementA stand listview control{30C5DCFC-C9DB-4270-A202-EF3EF0321AC9}QQ++++  listGUIElementA List of Information{64D0F902-FFC0-4b87-9DCB-37280EFC14FC}JJ$$$$*={N6i S\ procOpTableA stored procedure{2821CBC2-DAE3-429b-A2CF-995619831E5F}DD  PKOpTableA Primary Key{D204501B-39AD-43a7-831A-596DEF03D76C}==  indexOpTableAn index of one or more columns{64D6DC4D-D86C-4d0b-A88F-C1CF48549A69}RR,,,,  FKOpTableA Foreign Key{52CB2E90-FC32-4930-99BA-A1EB4B63DF6A}==  checkOpTableA Check constraint to enforce domain integrity{FE1E0DAC-E2AE-4ef8-8BBC-63B600B2B54A}aa;;;;  user pcnodeA class that represents a users pc{F8E64DA9-1F56-4106-BD35-A48151C35376}TT....  unix servernodeA class that represents a unix server{7C44C016-C2BA-4223-8E9B-8D152246C3C7}[[5555  storagenodeA class that represents a storage device{96A367B8-2953-4ed1-8FBC-AAAC600203B6}ZZ4444  servernodeA class that represents a server{A8079F64-3BC2-4f92-B8E2-78B64E79DD94}QQ++++  securenodeA class that represents aet{8F990926-89CC-4c41-9B50-7E18C9F45B42}LL&&&&  pc servernodeA class that represents a pc server{76E75B3A-CD1A-4da1-B834-4957F093D304}WW1111  pc clientnodeA class that represents a clients pc{3022C5E6-5115-4c97-8AB6-F1EFDDFE6B16}XX2222  pcnodeA class that represents a personal computer{9EE8CEA7-7EB0-4707-A0B1-8655CDA95AB4}XX2222 disk arraynodeA class that represents a disk array{A61D54E8-744A-41ef-9FB2-269BB128B6D6}YY3333  computernodeA class that represents a computer{3F40FB60-89AD-47ad-AAE9-46C82B9DA61C}UU////  cdromnodeA class that represents a CDRom drive{4E32894A-3B07-4627-85D9-BB5A3A205935}UU////  cd-romnodeA class that represents a CDRom drive{D35E80FF-EF5C-44dc-A590-04FB8C37C5FF}VV0000  use case systemmodelSpecifies the services offered to the users{D5ADC3E3-AF22-4540-8E38-6EE3BCBB9833}ff@@@@ implementation systemmodelContains implmentation subsystems and/or components and relationships{31A9E50A-7720-4adc-AF7B-68136960B030}```` design systemmodelContains design elements{C2524AF1-8C8B-4a7f-A898-2553A83DC589}QQ++++7co o4] processactivityA classifier whose instances represent a flow{321DF02A-95C4-4473-A0FF-9C6D1B7C64EE}cc==== hlineGUIElementFill=-1;Border=-1;Font=-1;{116D042D-995D-4535-95AF-E1FA9E2F178E}\\6 vlineGUIElementFill=-1;Border=-1;Font=-1;{7EF7E943-594A-4b90-B0C8-D555889DC7E9}\\6 includeusesSource use case explicitly includes the behaviour of target{5CF75748-D6CE-4900-943F-2B05A5A6ECB7}mmGGGG  extendusesTarget use case extends the source at a given extension point{05EBA0FC-6BBD-4bb3-A1CD-66611F36ACC4}nnHHHH  communicateusesCommunication between actor and use case{C8E226A5-2C9C-47cd-BB50-E480CED73C36}^^8888  systempackageA package representing the entire system being modeled{54C8A4DE-A3A3-4d4c-943D-C53BE06C4D1C}jjDDDD subsystempackageA grouping of elements that constitute a specification of behaviour offered by other contained elements{4434DD3C-2D7A-4fb0-A929-D5845D8F0145}xxxx  stubpackageA package serves as a proxy for the public contents of another package{58FDAB08-211F-4dd5-84CD-32FFAACDF695}xxRRRR  modelpackageA semantically closed abstraction of a system{77B2EF0E-E813-41b1-AD21-057B36A19456}``::::  frameworkpackagePackage consists mainly of patterns{D6545C25-42C2-43c2-B4FC-29A463CB57B2}ZZ4444  facadepackagePackage is a view of another concrete package{240FB25A-CBA7-481a-8065-8E9F17B12A56}aa;;;; uniqueOpTableA Unique contraint to enforce the integrity of a database automatically{0939FC11-FDCB-488e-86C1-A2B291B8F382}{{UUUU triggerOpTableA trigger which executes automatically when an UPDATE, INSERT, or DELETE statement is issued{325B75A5-1EB0-4866-8F8D-651217DE7EC3}kkkk brosrpfpwdrbxofpwhxjfmfofpwwuffmjvwvbm`vvb`vf{rulfuaxvjpfvvbm`vvfpwjw}axvjpfvvbm`vvjpwfup`m{rulfuaxvjpfvvbm`vv{rulfuaxvjpfvvordfmrakfbwv}vwfoaxvjpfvvordfmruh`pj~`wjrpxpjwaxvjpfvvordfm{rulxpjwbm`vv`vss`hf bm`vvarxpd`u} bm`vvbmjfpws`hf bm`vvbmjfpwvbujsw bm`vvbrpwurm bm`vvfpwjw}bm`vvfpxofu`wjrpbm`vvf|bfswjrpbm`vvgruobm`vvgu`ofvfwbm`vvjosmfofpw`wjrpbm`vvbm`vvjpwfug`bfbm`vvkvss`hfbm`vvsr{fuw}sfbm`vvsurbfvvbm`vvvbujswmjau`u} bm`vvvfuzfus`hf bm`vvvfuzmfw bm`vvvjhp`m bm`vvvwfufrw}sf bm`vvw`amfbm`vvw`uhfwbm`vvwiuf`dbm`vvw}sfbm`vvxwjmjw}bm`vv{fas`hfbm`vvjgjfuofw`bm`vvbroofpwuftxjufofpwbroofpwufvsrpvjajmjw}brosrpfpwdrbxofpwbrosrpfpwf|fbxw`amfbrosrpfpwgjmfbrosrpfpwmjau`u} brosrpfpww`amf brpvwu`jpwjpz`uj`pw brpvwu`jpwsrvwbrpdjwjrp brpvwu`jpwsufbrpdjwjrp dfsfpdfpb}`bbfvvdfsfpdfpb}ajpddfsfpdfpb}b`mmdfsfpdfpb}dfujzfdfsfpdfpb}gujfpddfsfpdfpb}josruwdfsfpdfpb}jpvw`pbfrgdfsfpdfpb}jpvw`pwj`wfdfsfpdfpb}sr{fuw}sfdfsfpdfpb}ufgjpfdfsfpdfpb}vfpddfsfpdfpb}wu`bfdfsfpdfpb}xvf hfpfu`mj~`wjrpjosmfofpw`wjrp hxjfmfofpwaxwwrp hxjfmfofpwbifblar| hxjfmfofpwbroarar| hxjfmfofpwd`wfhxjfmfofpwdj`mrhhxjfmfofpwdursdr{phxjfmfofpwgruohxjfmfofpwmjvwhxjfmfofpwmjvwzjf{hxjfmfofpws`pfmhxjfmfofpwu`djrhxjfmfofpwufsruwhxjfmfofpww`ahxjfmfofpwwf|war|hxjfmfofpwwjofhxjfmfofpwwuffmjvwc @@@ @ @@ @ `bwjzjw}surbfvv `vvrbj`wjrpvxavbujaf`wwujaw`amfbrmxopaxvjpfvvbm`vvb`vf{rulfuaxvjpfvvbm`vvfpwjw}axvjpfvvbm`vvjpwfup`m{rulfuaxvjpfvvbm`vv{rulfuaxvjpfvvordfmrakfbwv}vwfoaxvjpfvvordfmruh`pj~`wjrpxpjwaxvjpfvvordfm{rulxpjwbm`vv`vss`hf bm`vvarxpd`u} bm`vvbmjfpws`hf bm`vvbmjfpwvbujsw bm`vvbrpwurm bm`vvfpwjw}bm`vvfpxofu`wjrpbm`vvf|bfswjrpbm`vvgruobm`vvgu`ofvfwbm`vvjosmfofpw`wjrpbm`vvbm`vvjpwfug`bfbm`vvkvss`hfbm`vvsr{fuw}sfbm`vvsurbfvvbm`vvvbujswmjau`u} bm`vvvfuzfus`hf bm`vvvfuzmfw bm`vvvjhp`m bm`vvvwfufrw}sf bm`vvw`amfbm`vvw`uhfwbm`vvwiuf`dbm`vvw}sfbm`vvxwjmjw}bm`vv{fas`hfbm`vvjgjfuofw`bm`vvbroofpwuftxjufofpwbroofpwufvsrpvjajmjw}brosrpfpwdrbxofpwbrosrpfpwgjmfbrosrpfpwmjau`u} brosrpfpww`amf brpvwu`jpwjpz`uj`pw brpvwu`jpwsrvwbrpdjwjrp brpvwu`jpwsufbrpdjwjrp dfsfpdfpb}`bbfvvdfsfpdfpb}ajpddfsfpdfpb}b`mmdfsfpdfpb}dfujzfdfsfpdfpb}gujfpddfsfpdfpb}josruwdfsfpdfpb}jpvw`pbfrgdfsfpdfpb}jpvw`pwj`wfdfsfpdfpb}sr{fuw}sfdfsfpdfpb}ufgjpfdfsfpdfpb}vfpddfsfpdfpb}wu`bfdfsfpdfpb}xvf hfpfu`mj~`wjrpjosmfofpw`wjrp hxjfmfofpwaxwwrp hxjfmfofpwbifblar| hxjfmfofpwbroarar| hxjfmfofpwd`wfhxjfmfofpwdj`mrhhxjfmfofpwdursdr{phxjfmfofpwgruohxjfmfofpwmjvwhxjfmfofpwmjvwzjf{hxjfmfofpws`pfmhxjfmfofpwu`djrhxjfmfofpwufsruwhxjfmfofpww`ahxjfmfofpwwf|war|hxjfmfofpwwjofhxjfmfofpwwuffmjvw @@ @  @  @hxjfmfofpwzmjpf mjplfpdhmra`m mjplfpdmrb`m mjplfpds`u`ofwfu mjplfpdvfmg ofvv`hfafbrof ofvv`hfbrs}ofvv`hfbuf`wfofvv`hfdfvwur}ordfm`p`m}vjvv}vwfoordfmdfvjhpv}vwfoordfmjosmfofpw`wjrpv}vwfoordfmxvfb`vfv}vwfoprdfbduroprdfbduroprdfbrosxwfuprdfdjvl`uu`}prdfsbprdfsbbmjfpwprdfsbvfuzfu prdfvfbxuf prdfvfuzfu prdfvwru`hf prdfxpj|vfuzfu prdfxvfusbrsw`amfbifblrsw`amfglrsw`amfjpdf|rsw`amfslrsw`amfsurbrsw`amfwujhhfursw`amfxpjtxfs`bl`hfg`b`dfs`bl`hfgu`of{ruls`bl`hfordfms`bl`hfvwxas`bl`hfvxav}vwfos`bl`hfv}vwfoxvfvbrooxpjb`wfxvfvf|wfpd xvfvjpbmxdf VCN                    2           kIdTaskIDNameTaskTypeNOTESPriorityStatusOwner StartDateEndDatePhaseHistoryPercent TotalTime ActualTime AssignedTo  PrimaryKey E{qg])G:F]h D2.D..........._Q< @ @ @ @ @ @ @ @ @ @ @ @:Os@;@ Aoʠs@oʠs@t_diagramt_diagramobjects::::::::::8 @ 8s@ 8s@t_diagramtypest_diagram88888888886 ?[,s@[,s@t_packaget_diagramtypes88888888886 >"rs@"rs@t_packaget_diagram33333333331 =޿s@޿s@t_packaget_object22222222220 < Ns@ Ns@t_objectt_method1111111111/ ;kYs@kYs@t_objectt_attribute44444444442 :Os@Os@t_objectt_connector155555555553 9Bps@Bps@t_objectt_connector44444444442 8҈s@҈s@t_metrictypest_objectmetrics==========; 74s@4s@t_connectortypest_connector<<<<<<<<<<: mu@mu@Forms&&&&&&&&&&$ >*<@Tu@zz_q_implements2I@@$@I==1111111/ @xhan@U2@usysTables@@777+++++++) @>X@|`n@usysOldTablesE@=:::......., @rA@U2@usys_system-@=888,,,,,,,* @AF(nS@AF(nS@t_xrefuser++++++++++) AF(nS@AF(nS@t_xrefsystem----------+ +k2@+k2@t_xref''''''''''% vF(nS@vF(nS@t_versionp@666*******( @AF(nS@AF(nS@t_umlpatternq@999-------+ @>G{@U2@t_testtypes@<888,,,,,,,* @AF(nS@AF(nS@t_testplanse@888,,,,,,,* @`F{@U2@t_testclass#@<888,,,,,,,* @f)E{@U2@t_tcf@<222&&&&&&&$ @, 1@E(nS@t_tasks((((((((((& w,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$ w,sujojwjzfv$ w,suramfow}sfv$ w,surkfbwurmfv$ w,sursfuw}w}sfv$ w,uftxjufw}sfv$w,ufvrxubfv$w,ujvlw}sfv$w,urmfbrpvwu`jpw$w,uwg$w,uwgufsruw$w,uxmfv$w,vbfp`ujrw}sfv$w,vbujsw$w,vfbhurxs$w,vfbhurxssfuojvvjrp$w,vfbmrblv$w,vfbsfuojvvjrp$w,vfbsrmjbjfv$w,vfbxvfu$w,vfbxvfuhurxs$w,vfbxvfusfuojvvjrp$w,vw`wxvw}sfv$w,vwfufrw}sfv$ `bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfdVCK N    2    TCFID DescriptionWeightValueNotes  NumericWeight PrimaryKey{q7 QrH"[   @@@@@ w,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$ w,sujojwjzfv$ w,suramfow}sfv$ w,surkfbwurmfv$ w,sursfuw}w}sfv$ w,uftxjufw}sfv$w,ufvrxubfv$w,ujvlw}sfv$w,urmfbrpvwu`jpw$w,uwg$w,uwgufsruw$w,uxmfv$w,vbfp`ujrw}sfv$w,vbujsw$w,vfbhurxs$w,vfbhurxssfuojvvjrp$w,vfbmrblv$w,vfbsfuojvvjrp$w,vfbsrmjbjfv$w,vfbxvfu$w,vfbxvfuhurxs$w,vfbxvfusfuojvvjrp$w,vw`wxvw}sfv$w,vwfufrw}sfv$ w,w`vlv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd?@TCF13Special user training faciities are requiredBB?@TCF12Provide direct access for third parties==?@TCF11Includ special security features66?@TCF10Concurrent ?@TCF09Easy to change$$@@TCF08Portable?@TCF07Easy to use!!?@TCF06Easy to install%%?@TCF05Code must be re-usable,,?@TCF04Complex internal processing11?@TCF03End user efficiency (online)22?@TCF02Response or throughput performance objectivesCC@@TCF01Distributed System((_ @     lagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n y@ @wbgVWwbgVXwbgVYwbgVZwbgV[wbgV\wbgV]wbgV^wbgV_wbgWV wbgWW wbgWX wbgWY VC+N  (  2   'd       TemplateID TemplateType TemplateNameNotesStyleTemplate  PrimaryKeyS{qg           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$ VCN 2  2 TestClass Description  PrimaryKeya{q           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$ VC&N  2  d   '      PlanIDCategoryNameAuthorNotesTestPlaneele  PrimaryKeyE{qg]           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$ VC=N   2   TestType Description NumericWeightNotes  NumericWeight PrimaryKey{q@ AQ   @@@@@@w,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv$w,rbg$w,rsfu`wjrp$w,rsfu`wjrps`u`ov$w,rsfu`wjrpsrvwv$w,rsfu`wjrpsufv$w,rsfu`wjrpw`h$w,s`bl`hf$w,s`mfwwf$w,s`mfwwfjwfo$ w,sujojwjzfv$ w,suramfow}sfv$ w,surkfbwurmfv$ w,sursfuw}w}sfv$ w,uftxjufw}sfv$w,ufvrxubfv$w,ujvlw}sfv$w,urmfbrpvwu`jpw$w,uwg$w,uwgufsruw$w,uxmfv$w,vbfp`ujrw}sfv$w,vbujsw$w,vfbhurxs$w,vfbhurxssfuojvvjrp$w,vfbmrblv$w,vfbsfuojvvjrp$w,vfbsrmjbjfv$w,vfbxvfu$w,vfbxvfuhurxs$w,vfbxvfusfuojvvjrp$w,vw`wxvw}sfv$w,vwfufrw}sfv$ w,w`vlvw,wbgw,wfosm`wfw,wfvwbm`vvw,wfvwsm`pv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd?StandardSimple Test procedureUsed to test basic path=& ?RegressionRegression TestingRegression/% ?LoadPerformance under loadStress testing1#          IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@/I(nS@t_objecti555)))))))' @!#{@a2@t_metrictypes@:::......., @f"{@a2@t_method7@555)))))))' @$@E(nS@t_issues/@555)))))))' @5NU@c@t_implement2@888,,,,,,,* @'2@'2@t_image((((((((((& 0!{@Fu@t_html(@333'''''''% @8 {@a2@t_glossary@777+++++++) @1b@1b@t_genopt))))))))))' {@a2@t_ecf@222&&&&&&&$ @{@a2@t_diagramtypes@;;;///////- @ {@I(n mr`dufhufvvjrpvw`pd`udVC}N  2         Description NumericWeightNotesTRXTRX_IDStyle  NumericWeight PrimaryKey{qg]           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$ VCN   d          2 PatternIDPatternCategory PatternNameStyleNotes PatternXMLVersion{qgVCN   2    d              ElementID VersionID ElementTypeFlags ExternalFileNotesOwner VersionDateBranch ElementXMLkpNEPotStenaasr  ElementID PrimaryKey 22222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$ {qg           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$ VCN                       <(XrefIDNameType Visibility Namespace Requirement ConstraintBehavior Partition DescriptionClientSupplierLink(=$(=$ (=$(=$( =$(=$(=$(=$(=$ PrimaryKey XRefClient XRefSupplierXRefType {qg]@ .^``gW_g]fb_YZdd``ddW\_`V]bb\]Wd]0\.daWb]V\`Z]V`Z[fd^_d`\VW^XWZW_[Z[0\.dgXZY`\_WVX_ZbZb`W`Vb^XW`Wdg_\XY0\.f_W^VdfW^VVfZ\g`a]__Y^^fd[f^Wg[`0\ !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$ .VYV[X_WWY\X[ZZ]X^b\a[fW]ZXgfd][Y0\.bYdW^d_XY`[bZWWX__[^_X\`X[_a`fXZ0\.f^XZ\_WdX`f]Zb_b^ZV^^^W`Xa^[[W\g0\.f^XZ\_WdX`f]Zb_b^ZV^^^W`Xa^[[W\g0\#prpf%\#prpf%\#prpf%\#prpf%\brppfbwrusursfuw}\brppfbwrusursfuw}\brppfbwrusursfuw}\brppfbwrusursfuw}\VCN    2                  <(  $XrefIDToolIDNameType Visibility Namespace Requirement ConstraintBehavior Partition DescriptionClientSupplierLink$(=$(=$ (=$(=$ (=$(=$(=$(=$(= PrimaryKey XRefClient XRefSupplierXRefType {qg]            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$  VCN    2                  <(  $XrefIDToolIDNameType Visibility Namespace Requirement ConstraintBehavior Partition DescriptionClientSupplierLink$(=$(=$ (=$(=$ (=$(=$(=$(=$(= PrimaryKey XRefClient XRefSupplierXRefType {qg]           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2$292>2E2J2N2S2V2\2m2r2v2z2~       "$($+$2$7$;$?$C$L$N$ P$ T$ Y$ ^$ b$g$j$n$s$$$$$$$$$$$$$$$   VCSNHJ 2  2PropertyValueo  PrimaryKeya{q@@SSxfR=- q]J5$zl`VD+zhYI8%jZK9,}jT?*@@w,rakfbwgjmfvw,rakfbwofwujbvw,rakfbwsuramfovw,rakfbwsursfuwjfvw,rakfbwuftxjufvw,rakfbwufvrxubfw,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu| w,rakfbww}sfv350_TestTables1350_IssueEx1 350_DocumentEX1350_FeaturePos1350_TableListEx1350_Snapshot1 350_Phases1 350_ResourceHours1350_SystemTaggedValues1350_Flags1 WebStereo1 VersionDateJan-31-2004 Version4.00 TPos2TaggedVals1 Styles1Stereotypes1 RunState1 RTFFIELDS1 RoleConstraints1QueryDefs_1161QDF_251ParamIDX1 Packages1 PackageControl3Orphans301 OpsClean1 OpPos1OperationCode1ObjectScope1 ObjectParent1 NodeStereo1 Namespace1 LangDT251 IsNavigable1 GUID2GenericDataType1Gen25Fixes1 Elem3001 EAGUID1EA3TableNames1EA3FieldSizes3EA300VBDT1 EA300MSAccessDT1EA300Classifier1DiagramObjectStyle1DiagramLink1 DDL1Const1CodeGen1 ClassifierGUID1Classifier1 CheckObjectTypes1AttID1Association1 350_UserSecurity1350_TRXTypes1 350_Tables1 350_TableList1350_Styles1 350_Stereotype1350_Scenario1 350_RoleExtra1350_ResourceTables1350_ParamGUID1350_Package1 350_OpGUID1 350_DiagramObjectID1350_DiagramConnectorID1350_DataTypes1350_AttGUID1 310_XREF1 310_Tasks1 310_TableList21310_TableList1310_QObject1 310_Palette1 310_Metafile2 310_Images1 310_Generalization1310_FileTable1310_Columns1 310_Category1 k@@@ @@@   @ @   @@ @ YWV,b`wfhru}YWV,brmxopvYWV,gjmfw`amfYWV,hfpfu`mj~`wjrpYWV,jo`hfvYWV,ofw`gjmfYWV,s`mfwwfYWV,trakfbwYWV,w`amfmjvwYWV,w`amfmjvwX YWV,w`vlv YWV,|ufg Y[V,`wwhxjd Y[V,d`w`w}sfv Y[V,dj`hu`obrppfbwrujdY[V,dj`hu`orakfbwjdY[V,drbxofpwf|PY[V,gf`wxufsrvOY[V,gm`hvIY[V,jvvxff|QY[V,rshxjdY[V,s`bl`hfY[V,s`u`ohxjdY[V,si`vfvLY[V,ufvrxubfirxuvKY[V,ufvrxubfw`amfvY[V,urmff|wu`Y[V,vbfp`ujrY[V,vp`svirwMY[V,vwfufrw}sfY[V,vw}mfvY[V,v}vwfow`hhfdz`mxfvJY[V,w`amfmjvwY[V,w`amfmjvwf|NY[V,w`amfvY[V,wfvww`amfvRY[V,wu|w}sfvY[V,xvfuvfbxujw}`vvrbj`wjrp`wwjdbifblrakfbww}sfvbm`vvjgjfubm`vvjgjfuhxjd brdfhfp!brpvw"ddm#dj`hu`omjpl$dj`hu`orakfbwvw}mf%f`YVVbm`vvjgjfu&f`YVVov`bbfvvdw'f`YVVzadw(f`Ygjfmdvj~fv)f`Yw`amfp`ofv*f`hxjd+fmfoYVV,hfpX[gj|fv-hfpfujbd`w`w}sf.hxjd/jvp`zjh`amf0m`phdwX[1p`ofvs`bf2prdfvwfufr3rakfbws`ufpw4rakfbwvbrsf5rsfu`wjrpbrdf6rssrv7rsvbmf`p8rusi`pvYV9s`bl`hfbrpwurm:s`bl`hfv;s`u`ojd|<tdg,X[=txfu}dfgv,WW\>urmfbrpvwu`jpwv?uwggjfmdv@uxpvw`wfAvwfufrw}sfvBvw}mfvCw`hhfdz`mvDwsrvEzfuvjrpFzfuvjrpd`wfG{favwfufrH{@a2@t_diagramtypes@;;;///////- @ {@I(n VC<N  2  2   TableNameNewNameRelOrderFixCode{ "9tR,tN*~T6$pH\9!yWE!e<Authorst_authors Cardinalityt_cardinalityClientst_clients ComplexityTypest_complexitytypes%Connectort_connectorConnector_Typest_connectortypes$ConnectorConstraintt_connectorconstraint-Constantst_constantsConstraintTypest_constrainttypes%Diagramt_diagram DiagramObjectst_diagramobjects#DiagramTypest_diagramtypesECFt_ecf EffortTypest_efforttypesGlossaryt_glossary HTMLt_html Implementt_implementMaintTypest_mainttypesMethodt_method MetricTypest_metrictypesObjectt_object Object_Typest_objecttypesObjectConstraintt_objectconstraint'ObjectEffortt_objecteffortObjectFilest_objectfilesObjectMetricst_objectmetrics!ObjectProblemst_objectproblems#ObjectPropertiest_objectproperties'ObjectRequirest_objectrequires#ObjectResourcet_objectresource#ObjectRiskst_objectrisksObjectScenariost_objectscenarios%ObjectTestst_objecttestsObjectTRXt_objecttrxOCFt_ocf Operationt_operationOperationParamst_operationparams%OperationPostst_operationposts#OperationPrest_operationpres!Packaget_package Primitivest_primitivesProblemTypest_problemtypesProjectRolest_projectrolesPropertyTypest_propertytypes!RequireTypest_requiretypesResourcest_resourcesRiskTypest_risktypesWebSRoleConstraintt_roleconstraint# RTFt_rtf RTFReportt_rtfreportScenarioTypest_scenariotypes!StatusTypest_statustypesStereotypest_stereotypesTCFt_tcf TestClasst_testclassTestTypest_testtypesTRXTypest_trxtypes t_issues Attributet_attributeAttributeConstraintst_attributeconstraints/VC}N  2  2  QueryNameNewNameFixCode{@@giN?"~eJ/\[}S@\[}S@usysQueries*********** \[}S@\[}S@usysOldTables,,,,,,,,,,, \[}S@\[}S@usys_system*********** \[}S@\[}S@t_xrefuser))))))))))) \qVisibleObjectq_visibleobjectqUCMetricsq_ucmetrics qTCFq_tcf qSumTCFq_sumtcfqSumECFq_sumecfqResourceq_resource qRealizes2q_realizes2 qRealizes1q_realizes1 qPackagesq_packages qOrphansq_orphans qObjectTestsq_objecttests qObjectRealizesq_objectrealizes qObjectq_objectqMethodq_methodqImplements2q_implements2 qImplementsq_implements qECFq_ecf qDatatypesq_datatypes qConnectorq_connector qConnections3q_connections3qConnections2q_connections2qConnectionsq_connections qAttributeq_attribute VC^NX^  2   2  2  2 TableNameRelOrder DisplayNameFromVerToVer  PrimaryKeya{q)(\.i)b7yQ,`)U)\'@@@@t_objectresourceObject Resources1.1.09.9.9/*%t_objectrequiresObject Requires1.1.09.9.9.)$t_objectpropertiesObject Properties1.1.09.9.92-(t_objectproblemsObject Problems1.1.09.9.9.)$t_objectmetricsObject Metrics1.1.09.9.9,'"t_objectfilesObject Files1.1.09.9.9(#t_objecteffortObject Effort1.1.09.9.9*% t_objectconstraintObject Constraints1.1.09.9.93.)t_objectObject Details1.1.09.9.9%  t_metrictypesMetric Types1.1.09.9.9(#t_methodMethods1.1.09.9.9 t_mainttypesMaintenance Types1.1.09.9.9,'"t_listsLists3.5.09.9.9 t_issuesIssue Details1.1.09.9.9$ t_implementImplementation Details1.1.09.9.90+&t_imageImages3.1.09.9.9 t_glossaryGlossary1.1.09.9.9!t_genoptGeneration Options1.1.09.9.9)$ t_filesFiles3.5.09.9.9 t_efforttypesEffort Types1.1.09.9.9(#t_ecfECF Values1.1.09.9.9 t_documentDocument3.5.09.9.9!t_diagramtypesDiagram Types1.1.09.9.9*% t_diagramobjectsDiagram Objects1.1.09.9.9.)$t_diagramlinksDiagram Links1.1.09.9.9*% t_diagramDiagrams1.1.09.9.9 t_datatypesData Types1.1.09.9.9$t_constrainttypesConstraint Types1.1.09.9.90+&t_constantsConstants1.1.09.9.9#t_connectortypesConnector Types3.5.09.9.9.)$t_connectortagConnector Tag3.0.09.9.9*% t_connectorconstraintConnector Constraints1.1.09.9.994/t_connectorConnectors1.1.09.9.9$t_complexitytypesComplexity Types1.1.09.9.90+&t_clientsProject Clients1.1.09.9.9'"t_cardinalityObject Cardinality1.1.09.9.9.)$t_authorsProject Authors1.1.09.9.9'"t_attributetagAttribute Tag3.0.09.9.9*% t_attributeconstraintsAttribute Constraints1.1.09.9.9:50t_attributeObject Attributes1.1.09.9.9+&!$)k@G [*k@ d5h<xQ,t_testtypesTest Types1.1.09.9.9$t_testplansTest Plans3.5.09.9.9$t_testclassTest Classes1.1.09.9.9&!t_templateTemplates3.5.09.9.9"t_tcfTCF Values1.1.09.9.9 t_tasksTo Do List3.1.09.9.9  t_stereotypesStereotypes1.1.09.9.9'"t_statustypesStatus Types1.1.09.9.9(#t_secuserpermissionUser Permissions3.5.09.9.92-(t_secusergroupUser Group3.5.09.9.9'"t_secuserSecurity User3.5.09.9.9% t_secpoliciesSecurity Policies3.5.09.9.9-(#t_secpermissionPermissions3.5.09.9.9)$t_seclocksSecurity Locks3.5.09.9.9'"t_secgrouppermissionGroup Permissions3.5.09.9.94/*t_secgroupSecurity Groups3.5.09.9.9(#t_scriptScripts3.5.09.9.9 t_scenariotypesScenario Types1.1.09.9.9,'"t_rulesRules3.5.09.9.9 t_rtfreportRTF Reports1.1.09.9.9% qVist_roleconstraintRole Constraints1.1.09.9.9/*%t_risktypesRisk Types1.1.09.9.9$t_resourcesResources1.1.09.9.9#t_requiretypesRequire Types1.1.09.9.9*% t_propertytypesProperty Types1.1.09.9.9,'"t_projectrolesProject Roles1.1.09.9.9*% t_problemtypesProblem Types1.1.09.9.9*% t_paletteitemPalette Items3.1.09.9.9)$t_palettePalettes3.1.09.9.9 t_packagePackages1.1.09.9.9 t_operationtagOperation Tag3.0.09.9.9*% t_operationpresOperation Pre Conditions1.1.09.9.961,t_operationpostsOperation Post Conditions1.1.09.9.983.t_operationparamsOperation Parameters1.1.09.9.94/*t_operationOperations1.1.09.9.9$t_ocfOCF Values1.1.09.9.9 t_objecttypesObject Types3.5.09.9.9(#t_objecttrxObject TRX1.1.09.9.9$t_objecttestsObject Tests1.1.09.9.9(#t_objectscenariosObject Scenarios1.1.09.9.90+&t_objectrisksObject Risks1.1.09.9.9(# e8]5t_htmlHTML3.5.09.9.9 t_rtfRTF3.5.09.9.9 t_categoryCategory3.5.09.9.9!t_snapshotSnapshots3.5.09.9.9"t_phasePhases3.5.09.9.9 t_taggedvalueModel Tagged Values3.5.09.9.9/*%usys_systemSystem Settings3.1.09.9.9)$t_xrefuserUser XRef3.5.09.9.9"t_xrefsystemSystem XRef3.5.09.9.9&!t_xrefXRef3.1.09.9.9 t_versionFiles3.5.09.9.9t_umlpatternUML Patterns3.5.09.9.9'"t_trxtypesTRX Types1.1.09.9.9"n   @@@ @@@ @@ @ @  @@w,`wwujaxwfw,`wwujaxwfbrpvwu`jpwvw,`wwujaxwfw`hw,`xwiruvw,b`udjp`mjw}w,b`wfhru} w,bmjfpwvw,brosmf|jw}w}sfvw,brppfbwruw,brppfbwrubrpvwu`jpww,brppfbwruw`h w,brppfbwruw}sfv w,brpvw`pwv w,brpvwu`jpww}sfv w,d`w`w}sfv w,dj`hu`ow,dj`hu`omjplvw,dj`hu`orakfbwvw,dj`hu`ow}sfvw,drbxofpww,fbgw,fggruww}sfvw,gjmfvw,hfprsww,hmrvv`u}w,iwom w,jo`hfw,josmfofpww,jvvxfvw,mjvwvw,o`jpww}sfvw,ofwirdw,ofwujbw}sfvw,rakfbww,rakfbwbrpvwu`jpw w,rakfbwfggruw!w,rakfbwgjmfv"w,rakfbwofwujbv#w,rakfbwsuramfov$w,rakfbwsursfuwjfv%w,rakfbwuftxjufv&w,rakfbwufvrxubf'w,rakfbwujvlvw,rakfbwvbfp`ujrvw,rakfbwwfvwvw,rakfbwwu|w,rakfbww}sfvw,rbgw,rsfu`wjrpw,rsfu`wjrps`u`ovw,rsfu`wjrpsrvwvw,rsfu`wjrpsufv w,rsfu`wjrpw`h w,s`bl`hf w,s`mfwwf w,s`mfwwfjwfo w,si`vfw,suramfow}sfvw,surkfbwurmfvw,sursfuw}w}sfvw,uftxjufw}sfvw,ufvrxubfvw,ujvlw}sfvw,urmfbrpvwu`jpww,uwg w,uwgufsruww,uxmfvw,vbfp`ujrw}sfvw,vbujsww,vfbhurxsw,vfbhurxssfuojvvjrpw,vfbmrblvw,vfbsfuojvvjrpw,vfbsrmjbjfvw,vfbxvfuw,vfbxvfuhurxsw,vfbxvfusfuojvvjrp w,vp`svirw w,vw`wxvw}sfv!w,vwfufrw}sfv"w,w`hhfdz`mxfw,w`vlv#w,wbg$w,wfosm`wf%w,wfvwbm`vv&w,wfvwsm`pv'w,wfvww}sfv(w,wu|w}sfvw,xoms`wwfupw,zfuvjrpw,|ufgw,|ufgv}vwfow,|ufgxvfuxv}v,v}vwfo(ș<Jk^ @ @ @ @ @ @ @ @ @$I$I$I$I%I%I%I%I %I!%I&I"&I$&I%&I&&I'&I(&I)&I*&I+&I,&I-&I.&I/&I0&I#'I1'I3'A'A'A'I2(A(A(A(A(A(A (A (A (A (A (A(A(A(A(t_metrt_objt_objet_diagramt_diagramobjectst_diagramobjectsDiagram_IDt_diagramDiagram_IDSI@6& t_diagramtypest_diagramt_diagramDiagram_Typet_diagramtypesDiagram_TypeSG9-$ t_packaget_diagramtypest_diagramtypesPackage_IDt_packagePackage_IDOE<2$ t_packaget_diagramt_diagramPackage_IDt_packagePackage_IDE;2( t_packaget_objectt_objectPackage_IDt_packagePackage_IDC90& t_objectt_methodt_methodObject_IDt_objectObject_ID?6.% t_objectt_attributet_attributeObject_IDt_objectObject_IDE<4+ t_objectt_connector1t_connectorStart_Object_IDt_objectObject_IDLC;,! t_objectt_connectort_connectorEnd_Object_IDt_objectObject_IDI@8+ t_metrictypest_objectmetricst_objectmetricsMetricTypet_metrictypesMetricUOB8) t_connectortypest_connectort_connectorConnector_Typet_connectortypesConnector_Type_QA3( E{qg]     Uqq=  m9  +PersistenceNULL#;*MultiplicityNULL$;)EventFlagsNULL";(ActionFlagsNULL#;'PackageFlagsNULL$;&StateFlagsNULL";%IsActive0;$IsSpec0;#IsLeaf0;"IsRoot0;!RunStateNULL ; Phase'1.0' ;Header2NULL;Header1NULL;GenLinksNULL ;GenFileNULL;GenType'Java'!;Fontcolor-1;Backcolor-1;BorderWidth-1!;Bordercolor-1!;PDATA5NULL;ModifiedDate#2003-08-22 13:36:21#5;Tagged0;Classifier_guidNULL'; P|l"DUID=1CE36E20;/! 0OyDUID=81FBAF85;/! 0Nx.FDUID=31760B86;/! 0MDUID=EE2397B7;/! 0LqDUID=DFC93F21;/! 0HDUID=E585EE32;/! 0GwEDUID=3D79E0A4;/! DoDUID=E58486A8;LBL=;4! C DUID=FAD2A1B5;LBL=;4! B]2 DUID=12DDDFF9;LBL=;4! Ad DUID=5DECEEC9;LBL=;4! >n( DUID=BDEA24A9;LBL=;4! = c DUID=BFDAC143;LBL=;4! <gSDUID=CDDEF3BC;LBL=;4!g3L9&rAM          2                   IdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtra  Id ParentIdName        E(nS@t_objectproblemsS@===1111111/ @;R.{@U2@t_objectmetrics@<<<0000000. @-{@g2@t_objectfiles@:::......., @-{@U2@t_objecteffort@;;;///////- @%{@+(@!7 '+t_packaget_object*@ 7) +t_objectt_diagramobjects/@70$ +t_object.Stereotype+ g+ t_object.Note% g+ t_object.Name% g+t_object.Object_Type, g+t_object.Object_ID* g+Packaget_package.Name- o+t_package +t_diagramobjects +t_object + G+ G+ + * t_package.Package_ID, '*b@7 '*t_packageObject_1*@7) *Object_1q_implements*@7,  *t_implementObject_1'@7+ *t_objecttypesObject_10@7-! * t_objecttypes.DesignObject2 g* ImplementorType"") o*ImplementorName"") oLVALhowBorder    Yes/No  Yes  jlShowPackageContents    Yes/No  Yes  jN PDATA      mT Locked    Yes/No  jM Name ^     mO Author      mP ea_guid      mK'~ok\MXI:+' xteVRC4  ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o  ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o LVAL <T2X%KKDRequired! PermissionID #PermissionName KKDRequired UserID  EntityType EntityID  Timestamp KKDRequired GroupID ! PermissionID KKDRequired GroupID  GroupName KKDRequiredScriptID  ScriptName  Script KKDRequired RuleID RuleName RuleType KKDRequired ListID Category  Name KKDRequired FileID  AppliesTo Category  Name KKDRequired DocID  DocName  ElementID   ElementType KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlFilterOrderBy< ' t_diagramobjects.Object_ID DESC\ Diagram_ID      0  m[ Object_ID      0  mY RectTop      0  mZRectLeft      0  m[ RectRight      0  m\ RectBottom      0  mZSequence      0  mDLVAL<,V333vvvvvvKKDi AccessVersionBuildTrack Name AutoCorrect InfoPerform Name AutoCorrectProjVer EADiffViewso  07.53    & t_datatypes|t_object|t_packageKKDRequired PhaseID  PhaseName KKDRequired PropertyID  ElementID  BaseClass KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKDRequired ElementID  VersionID   ElementType KKDRequired PatternID   PatternName  PatternXML KKDRequired PlanID  Name TestPlan KKDRequired TemplateID ! TemplateType ! TemplateName KKDRequired UserID ! PermissionID KKDRequired UserID  GroupID KKDRequired UserID  UserLogin  FirstName  Surname KKDRequiredProperty  Value KKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValueFilterOrderByValidationRuleValidationText DescriptionFormat InputMaskCaption U Diagram_Type      m\ Package_ID      0  mM Name      mLVALddŵ% &&&'''((())), &, ', (- )- *- +. ,. -. ./ ///00011122 2 3 3 3 444555666% !"#$$ $!$"999>>>E#E$E%J&JJNNNSSSVV V \ \ \ mmKKDi AccessVersionBuildTrack Name AutoCorrect InfoPerform Name AutoCorrectProjVer EADiffViewsT  07.53     tmpKKDRequired SnapshotID SeriesID ! SnapshotName  ElementID   ElementType KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue n Description s   Description of TCF   mi Weight 6    Weighting   1  m] Notes    Comment   mj ECFID s   Technical Factor Coe   mW Value      0  m&LVAL2Gh)Jm4X"t=EG UCX}S@CX}S@t_objecttrx*********** CX}S@CX}S@t_objecttests,,,,,,,,,,, ^X}S@^X}S@t_objectscenarios00000000000 ^X}S@^X}S@t_objectrisks,,,,,,,,,,,  ^X}S@^X}S@t_objectresource/////////// ^X}S@^X}S@t_objectrequires/////////// ^X}S@^X}S@t_objectproperties11111111111 ^X}S@^X}S@t_objectproblems/////////// ^X}S@f[}S@t_objectmetrics........... ^X}S@^X}S@t_objectfiles,,,,,,,,,,, ^X}S@^X}S@t_objecteffort----------- ^X}S@^X}S@t_objectconstraint11111111111 W}S@f[}S@t_object''''''''''' W}S@f[}S@t_metrictypes,,,,,,,,,,, W}S@f[}S@t_method''''''''''' W}S@W}S@t_mainttypes+++++++++++ W}S@W}S@t_lists&&&&&&&&&&& W}S@W}S@t_issues''''''''''' W}S@W}S@t_implement*********** W}S@W}S@t_image&&&&&&&&&&& W}S@W}S@t_html%%%%%%%%%%% KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValueValidationRuleValidationTextFilterOrderByFormat InputMaskCaption  NumericWeight   E =Numeric factor to apply to metric - accepts decimal fractions   0  mc Notes     Further notes   md EffortType     Risk Code   mo Description    Description of Risk   m1>>>22222220 @;1{@U2@t_objectrisks@0:::......., @/{@U2@t_objectrequires@/===1111111/ @Zb@U2@t_objectpropertiesi@/???33333331 @ /{@E(nS@t_objectproblemsS@.===1111111/ @;R.{@U2@t_objectmetrics@.<<<0000000. @-{@g2@t_objectfiles@-:::......., @",{@U2@t_objectconstraint@-???33333331 @%{@MS@t_objecti*555)))))))' @!#{@a2@t_metrictypes@):::......., @ )"{@a2@t_mainttypesr@)999-------+ @AF(nS@AF(nS@t_listse@444(((((((& @$@mT@t_issuesV@M555)))))))' @5NU@c@t_implement2@%888,,,,,,,* @'2@'2@t_image((((((((((& 8 {@a2@t_glossary @ @ @ @@@w,vfbxvfusfuojvvjrp$w,vp`svirw>w,vw`wxvw}sfv$w,vwfufrw}sfv$ w,w`hhfdz`mxf>w,w`vlvw,wbgw,wfosm`wfw,wfvwbm`vvw,wfvwsm`pvw,wfvww}sfvw,wu|w}sfvw,xoms`wwfupw,zfuvjrpw,|ufg w,|ufgv}vwfo w,|ufgxvfu xv}v,v}vwfo xv}vrmdw`amfv xv}vtxfujfvxv}vw`amfv~~,t,josmfofpwvX~~,t,rusi`pv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd.^Z_g`W\bg]VZZXbZ^Wd[]WZV_YX^X`[d0s`bl`hfdj`hu`o^Wd[]WZV_YX^X`[d0s`bl`hfdj`hu`oaf\aX``Wb[gWXWfX0s`bl`hfdj`hu`oaf\aX``Wb[gWXWfX0s`bl`hfdj`hu`oaf\aX``Wb[gWXWfX0s`bl`hfdj`hu`oaf\aX``Wb[gWXWfX0s`bl`hfdj`hu`oaf\aX``Wb[gWXWfX0s`bl`hfdj`hu`o@@@w,brppfbwruw}sfvw,brppfbwruw,dj`hu`ow,dj`hu`orakfbwv(w,dj`hu`ow}sfvw,dj`hu`o'w,ofwujbw}sfvw,rakfbwofwujbvw,rakfbww,`wwujaxwf"w,rakfbww,brppfbwru w,rakfbww,brppfbwruW!w,rakfbww,ofwird#w,s`bl`hfw,dj`hu`o%w,s`bl`hfw,dj`hu`ow}sfv&w,s`bl`hfw,rakfbw$@XI{D748CF3F-CD8D-4A32-BE6B-2AA1C5F121E2}t_attributeObject_IDt_objectObject_IDXOG>3 {8E928001-6F1B-488D-8ED6-096A83BEFC22}t_connectorEnd_Object_IDt_objectObject_ID\SK>3 {849FA16C-F704-42C4-81D5-714093282A5D}t_diagramobjectsDiagram_IDt_diagramDiagram_ID`VMC3 {50EF5A01-F828-42A0-BB68-A639A0ADAD38}t_connectorStart_Object_IDt_objectObject_ID^UM>3 {4284C791-A819-44C8-B0AD-41BCCD533E6A}t_objectmetricsMetricTypet_metrictypesMetric_YLB3 {2B3CBB66-A1DE-44CB-91EF-FA7293F5D8AC}t_connectorConnector_Typet_connectortypesConnector_Typej\L>3 {1E62D3A8-F3CF-4E2A-B0A0-A7266C98C7DB}t_methodObject_IDt_objectObject_IDULD;3 :~o`QB/ qbO@1"s`QBBBBBBBBBBB3/ < <ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o < : 8 8ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 8 7 7ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 7   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o     ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o     ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o     ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o  LVAL4@@(G (H)Connector)ObjectaObject_1(G (H)Connector)ObjectaObject_1(H)Connector)ObjectaObject_1( G&bAttribute1qObject4LVALqWNKKD~ RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn ColumnWidth ColumnHidden Replicable1  < KKD~ RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn ColumnWidth ColumnHidden Replicable1  <  KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  + SourceName  + SourceType  )DestType 7 )DestName o ' DestID  )SourceID  KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  + SourceName  + SourceType  )DestType 7 )DestName o ' DestID  )SourceID  KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  + SourceName  + SourceType  )DestType 7 )DestName o ' DestID  KKDc RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKDTitleAuthorCompanyC db2 Geoffrey Sparks  Sparx SystemsKKD KeepLocal T b` cń7j%ڂCi"؀GYAF(nS@AF(nS@t_templateu@777+++++++) @C{@|\B(nS@t_stereotypes@;:::......., @%F(nS@%F(nS@t_secpoliciesK@:::......., @E(nS@%F(nS@t_secgroupN@777+++++++) @sQ@'7s@t_rtf9@9222&&&&&&&$ @^FE@U2@t_propertytypes@5<<<0000000. @;E8{@U2@t_operationpres7@6<<<0000000. @"p*+{@U2@t_objecttypesO@2:::......., @ ufN@*S@t_objectresourced@0===1111111/ @-{@U2@t_objecteffort@-;;;///////- @f"{@ Ns@t_method7@)555)))))))' @0!{@Fu@t_html(@%333'''''''% @{@a2@t_ecf@222&&&&&&&$ @$l@.I(nS@t_datatypes@&888,,,,,,,* @\{@Os@t_connectorW888,,,,,,,* @E)4{@a2@t_authors@666*******( @(}<@ٰ<@rptUseCases@@D88,,,,,,,* @$l|-@l|-@qdf_relatestoE@:::......., @d<@d<@q_visibleobject@@@H<<0000000. @.<@.<@q_sumtcf@@A55)))))))' @I<@l<@q_realizes2.@@D88,,,,,,,* @ <@K<@q_objectrealizes@@I==1111111/ @<@鋊}@q_implements@$@E99-------+ @Ab<@Ab<@q_connector@ @D88,,,,,,,* @ &q<@+<@q_connections@ @ F::......., @ lu@lu@SummaryInfoe@ 888,,,,,,,* @.=~o`\MI:+' xteVRC4Package_IDpiLeT_dalA Aۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o A @ @ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o @ ? ?ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o ? > >ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o > = =ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o = ; ;ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o ; : :ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 9 9ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 9   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o  Tۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o     ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o     N 2                $  (  0    2     8                   2   2   2 !  !2 !" "2 "# # #$ $ $% % %& &2 &' ' '( ( () ))* < *+ +(+, @ ,- - -.  .(./ D/0 01 12 23  34  4 4 5  5 5!6 62 6"7  7 7#8  8 8$9  9 Object_ID Object_Type Diagram_IDNameAliasAuthorVersionNote Package_ID StereotypeNType ComplexityEffortStyle Backcolor BorderStyle BorderWidth Fontcolor Bordercolor CreatedDate ModifiedDateStatusAbstractTaggedPDATA1PDATA2PDATA3PDATA4PDATA5 Concurrency Visibility Persiste 9${@#NSomethingDefectNewLow**''''''$ K'~ok\MI:+' xteVRC4  ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o     ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o      ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o      ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o      ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   Tۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 0LVALtD]Eg/Dc!fCZ u eMethod5qObject^nDiagram(v/&qt_objecttypes qt_object2qt_connector/rObject_1} vt_package(G&5{ECF(M9'Connector0sDiagramObjects[ tDiagramObjects_1(H)Connector)ObjectaObject_1LVAL  K<Eg/Dc!fC`&}F[T}S@T}S@q_packages))))))))))) T}S@T}S@q_KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable( Package  3t_object.Object_ID t 1  <  KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  . Object_1.Name  KKDc RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKDc RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKD~ RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn ColumnWidth ColumnHidden Replicable1  <  , PackageName  KKDc RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  )ObjectID   0ImplementedByID  + ObjectName  0ImplementorName  + ObjectType  0ImplementorType d KKDc RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKD8 RecordLocks ODBCTimeout MaxRecords Replicable  <|LVALt @ @ @ @ @ @ @ @ @ @ @ @ @]x&q"t_object qt_package(/yxut_object qt_packageB6Object_1}t_objecttypes&qt_objecttests qt_object&qt_package qt_objecttypes2qt_object&qt_package q"t_object2qt_diagramobjectsK'~ok\MI:+' xteVRC4T}S@T}S@q_packages!    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o LVAL(P(4Eg/Dc!f(G&qTCF(G&qTCFa*#[&qECF&qObjectResourceIoObject&qt_package qt_objecttypes2qt_objectqt_connector&qt_package qt_objecttypes2qt_objectqt_connectorLVALY)KKDc RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  + Complexity d 5t_object.Object_Type  . t_object.Name  /t_package.Name  5t_package.Package_ID  KKDc RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKDc RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKDc RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKD~ RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn ColumnWidth ColumnHidden Replicable1  <  KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable% Type  1  <  )ObjectID  - RealizedByID  KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable% Type  1  <  )ObjectID  - RealizedByID  LVALt4( @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @     wAzObjectPackagekFDiagramv&qObjectrAzObjectPackagekFDiagramu&qObject,oObject_Types({&St_ocfFt_package t_objectLVAL v1b @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @KKDd OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl T Cardinality      mKKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable3Object.Object_Type 8 , Object.Name  1  <  . Object_1.Name  KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable3Object.Object_Type 8 5Diagram.Diagram_Type  , Object.Name  - Package Name  - Diagram Name  I  <   rptUseCases.NameKKD ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetType RowHeightFilterOrderBy OrderByOn Replicable, Object.Name  , Object.Note $ =  <    KKD~ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKD ODBCTimeout MaxRecords" < KKD ODBCTimeout MaxRecords" < KKD ODBCTimeout MaxRecords" < KKD ODBCTimeout MaxRecords" < KKD ODBCTimeout MaxRecords" < KKD ODBCTimeout MaxRecords" < K'~ok\MI:+' xteVRC4J E Eۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o E $ $ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o $ > >ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o > 9 9ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o 9 ) )ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o ) ( (ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o ( ' 'ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o ' & &ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o & % %ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o % $ $ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o $ # #ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o # " "ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o " ! !ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o LVALtP` cʾt_rtfreportIq_packages 6-! ut_object~rt_diagramobjects&qt_package(z<+Ct_implement+Tt_packageo:t_objecttypes rObject_1`qq_implements(ObjectD#Object_1p|ConnectorLVAL @KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption [ Object_ID       0  mN Scope G     mS Stereotype      mT Containment      mZIsStatic      0  m^ IsCollection      0  m[ IsOrdered      0  maAllowDuplicates      0  mS LowerBound      mS UpperBound      mR Container      mD Notes     P Derived      mM Name      m/ID   L Pos      mH GenOption     O Length      mR Precision      mN Scale      mN Const      mN Style      mPLVAL2^TGF^ Fp)D4C]g.|8*z+sV}S@+sV}S@t_constants*********** vV}S@f[}S@t_connectortypes/////////// rV}S@V}S@t_connectortag----------- mV}S@V}S@t_connectorconstraint44444444444 \V}S@f[}S@t_connector*********** VU}S@U}S@t_complexitytypes00000000000 SU}S@U}S@t_clients((((((((((( NU}S@U}S@t_category))))))))))) JU}S@U}S@t_cardinality,,,,,,,,,,, EU}S@U}S@t_authors((((((((((( $U}S@U}S@t_attributetag----------- >U}S@U}S@t_attributeconstraints55555555555 KKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption DefaultValue N Roles      mN Notes      mS AuthorName      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption [ Object_ID      0  mD Notes     S Constraint      mP AttName      mM Type F     mKID      mK'~ok\MI:+' xteVRC4  ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o  ~ ~ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o ~ z zۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o z v vۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o v r rۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o r m mۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o m \ \ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o \ V Vۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o V S Sۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o S N Nۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o N J Jۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o LVALV %F^ Fp)D4C}5Bc*x4~**z+sV}S@+sV}S@t_constants*********** vV}S@f[}S@t_connectortypes/////////// rV}S@V}S@t_connectortag-KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLength ] ConnectorID      0  mS Constraint O     mD Notes     WConstraintType      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue S Complexity      m_ NumericWeight      0  mKKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlFilterOrderByValidationRuleValidationText DescriptionFormat InputMaskCaption DefaultValue N Roles      mN Notes      mO Phone1 7     mO Phone2      mO Mobile      mL Fax      mN Email       mM Name      mU Organisation      mLVAL3ț6  m` Name     Object name   m] BorderWidth      0  m[ Fontcolor      0  m] Bordercolor      0  mT Concurrency      mS Visibility      mT Persistence      mT Cardinality      mP GenType      mP GenFile      mF Header1 @    F Header2     N Phase      mN Scope      mH GenOption     GGenLinks     k Object_Type (   The object type   mN Alias      mO AuExcludeRTF=0;DocAll=0;HideQuals=0;AttPkg=1;SuppressFOC=0;TDurLow=0;TDurHigh=100;TDurUnit=;TDurHide=0;ExcludeRTF=0;DocAll=0;HideQuals=0;AttPkg=1;SuppressFOC=0;TDurLow=0;TDurHigh=100;TDurUnit=;TDurHide=0;ExcludeRTF=0;DocAll=0;HideQuals=0;AttPkg=1;SuppressFOC=0;TDurLow=0;TDurHigh=100;TDurUnit=;TDurHide=0;ExcludeRTF=0;DocAll=0;HideQuals=0;AttPkg=1;SuppressFOC=0;TDurLow=0;TDurHigh=100;TDurUnit=;TDurHide=0;2d?Ohtт@\ n @ @ @ @ @ @DDLSQL Server 2000moneycurrencyD<<<<<<7(% &&& DDLSybasenumericnumeric<555555.(% DDLInterBaseblob sub_type 0blobD@@@@@@1(% 5DDLSybasedoubledouble:444444.(% @2DDLPostgreSQLvarcharvarchar@9999992(% DDLPostgreSQLintegerinteger@9999992(% DDLDB2FLOATfloat5000000+(% && DDLPostgreSQLnumericnumeric@9999992(% DDLDB2LONG VARCHARtext;777777+(% DDLSQL Server 2000smalldatetimedatetimeLDDDDDD7(% 2DDLSQL Server 2000nvarcharnvarcharG??????7(% DDLSQL Server 2000imageblob@<<<<<<7(% @ DDLSQL Server 2000binaryBinaryC======7(% DDLInterBasedouble precisiondoubleGAAAAAA1(% @2DDLSybasevarcharvarchar<555555.(% DDLSybasebigintbigint:444444.(% DDLSQL Server 2000timestamptimestampI@@@@@@7(% @ DDLSQL Server 2000charchar?;;;;;;7(% DDLSybasesmallintsmallint>666666.(% DDLSybasebinaryblob8444444.(% 55DDLPostgreSQLrealdouble<6666662(% DDLInterBasetimestampdatetimeB::::::1(%  DDLMySqlNCHARnchar7222222-(%  DDLInterBasesmallintsmallintA9999991(%  DDLInterBaseintegerinteger?8888881(% \X;gDÏ@V v'^XRLF@:4.(" tructor=pyConInline=CodePHPvarvar2//////,)% ODDLSQL Server 2000texttext?;;;;;;7(% 55DDLSQL Server 2000realdoubleA;;;;;;7(% DDLMSAccessBytetinyint;4444440(% 2DDLInterBasevarcharvarchar?8888881(% DDLSybasetinyinttinyint<555555.(% DDLSybasetimestamptimestamp@777777.(% 2DDLOracleNVARCHAR2nvarchar?777777.(%  DDLSQL Server 2000ncharncharA<<<<<<7(% 55DDLSQL Server 2000floatfloatA<<<<<<7(% DDLSQL Server 2000datetimedatetimeG??????7(% (DDLSQLServer7uniqueidentifieruniqueidentifierRBBBBBB2(% DDLMySqlBLOBblob5111111-(% DDLSQL Server 2000intintegerA::::::7(% DDLSybasefloatfloat8333333.(% DDLMSAccessOLEObjectblob=9999990(% DDLSybasedatetimedatetime>666666.(%  DDLOracleCLOBtext6222222.(% @ DDLSybasecharchar6222222.(% DDLDB2SMALLINTsmallint;333333+(% DDLPostgreSQLbigintbigint>8888882(% DDLSybasetexttext6222222.(% 55DDLSybaserealreal6222222.(% DDLSQL Server 2000uniqueidentifierguidKGGGGGG7(% DDLSQL Server 2000ntextntextA<<<<<<7(% $                         $ %                !"#$%&      !" # $ %!&!!"""###$$ $ % % % &&&'''((())), &, ', (- )- *- +. ,. -. ./ ///00011122 2 3 3 3 444555666% !"#$$ $!$"999>>>E#E$E%J&JJNNNSSSVV V \ \ \ mmmrrrv          ! " # #?#3% &&&'''((()))*K&*L*L+L+L+L7 07 17 28 38 48 59&9'9(: 6:):*;+;,;-< 7< 8< 9=.=/=0>1>2>3?4?5?6@7@8@9A:A;A<% !"#$$ $!$"999>>>E#E$E%J&JJNNNSSSVV V \ \ \ lLlLlLmmmrrrvvvzzz~~~       !"#$%&(((((((((( ( ( ( ( (((((((((((((((((( (  (! ("(#($(%(&HHHHHHHH"H"H "H (H (H (H +H+H          ! " #LVAL% &&&'''((())), &, ', (- )- *- +. ,KKDValidationRuleValidationTextFilterOrderBy OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionFormat InputMaskCaption DefaultValueRequiredAllowZeroLengthDisplayControl M Type       mKKDo OrderByOn RowHeight ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl!  M Type      mGTemplate -    KKDq OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl q Description    Description of Metric   mY Notes     Further notes  f Constraint s    Metric Code   mKKDd OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl U ConstantName      mV ConstantValue /     mKKDd OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl WConnector_Type      mT Description      m*LVAL8TGF^ Fp)D4C}5BKKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlFilterOrderByValidationRuleValidationText DescriptionFormat InputMaskCaption DefaultValue F Meaning     M Term      mM Type      mKKDValidationRuleValidationTextFilterOrderBy OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionFormat InputMaskCaption DefaultValueRequiredAllowZeroLengthDisplayControl DecimalPlaces M Type       mT ProductName       mQDataType       mM Size       mO MaxLen       mP MaxPrec       mS DefaultLen       mT DefaultPrec       mU DefaultScale       mM User       mO PDATA1       mO PDATA2       mO PDATA3       mO PDATA4       mR HasLength       mZMaxScale      0   mLVAL KKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue DescriptionFormatFilterOrderByValidationRuleValidationTextCaption InputMask 7 Diagram_ID   U Diagram_Type       mS Stereotype      m Package_ID      1  m' Diagram belongs in this package] Version g     m  "1.0"_ AttPub )   Yes/No  Yes  j_ AttPri )   Yes/No  Yes  j_ AttPro e   Yes/No  Yes  j_ Orientation      m  "P"Tcx      0  mTcy      0  mY Scale      100  m] ShowDetails :     0  mP CreatedDate     =Date()Q ModifiedDate     =Date()ParentID   b ZOptional objectID that this diagram exists under - e.g.Sequence diagram under UseCase node   0  mQHTMLPath      mD Notes     d ShowForeign    Yes/No  j  Yesc SK'~ok\MI:+' xteVRC4t_CX}S@CX}S@t_objecttr  ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o     ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o    ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o  ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o   ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o LVALWKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue q Description s   Description of Metric   m NumericWeight 6  E =Numeric factor to apply to metric - accepts decimal fractions   1  mc Notes     Further notes   mb Metric s    Metric Code   mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption [ Object_ID      0  mN Scope      mM Type      mM Name      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue g Description     Description   m NumericWeight   8 0Numeric weight tot apply to this type of problem   1  mc Notes     Further notes   mj MaintType '   Maintenance Type   mLVAL +KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValueValidationRuleValidationTextFilterOrderByFormatCaption InputMask S Object_ID )   The objects unique ID\ Package_ID      0  mn Diagram_ID      0  m  Diagram ID] Version :     m  "1.0"C Note     W NType      0  m BorderStyle      0  m9 1Dash, dot ... depends on object - default = solid[ Backcolor      0  mP CreatedDate    =Date() Q ModifiedDate l   =Date()  Complexity   / 'Subjective Measure of object complexity   m  2p Effort    Estimated Effort   0  mO Status      mQAbstract      mX Tagged      0  m PDATA1   R JPrivate data - may be used for different reasons by different object types   mO PDATA2      mO PDATA3      mO PDATA4  LVAL ,    mO PDATA5      m` Name     Object name   m] BorderWidth      0  m[ Fontcolor      0  m] Bordercolor      0  mT Concurrency      mS Visibility      mT Persistence      mT Cardinality      mP GenType      mP GenFile      mF Header1 @    F Header2     N Phase      mN Scope      mH GenOption     GGenLinks     k Object_Type (   The object type   mN Alias      mO Author I     mS Stereotype V     mN Style      mS Classifier      mP ea_guid      mQPargLVALsentID      mGRunState     LVALKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLength [ Object_ID      0  mQFileName      mM Type      mC Note     KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption [ Object_ID      0  mS EffortType      mX EValue      0  mD Notes     O Effort      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthFilterOrderByValidationRuleValidationText DescriptionFormat InputMaskCaption [ Object_ID      0  mS Constraint      mX Weight      0  mD Notes     WConstraintType      mO Status      mLVALKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption [ Object_ID      0  mP Problem Q     mK ProblemNotes     O Status      mB DateReported    B DateResolved    P Version      mL ResolverNotes     T ProblemType U     mS ReportedBy      mS ResolvedBy      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControl DescriptionAllowZeroLengthValidationRuleValidationTextFilterOrderByFormat InputMaskCaption { Object_ID      0  m  Object metric applies to EValue   1 )Value to give this metric in this context   1  mf MetricType     Metric code    mD Notes      O Metric       mLVAL% &&&'''((())), &, ', (- )- *- +. ,KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormatCaption InputMask [ Object_ID      0  mT Requirement Q     mD Notes     O Status      m2 ReqID   R Stability      mS Difficulty      mQPriority      mM LastUpdate     Now() P ReqType U     mKKDValidationRuleValidationTextFilterOrderBy OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionFormat DecimalPlaces InputMaskCaption DefaultValueRequiredDisplayControlAllowZeroLength [ Object_ID       0  mN Value      mD Notes     7 PropertyID   QProperty      mLVAL% &&&'''((())), &, ', (- )- *- +. ,. -. ./ ///00011122 2 3 KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption [ Object_ID      0  mQRiskType      mX EValue      0  mD Notes     M Risk      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption [ Object_ID      0  mD Notes     V Time      0  mQResource      mM Role %     maPercentComplete      0  m? DateStart    = DateEnd    aLVALooKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthFilterOrderByValidationRuleValidationText DescriptionFormat InputMaskCaption [ Object_ID      0  mQTestType       mO Status      m[ TestClass      0  mD Notes     H InputData (    QAcceptanceCriteria C    K DateRun     =Now()F Results     N RunBy      mP CheckBy      mM Test      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption [ Object_ID      0  mU ScenarioType      mX EValue      0  mD Notes     QScenario      mLVAL)JFF84Eo+COBf}yA/kCX}S@CX}S@t_objecttrx*********** CX}S@CX}S@t_objecttests,,,,,,,,,,, )1{@RJ(nS@t_objectscenarios@1>>>22222220 @;1{@U2@t_objectrisks@0:::......., @/{@U2@t_objectrequires@/===1111111/KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue  ObjectType   0 (Type of Object e.g Actor, UseCase, Class   mComplexityWeight   3 +Factor to multiply complexty by for metrics   0  mKKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlFormat DecimalPlaces DefaultValueValidationRuleValidationTextFilterOrderBy Description InputMaskCaption T Object_Type      mZ DesignObject    Yes/No  jY ImageID      0  mT Description C     mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLength [ Object_ID      0  mL TRX O     mX Weight      0  mP TRXType      mD Notes     $?!"#$%&      !"#$%&(((((((((( ( ( ( ( (((((((((((((((((( (  (! ("(#($(%(&HHHHHHHH"H"H "H (H (H (H +H+H+H2H2H2H7H7H7H;H;H;H?H?H?HCHCHCHLH LH!LH"NH#NH$NH%PH&PIPITITITIYIYIYI^I^I ^I bI bI bI gIgIgIjIjIjInInInIsIsIsIIIIIIII I!I"I#I$I%I&JJJJJJJJJJ J J J J JJJJJJJJJJJJJJJJJJJ J!J"J#J$J%J&KKKKKKKKKK K           ! " #DLVALPqg]SI?j%ڂKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormatCaption InputMask [ Object_ID      0  mN Scope      mS Stereotype      mD Notes     8 OperationID   T ReturnArray      mQIsStatic      mT Concurrency      mH Behaviour     QAbstract      mM Name      mM Type      mH GenOption     U Synchronized      mL Pos      mN Const      mN Style      mD Pure     mO Throws      m?LVALUO@Nb%p6Sb)w:KKDValidationRuleValidationTextFilterOrderBy OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionFormat InputMaskCaption DefaultValueRequiredAllowZeroLengthDisplayControl QProperty       mD Notes      T Description       mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption ] OperationID      0  mD Notes     V PostCondition      mM Type      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthFilterOrderByValidationRuleValidationText DescriptionFormat InputMaskCaption ] OperationID      0  mD Notes     M Name      mM Type      mP Default      mL Pos      mE Const     mN Style      mM Kind      mLVALKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValueValidationRuleValidationTextFilterOrderByFormat InputMaskCaption Y Notes     Further notes  ^ Role s    Role Name   mg Description s    Description   mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValueValidationRuleValidationTextFilterOrderByFormat InputMaskCaption  NumericWeight 6  E =Numeric factor to apply to metric - accepts decimal fractions   1  mc Notes     Further notes   mg ProblemType s    Metric Code   mq Description s   Description of Metric   mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption ] OperationID      0  mM Type      mD Notes     U PreCondition      m<LVALlJKKDd OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl QDatatype      mT Description      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValueValidationRuleValidationTextFilterOrderBy DescriptionFormatCaption InputMask [ Parent_ID      0  mP CreatedDate    =Date() Q ModifiedDate 6   =Date() 7 Package_ID T  D Notes     M Name      mP ea_guid      mP XMLPath      mL IsControlled     mB LastLoadDate    B LastSaveDate    P Version      mI Protected     mQPkgOwner      mS UMLVersion      mF UseDTD     mF LogXML     mQCodePath      mR Namespace      mLVALt!"#$%&     KKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption DefaultValue N Roles      mN Notes      mO Phone1 7     mO Phone2      mO Mobile      mL Fax      mM Name      mU Organisation      mN Email       mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue q Description N   Description of Metric   m NumericWeight   E =Numeric factor to apply to metric - accepts decimal fractions   1  mc Notes     Further notes   mm Requirement    Rrequirement Code   mLVALK!"#$%&     KKD OrderByOn RowHeight ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlFilterOrderBy!  M Type      mGTemplate -    KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLength ] ConnectorID      0  mS Constraint O     mWConstraintType      mD Notes     U ConnectorEnd      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue o Description    Description of Risk   m NumericWeight   E =Numeric factor to apply to metric - accepts decimal fractions   0  mc Notes     Further notes   m^ Risk     Risk Code   mLVAL~ok\MI:+' xtKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthFormatFilterOrderByValidationRuleValidationText Description InputMaskCaption ] RootPackage       0  mQFilename      m]ProcessChildren    Yes/No  jZ ShowDiagrams    Yes/No  jP Heading V     mZ Requirements    Yes/No  jZ Associations    Yes/No  jW Scenarios    Yes/No  j[ ChildDiagrams    Yes/No  jX Attributes    Yes/No  jU Methods    Yes/No  jS TemplateID %     m[ ImageType      0  mT Paging    Yes/No  jD Intro     b Resources    Yes/No  Yes  jd Constraints    Yes/No  Yes  jU Details    Yes/No  jT Tagged    Yes/No  jZLVALyHj!"#$%&      !"#$%&(KKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption DefaultValue S Stereotype      mR AppliesTo      mT Description      mKKDu OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlFilterOrderBy O Status E     mT Description      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue q Description s   Description of Metric   m NumericWeight 6  E =Numeric factor to apply to metric - accepts decimal fractions   1  mc Notes     Further notes   mh ScenarioType s    Metric Code   mLVALdA!"#$%&     KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue q Description s   Description of Metric   m NumericWeight 6  E =Numeric factor to apply to metric - accepts decimal fractions   1  mc Notes     Further notes   mdTestType s    Metric Code   mKKDd OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl R TestClass      mT Description      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue n Description s   Description of TCF   mi Weight 6    Weighting   1  m] Notes    Comment   mj TCFID s   Technical Factor Coe   mW Value      0  mLVALyKKDValidationRuleValidationTextFilterOrderBy OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionFormat InputMaskCaption DefaultValueRequiredAllowZeroLengthDisplayControl R QueryName       mP NewName       mU FixCode    Yes/No   jKKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValueValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption R TableName o     mZRelOrder      0  mP NewName      mU FixCode    Yes/No  jKKDu OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlFilterOrderBy QProperty      mN Value      mKKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue q Description    Description of Metric   m NumericWeight   E =Numeric factor to apply to metric - accepts decimal fractions   1  mY Notes     Further notes  1qGE S@ S@t_snapshot@777+++++++) @B*S@*S@t_phaseN@444(((((((& @lX@|`n@usysOldTablesE@=:::......., @rA@U2E Eۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o E B Bۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o B l lۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o l + +ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o + * *ۇ O8V#jKrvwlrV#jKV#jKV#jKV#jKrvwlrV#jKV#jKV#jKV#jKV#o LVALKKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlValidationRuleValidationTextFilterOrderBy DescriptionFormat InputMaskCaption DefaultValue ? IssueDate    O Status      mD Notes     B DateResolved    I Resolution     N Issue      mN Owner      mQResolver      m4 IssueID   QCategory      mQPriority      mQSeverity      mLVAL o6~CTp0w ^|-@t 1@Tablesqdf_object5+% l|-@l|-@Tablesqdf_diagramlink:+% l|-@l|-@Tablesqdf_attribute8+% d<@d<@Tablesq_visibleobject:+% <@@Tablesq_ucmetrics6+% @l<@c<@Tablesq_tcf0+% .<@.<@Tablesq_sumtcf3+% ֱ<@ֱ<@Tablesq_sumecf3+% 5<@s<@Tablesq_resource5+% I<@l<@Tablesq_realizes26+% =<@&{<@Tablesq_realizes16+% <@(pz@Tablesq_pkgobject6+% uD<@ '-{ @Tablesq_packages5+%  <@ <@Tablesq_objecttests8+%  <@K<@Tabʾt_connectorq_packages  ʾt_connectorq_packages  QLVAL]Gh)JFF84Eo+COBf}yA/OC3{@U2@t_objecttrx-@2888,,,,,,,* @r2{@FSߝT@t_objecttests@:::......., @)1{@RJ(nS@t_objectscenarios@1>>>22222220 @;1{@U2@t_objectrisks@0:::......., @/{@U2@t_objectrequires@/===1111111/ @Zb@U2@t_objectpropertiesi@/???33333331 @ /{@E(nS@t_objectproblemsS@.===1111111/ @;R.{@U2@t_objectmetrics@.<<<0000000. @-{@g2@t_objectfiles@-:::......., @",{@U2@t_objectconstraint@-???33333331 @%KKD OrderByOn ColumnWidth ColumnOrder ColumnHidden DecimalPlaces DefaultValueRequiredDisplayControlAllowZeroLengthFilterOrderByValidationRuleValidationText DescriptionFormat InputMaskCaption [ Object_ID      0  m[ TestClass      0  mD Notes     H InputData (    QAcceptanceCriteria C    K DateRun     =Now()F Results     N RunBy      mP CheckBy      mM Test      mQTestType       mO Status      m qg            !!""##$$%%&&''(())*nd @sz@TEXTLogicalData Model1.0PHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=0;OpParams=1;ShowSeqNotes=0;ScalePrintImage=0;PaperSize=9;ShowIcons=1;SuppressCollabNumber=0;HideProps=0;HideParents=0;UseAlias=0;HideAtts=0;HideOps=0;HideStereo=0;HideElemStereo=0;FormName=;{2FBE7B3F-756C-46a0-90EE-93429FDA065D}locked=false;orientation=0;width=0;names=false;color=0;bold=false;fcol=0;;cls=0;e@ T.FFEEEEB81 nd @sz@TEXTLogicalData Model1.0PHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=0;OpParams=1;ShowSeqNotes=0;ScalePrintImage=0;PaperSize=9;ShowIcons=1;SuppressCollabNumber=0;HideProps=0;HideParents=0;UseAlias=0;HideAtts=0;HideOps=0;HideStereo=0;HideElemStereo=0;FormName=;{2FBE7B3F-756C-46a0-90EE-93429FDA065D}locked=false;orientation=0;width=0;names=false;color=0;bold=false;fcol=0;;cls=0;e@ T.FFEEEEB81 ALVALMKKDi AccessVersionBuildTrack Name AutoCorrect InfoPerform Name AutoCorrectProjVer EADiffViewsF  07.53     t_attribute|t_attributeconstraints|t_attributetag|t_authors|t_cardinality|t_category|t_clients|t_complexitytypes|t_connector|t_connectorconstraint|t_connectortag|t_connectortypes|t_constants|t_constrainttypes|t_datatypes|t_diagram|t_diagramlinks|t_diagramobjects|t_diagramtypes|t_document|t_ecf|t_efforttypes|t_files|t_genopt|t_glossary|t_html|t_image|t_implement|t_issues|t_lists|t_mainttypes|t_method|t_metrictypes|t_object|t_objectconstraint|t_objecteffort|t_objectfiles|t_objectmetrics|t_objectproblems|t_objectproperties|t_objectrequires|t_objectresource|t_objectrisks|t_objectscenarios|t_objecttests|t_objecttrx|t_objecttypes|t_ocf|t_operation|t_operationparams|t_operationposts|t_operationpres|t_operationtag|t_package|t_palette|t_paletteitem|t_phase|t_primitives|t_problemtypes|t_projectroles|t_propertytypes|t_requiretypes|t_resources|t_risktypes|t_roleconstraint|t_rtf|t_rtfreport|t_rules|t_scenariotypes|t_script|t_secgroup|t_secgrouppermission|t_seclocks|t_secpermission|t_secpolicies|t_secuser|t_secusergroup|t_secuserpermission|t_snapshot|t_statustypes|t_stereotypes|t_taggedvalue|t_tasks|t_tcf|t_template|t_testclass|t_testplans|t_testtypes|t_trxtypes|t_umlpattern|t_version|t_xref|t_xrefsystem|t_xrefuser|usys_system|usysOldTables|usysQueries|usysTablesVCineColor StereotypeVirtualInheritance LinkAccessPDATA1PDATA2PDATA3PDATA4PDATA5 DiagramIDea_guidSourceConstraintDestConstraintSourceIsNavigableDestIsNavigableIsRootIsLeafIsSpecSourceChangeableDestChangeableSourceTSDestTS StateFlags ActionFlagsIsSignal IsStimulusDispatchActionTarget2StyleExSourceStereotypeDestStereotype SourceStyle DestStyle EventFlags SourceRoleDestRole]_`a6bcde7fg hi jk Connector_IDConnector_Type DiagramID End_Object_IDIDX_GUID PrimaryKeyStart_Object_ID]]]]]]I] ]L ] ]M ] ]GGE ,o[{@o[{@{1E62D3A8-F3CF-4E2A-B0A0-A7266C98C7DB}GGGGGGGGGGE >*<@Tu@zz_q_implements2I@@$@I==1111111/ @xhan@U2@usysTables@@777+++++++) @>X@|`n@usysOldTablesE@=:::......., @rA@U2@usys_system-@=888,,,,,,,* @AF(nS@AF(nS@t_xrefuser++++++++++) AF(nS@AF(nS@t_xrefsystem----------+ +k2@+k2@t_xref''''''''''% vF(nS@vF(nS@t_versionp@666*******( @AF(nS@AF(nS@t_umlpatternq@999-------+ @>G{@U2@t_testtypes@<888,,,,,,,* @AF(nS@AF(nS@t_testplanse@888,,,,,,,* @`F{@U2@t_testclass#@<888,,,,,,,* @f)E{@U2@t_tcf@<222&&&&&&&$ @, 1@E(nS@t_tasks((((((((((& LVAL @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ a=  t_objectt_object}t_methodt_method-Mt_connectortypest_connectortypesqt_connectort_connectorP ft_metrictypest_metrictypes_st_objectmetricst_objectmetricsf)t_diagramt_diagram#ft_diagramobjectst_diagramobjectsqyt_object_1t_object~t_attributet_attributest_diagramtypest_diagramtypesTt_packaget_package2m$H    robate'{5318DB33-47A8-41c5-90C4-C25C03E8CA97}ConstStatusTypeImplementedEE:+ate'{36C52C56-583F-4851-B0C1-A24F78965CE4}ConstStatusTypeBuild??:+ate'{2BE502E4-E7C3-415e-8534-0F609F75A224}ConstStatusTypeValidatedCC:+ate'{976DB1EA-71E8-432f-9FDC-935D8706F4FF}ConstStatusTypeApprovedBB:+ate'{F2AC17B8-847A-4ac5-8F1A-270B1F2AF073}ConstStatusTypeMandatoryCC:+ate'{78129304-34A8-483b-95F6-BDFD0F9C1F18}ConstStatusTypeProposedBB:+ LVALNKKDi AccessVersionBuildTrack Name AutoCorrect InfoPerform Name AutoCorrectProjVer EADiffViewsF  07.53     t_attribute|t_attributeconstraints|t_attributetag|t_authors|t_cardinality|t_category|t_clients|t_complexitytypes|t_connector|t_connectorconstraint|t_connectortag|t_connectortypes|t_constants|t_constrainttypes|t_datatypes|t_diagram|t_diagramlinks|t_diagramobjects|t_diagramtypes|t_document|t_ecf|t_efforttypes|t_files|t_genopt|t_glossary|t_html|t_image|t_imSELECT Object_1.Object_ID AS SourceID, Object_1.Name AS SourceName, Object_1.Object_Type AS SourceType, t_connector.Connector_Type, t_object.Object_Type AS DestType, t_object.Name AS DestName, t_object.Object_ID AS DestID, t_connector.Connector_ID FROM t_object Object_1, t_connector, t_object WHERE t_connector.End_Object_ID = Object_1.Object_ID AND t_object.Object_ID = t_connector.Start_Object_ID AND Object_1.Object_ID=59SELECT t_object.Object_ID AS SourceID, t_object.Name AS SourceName, t_object.Object_Type AS SourceType, t_connector.Connector_Type, Object_1.Object_Type AS DestType, Object_1.Name AS DestName, Object_1.Object_ID AS DestID, t_connector.Connector_ID FROM t_object, t_connector, t_object Object_1 WHERE t_connector.End_Object_ID @PROP=@NAME=isIndirectlyInstantiated@ENDNAME;@TYPE=boolean@ENDTYPE;@VALU=true@ENDVALU;@PRMT=@ENDPRMT;@ENDPROP; KKDi AccessVersionBuildTrack Name AutoCorrect InfoPerform Name AutoCorrectProjVer EADiffViewsF  07.53     t_attribute|t_attributeconstraints|t_attributetag|t_authors|t_cardinality|t_category|t_clients|t_complexitytypes|t_connector|t_connectorconstraint|t_connectortag|t_connectortypes|t_constants|t_constrainttypes|t_datatypes|t_diagram|t_diagramlinks|t_diagramobjects|t_diagramtypes|t_document|t_ecf|t_efforttypes|t_files|t_genopt|t_glossary|t_html|t_image|t_implement|t_issues|t_lists|t_mainttypes|t_method|t_metrictypes|t_object|t_objectconstraint|t_objecteffort|t_objectfiles|t_objectmetrics|t_objectproblems|t_objectproperties|t_objectrequires|t_objectresource|t_objectrisks|t_objectscenarios|t_objectt {D9D3378B-6429-4413-8664-CCC78EBFFC99}CustomPropertieselement propertyPublicn@U{175C5853-7CF9-42b3-8796-F3AA4ACBFB3B}YMMMMMMG7' LVAL XKKD OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue DescriptionFilterOrderByValidationRuleValidationTextFormatCaption InputMask 9 Connector_ID   WConnector_Type p     maStart_Object_ID      0  m_ End_Object_ID %     0  mXTop_Start_Label b     mV Top_Mid_Label      mV Top_End_Label      mXBtm_Start_Label      mV Btm_Mid_Label      mV Btm_End_Label      m\ Start_Edge      0  mZEnd_Edge      0  mZPtStartX      0  mZPtStartY      0  mX PtEndX      0  mX PtEndY      0  m SeqNo   6 .For sequence diagrams - stores sequence number   0  m HeadStyle   : 2Head style - filled, open ... depends on connector   0  m LineStyle   1 )Line is dot, dash... depends on connector LVAL Y  0  m RouteStyle   0 (Route line direct/auto ...user selection   0  mP SubType      mS SourceCard 7     mU SourceAccess      mV SourceElement      mQDestCard      mS DestAccess      mT DestElement      mR Direction v     mD Notes     WSourceRoleType      mMSourceRoleNote     ZSourceContainment      mcSourceIsAggregate      0  maSourceIsOrdered      0  mU DestRoleType      mK DestRoleNote     XDestContainment      maDestIsAggregate      0  m_ DestIsOrdered      0  mXSourceQualifier      mV DestQualifier      m| IsBold   $ LLVAL Zine style is bold or normal   0  mp LineColor    Color of line   0  mS Stereotype      m[VirtualInheritance      mS LinkAccess      mO PDATA1      mO PDATA2      mO PDATA3      mO PDATA4      mO PDATA5      m[ DiagramID      0  mM Name H     mP ea_guid      mS SourceRole      mQDestRole      mYSourceConstraint      mWDestConstraint      mQSourceIsNavigable     mODestIsNavigable     mF IsRoot     mF IsLeaf     mF IsSpec     mYSourceChangeable      mWDestChangeable      mQSourceTS     LVAL mO DestTS      mS StateFlags      mT ActionFlags      mHIsSignal     mJ IsStimulus     mWDispatchAction      mP Target2      mF StyleEx     YSourceStereotype      mWDestStereotype      mJ SourceStyle     H DestStyle     S EventFlags      mLVAL>NAA!****!!!!!!!!  !  !  !  !  !!!!!!!!!!!!!!!!!!!  !!!!""!##!$$!%%!&&!''!((!))!**!++*,*-*.*/*0*1*2*3*4* 5* 6* 7* 8* 9*:*;*<*=*>*?*@*A*B*****!'37t_object.ActionFlags(36t_object.StateFlags'35t_object.IsActive%34t_object.IsSpec#33@PROP=@NAME=kind@ENDNAME;@TYPE=TransitionKind@ENDTYPE;@VALU=@ENDVALU;@PRMT=@ENDPRMT;@ENDPROP;@PROP=@NAME=isSubstitutable@ENDNAME;@TYPE=boolean@ENDTYPE;@VALU=@ENDVALU;@PRMT=@ENDPRMT;@ENDPROP;@PROP=@NAME=isSubstitutable@ENDNAME;@TYPE=boolean@ENDTYPE;@VALU=@ENDVALU;@PRMT=@ENDPRMT;@ENDPROP;@PROP=@NAME=isSubstitutable@ENDNAME;@TYPE=boolean@ENDTYPE;@VALU=@ENDVALU;@PRMT=@ENDPRMT;@ENDPROP;&h88--     NULL$;&StateFlagsNULL";%IsActive0;$IsSpec0;#IsLeaf0;"IsRoot0;nd\@-ndt_packagendt_objectt_object_1ndt_diagramobjectsndt_objectt_objectt_package*@-%?t_objectt_object_1*@-&?t_objectt_diagramobjects/@-, ?Bt_object.Classifier_guid,3At_object.Cardinality(3@t_object.Visibility'3?t_object.Concurrency(3> t_object.TPos!3=t_object.StyleEx$3<t_object.Persistence(3;t_object.ParentID%3:t_object.Multiplicity)39t_object.PackageFlags)38 {E9180DE1-800E-46fa-B799-388ED5E81F5A}CustomPropertiesconnector propertyPublic]@[{6F8D296A-CFF7-420b-94AF-65A68FAE5F93}[OOOOOOI7'  {8AAF19F7-EC93-4dda-ADD1-69A07CC671D7}CustomPropertiesconnector propertyPublica@[{E824691D-2AE7-4c9c-8408-881A2B85516F}[OOOOOOI7'  {DF243A69-1029-4c4c-A1A0-C821A1DF9623}CustomPropertiesconnector propertyPublica@[{03052911-3625-4472-8C6B-5E1742FED753}[OOOOOOI7'  {DB1C706A-470A-45ed-89DA-601821419545}CustomPropertiesconnector propertyPublica@[{C3D18D92-3A5C-4112-9958-926A259BAE24}[OOOOOOI7'    ctBottomSequence ObjectStyle Instance_IDTo  DiagramIDObjectID PrimaryKey-81D5-714093282A5D} DiagramIDObjectID PrimaryKeySELECT Object_1.Object_ID AS SourceID, Object_1.Name AS SourceName, Object_1.Object_Type AS SourceType, t_connector.Connector_Type, t_object.Object_Type AS DestType, t_object.Name AS DestName, t_object.Object_ID AS DestID, t_connector.Connector@@@ G@\Mode=2;EOID=CDDEF3BC;SOID=CDDEF3BC;<< O \ON      t_objectt_object_1t_diagramobjectst_objectt_objectt_package*@%?t_objectt_object_1*@&?t_objectt_diagramobjects/@, ?Bt_object.Classifier_guid,3At_object.Cardinality(3@t_object.Visibility'3?t_object.Concurrency(3> t_object.TPos!3=t_object.StyleEx$3<t_object.Persistence(3;t_object.ParentID%3:t_object.Multiplicity)3@@@# Q<=jSource -> DestinationAggregationStrongPublicPublic{B53E96AD-469B-4754-8A01-FCF41E3778BE}{{ujjUU5 ?\ ŴQ Q >DSource -> DestinationGeneralizationPublicPublicSX=-24;SY=-16;{E824691D-2AE7-4c9c-8408-881A2B85516F}~~~xxxjjUU5 ?Q B<;**Source -> DestinationAssociationPublic0..*PublicUnspecifiedUnspecified0{A9112D1C-DCB6-4040-B466-D5F560898B33}homeœ{{uuujjUU5 Q <A;**Source -> DestinationAssociationPublic1PublicUnspecifiedUnspecified0SX=8;SY=5;EX=8;EY=5;{161BF4FA-8F48-441f-AF1F-D36014D57A1F}bathroomӭ|{{uuujjUU5 QA=Source -> DestinationGeneralizationPublicPublic{03052911-3625-4472-8C6B-5E1742FED753}~~~xxxjjUU5 ?Q><diagBi-DirectionalAssociation1Public1PublicUnspecifiedUnspecified0SX=6;SY=-12;EX=-44;EY=-9;EDGE=1;{9F0FF178-300F-45f4-B31F-9633AF770E44}kitchenhouseٳ|||||vuuonnccUU5Ն Q>=Source -> DestinationGeneralizationPublicPublicEX=37;EY=3;{C3D18D92-3A5C-4112-9958-926A259BAE24}~~~xxxjjUU5 ?Q=<Source -> DestinationAggregationStrong1..*Public1PublicUnspecifiedUnspecified0SX=-2;SY=-1;EX=-2;EY=-1;{F15A2B25-0DA9-4203-8FC9-25645610B5E5}roomhouseợ{ujjUU5 ]gC`y'B]jd^XRLF@:4.(" ztnhb\VPJD>82,& @@ DDLInterBasedecimaldecimal?8888881(% DDLSybasebitboolean8111111.(% DDLPostgreSQLbyteablob;7777772(% 2DDLMySqlNVARCHARnvarchar=555555-(% DDLPostgreSQLtimestampdatetimeC;;;;;;2(% DDLPostgreSQLbooleanboolean@9999992(% DDLMSAccessLong IntegerbigintB<<<<<<0(%  DDLInterBasecharchar95555551(% DDLInterBaseblob sub_type 1textD@@@@@@1(% DDLSQL Server 2000smallmoneymoneyFAAAAAA7(% &&& DDLSybasedecimaldecimal<555555.(% DDLSybasemoneycurrency;333333.(% DDLSybaseintegerinteger<555555.(% DDLSQL Server 2000bigintbigintC======7(% DDLPostgreSQLtexttext:6666662(% & DDLPostgreSQLdecimaldecimal@9999992(% @ DDLPostgreSQLcharchar:6666662(%  DDLDB2CHARchar3//////+(% DDLMySqlTIMESTAMPtimestamp?666666-(% @2DDLSQL Server 2000varcharvarcharE>>>>>>7(% DDLSQL Server 2000smallintsmallintG??????7(% DDLPostgreSQLnumbercurrency@8888882(% DDLPostgreSQLsmallintsmallintB::::::2(% DDLSQL Server 2000tinyinttinyintE>>>>>>7(% yLVALdș2dŕK   SX=36;SY=-9;EX=45;EY=-9;EDGE=1;$LLB=;LLT=CX=40:CY=15SX=36;SY=-9;EX=45;EY=-9;EDGE=1;$LLB=;LLT=CX=40:CY=15:OX=-17:OY=-1:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:SSX=6SX=-2;SY=-1;EX=-2;EY=-1;EDGE=1;$LLB=CX=26:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LLT=CX=40:CY=15:OX=-12:OY=-3:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LMT=;LMB=;LRT=CX=44:CY=15:OX=-6:OY=-11:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LRB=CX=16:CY=15:OX=-6:OY=-6:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;SX=-2;SY=-1;EX=-2;EY=-1;EDGE=1;$LLB=CX=26:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LLT=CX=40:CY=15:OX=-12:OY=-3:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LMT=;LMB=;LRT=CX=44:CY=15:OX=-6:OY=-11:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LRB=CX=16:CY=15:OX=-6:OY=-6:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;SX=6;SY=-12;EX=-44;EY=-9;EDGE=1;$LLB=CX=16:CY=15:OX=13:OY=-3:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LLT=CX=49:CY=15:OX=0:OY=-14:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LMT=;LMB=;LRT=CX=44:CY=15:OX=-10:OY=-1:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LRB=CX=16:CY=15:OX=-23:OY=-4:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;SX=36;SY=-9;EX=45;EY=-9;EDGE=1;$LLB=;LLT=CX=40:CY=15:OX=-17:OY=-1:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LMT=;LMB=;LRT=;LRB=;EDGE=2;$LLB=;LLT=;LMT=;LMB=;LRT=CX=43:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LRB=;EDGE=1;$LLB=;LLT=CX=40:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LMT=;LMB=;LRT=;LRB=;EDGE=1;$LLB=;LLT=CX=40:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LMT=;LMB=;LRT=;LRB=;EDGE=1;$LLB=;LLT=CX=40:CY=15:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=0:DIR=0:;LMT=;LMB=;LRT=;LRB=;||:t222l*      g@ FMode=3;EOID=1CE36E20;SOID=BDEA24A9;<< O0@_aMode=3;EOID=3D79E0A4;SOID=81FBAF85;<< O0g@^aMode=3;EOID=3D79E0A4;SOID=31760B86;<< O0g@]aMode=3;EOID=3D79E0A4;SOID=EE2397B7;<< O0 g@\aMode=3;EOID=3D79E0A4;SOID=E585EE32;<< O0 g@[aMode=3;EOID=3D79E0A4;SOID=DFC93F21;<< O 4@FMode=3;EOID=E58486A8;SOID=BDEA24A9;<< O @ FMode=3;EOID=CDDEF3BC;SOID=12DDDFF9;<< O @FMode=3;EOID=5DECEEC9;SOID=CDDEF3BC;<< O&@FMode=3;EOID=BFDAC143;SOID=5DECEEC9;<< OM@baMode=3;EOID=CDDEF3BC;SOID=BDEA24A9;<< O1@FMode=3;EOID=BFDAC143;SOID=BDEA24A9;<< OJ@caMode=3;EOID=CDDEF3BC;SOID=BFDAC143;<< Orgen-0.7.0/test/testmodel/class_model_checker.rb0000644000004100000410000001216312352210062021752 0ustar www-datawww-datarequire 'metamodels/uml13_metamodel' require 'metamodels/uml13_metamodel_ext' module Testmodel # Checks the UML Class model elements from the example model # module ClassModelChecker def checkClassModel(envUML) # check main package mainPackage = envUML.find(:class => UML13::Package, :name => "HouseMetamodel").first assert_not_nil mainPackage # check Rooms package subs = mainPackage.ownedElement.select{|e| e.is_a?(UML13::Package)} assert_equal 1, subs.size roomsPackage = subs.first assert_equal "Rooms", roomsPackage.name # check main package classes classes = mainPackage.ownedElement.select{|e| e.is_a?(UML13::Class)} assert_equal 3, classes.size houseClass = classes.find{|c| c.name == "House"} personClass = classes.find{|c| c.name == "Person"} meetingPlaceClass = classes.find{|c| c.name == "MeetingPlace"} cookingPlaceInterface = mainPackage.ownedElement.find{|e| e.is_a?(UML13::Interface) && e.name == "CookingPlace"} assert_not_nil houseClass assert_not_nil personClass assert_not_nil meetingPlaceClass assert_not_nil cookingPlaceInterface # check Rooms package classes classes = roomsPackage.ownedElement.select{|e| e.is_a?(UML13::Class)} assert_equal 3, classes.size roomClass = classes.find{|c| c.name == "Room"} kitchenClass = classes.find{|c| c.name == "Kitchen"} bathroomClass = classes.find{|c| c.name == "Bathroom"} assert_not_nil roomClass assert_not_nil kitchenClass assert_not_nil bathroomClass # check Room inheritance assert_equal 2, roomClass.specialization.child.size assert_not_nil roomClass.specialization.child.find{|c| c.name == "Kitchen"} assert_not_nil roomClass.specialization.child.find{|c| c.name == "Bathroom"} assert_equal 2, kitchenClass.generalization.parent.size assert_equal roomClass.object_id, kitchenClass.generalization.parent.find{|c| c.name == "Room"}.object_id assert_equal meetingPlaceClass.object_id, kitchenClass.generalization.parent.find{|c| c.name == "MeetingPlace"}.object_id assert_equal 1, bathroomClass.generalization.parent.size assert_equal roomClass.object_id, bathroomClass.generalization.parent.first.object_id assert_not_nil kitchenClass.clientDependency.find{|d| d.stereotype.name == "implements"} assert_equal cookingPlaceInterface.object_id, kitchenClass.clientDependency.supplier.find{|c| c.name == "CookingPlace"}.object_id assert_equal kitchenClass.object_id, cookingPlaceInterface.supplierDependency.client.find{|c| c.name == "Kitchen"}.object_id # check House-Room "part of" association assert_equal 1, houseClass.localCompositeEnd.size roomEnd = houseClass.localCompositeEnd.first.otherEnd assert_equal UML13::Association, roomEnd.association.class assert_equal roomClass.object_id, roomEnd.type.object_id assert_equal "room", roomEnd.name assert_equal UML13::Multiplicity, roomEnd.multiplicity.class assert_equal "1", roomEnd.multiplicity.range.first.lower assert_equal "*", roomEnd.multiplicity.range.first.upper assert_equal 1, roomClass.remoteCompositeEnd.size assert_equal houseClass.object_id, roomClass.remoteCompositeEnd.first.type.object_id assert_equal "house", roomClass.remoteCompositeEnd.first.name # check House OUT associations assert_equal 2, houseClass.remoteNavigableEnd.size bathEnd = houseClass.remoteNavigableEnd.find{|e| e.name == "bathroom"} kitchenEnd = houseClass.remoteNavigableEnd.find{|e| e.name== "kitchen"} assert_not_nil bathEnd assert_not_nil kitchenEnd assert_equal UML13::Association, bathEnd.association.class assert_equal UML13::Association, kitchenEnd.association.class assert_equal "1", kitchenEnd.multiplicity.range.first.lower assert_equal "1", kitchenEnd.multiplicity.range.first.upper # check House IN associations assert_equal 3, houseClass.localNavigableEnd.size homeEnd = houseClass.localNavigableEnd.find{|e| e.name == "home"} assert_not_nil homeEnd assert_equal UML13::Association, homeEnd.association.class assert_equal "0", homeEnd.multiplicity.range.first.lower assert_equal "*", homeEnd.multiplicity.range.first.upper # check House all associations assert_equal 4, houseClass.associationEnd.size end def checkClassModelPartial(envUML) # HouseMetamodel package is not part of the partial export mainPackage = envUML.find(:class => UML13::Package, :name => "HouseMetamodel").first assert_nil mainPackage roomsPackage = envUML.find(:class => UML13::Package, :name => "Rooms").first assert_not_nil roomsPackage roomClass = envUML.find(:class => UML13::Class, :name => "Room").first assert_not_nil roomClass # House is created from an EAStub houseClass = roomClass.remoteCompositeEnd.first.type assert_not_nil houseClass assert_equal "House", houseClass.name # House is not in a package since it's just a stub assert houseClass.namespace.nil? # in the partial model, House has only 3 (not 4) associations # since the fourth class (Person) is not in Rooms package assert_equal 3, houseClass.associationEnd.size end end endrgen-0.7.0/test/testmodel/ea_testmodel_partial.xml0000644000004100000410000005244012352210062022361 0ustar www-datawww-data Enterprise Architect 2.5 rgen-0.7.0/test/testmodel/ea_testmodel_regenerated.xml0000644000004100000410000021557012352210062023217 0ustar www-datawww-data Enterprise Architect 2.5 rgen-0.7.0/test/testmodel/ea_testmodel.xml0000644000004100000410000021531012352210062020642 0ustar www-datawww-data Enterprise Architect 2.5 HouseMetamodel Rooms HouseExampleModel rgen-0.7.0/test/testmodel/object_model_checker.rb0000644000004100000410000000463712352210062022122 0ustar www-datawww-datarequire 'metamodels/uml13_metamodel' require 'metamodels/uml13_metamodel_ext' module Testmodel # Checks the UML Object model elements from the example model # module ObjectModelChecker # convenient extension for this test only module UML13::ClassifierRole::ClassModule def classname taggedValue.find{|tv| tv.tag == "classname"}.value end end def checkObjectModel(envUML) # check main package mainPackage = envUML.find(:class => UML13::Package, :name => "HouseExampleModel").first assert_not_nil mainPackage eaRootCollaboration = mainPackage.ownedElement.find{|e| e.is_a?(UML13::Collaboration) && e.name == "Collaborations"} assert_not_nil eaRootCollaboration # check main package objects objects = eaRootCollaboration.ownedElement.select{|e| e.is_a?(UML13::ClassifierRole)} assert_equal 6, objects.size someone = objects.find{|o| o.name == "Someone"} assert_equal "Person", someone.classname someonesHouse = objects.find{|o| o.name == "SomeonesHouse"} assert_equal "House", someonesHouse.classname greenRoom = objects.find{|o| o.name == "GreenRoom"} assert_equal "Room", greenRoom.classname yellowRoom = objects.find{|o| o.name == "YellowRoom"} assert_equal "Room", yellowRoom.classname hotRoom = objects.find{|o| o.name == "HotRoom"} assert_equal "Kitchen", hotRoom.classname wetRoom = objects.find{|o| o.name == "WetRoom"} assert_equal "Bathroom", wetRoom.classname # Someone to SomeonesHouse assert someone.associationEnd.otherEnd.getType.is_a?(Array) assert_equal 1, someone.associationEnd.otherEnd.getType.size houseEnd = someone.associationEnd.otherEnd[0] assert_equal someonesHouse.object_id, houseEnd.getType.object_id assert_equal "home", houseEnd.name # Someone to SomeonesHouse assert someonesHouse.localCompositeEnd.otherEnd.is_a?(Array) assert_equal 4, someonesHouse.localCompositeEnd.otherEnd.size assert someonesHouse.localCompositeEnd.otherEnd.all?{|e| e.name == "room"} assert_not_nil someonesHouse.localCompositeEnd.otherEnd.getType.find{|o| o == yellowRoom} assert_not_nil someonesHouse.localCompositeEnd.otherEnd.getType.find{|o| o == greenRoom} assert_not_nil someonesHouse.localCompositeEnd.otherEnd.getType.find{|o| o == hotRoom} assert_not_nil someonesHouse.localCompositeEnd.otherEnd.getType.find{|o| o == wetRoom} end end endrgen-0.7.0/test/testmodel/ecore_model_checker.rb0000644000004100000410000001027712352210062021746 0ustar www-datawww-datarequire 'rgen/ecore/ecore' module Testmodel # Checks the ECore model elements created by transformation from the # UML Class model elements from the example model # module ECoreModelChecker include RGen::ECore def checkECoreModel(env) # check main package mainPackage = env.elements.select {|e| e.is_a? EPackage and e.name == "HouseMetamodel"}.first assert_not_nil mainPackage # check Rooms package assert mainPackage.eSubpackages.is_a?(Array) assert_equal 1, mainPackage.eSubpackages.size assert mainPackage.eSubpackages[0].is_a?(EPackage) roomsPackage = mainPackage.eSubpackages[0] assert_equal "Rooms", roomsPackage.name # check main package classes assert mainPackage.eClassifiers.is_a?(Array) assert_equal 4, mainPackage.eClassifiers.size assert mainPackage.eClassifiers.all?{|c| c.is_a?(EClass)} houseClass = mainPackage.eClassifiers.select{|c| c.name == "House"}.first personClass = mainPackage.eClassifiers.select{|c| c.name == "Person"}.first meetingPlaceClass = mainPackage.eClassifiers.select{|c| c.name == "MeetingPlace"}.first cookingPlaceInterface = mainPackage.eClassifiers.select{|c| c.name == "CookingPlace"}.first assert_not_nil houseClass assert_not_nil personClass assert_not_nil meetingPlaceClass assert_not_nil cookingPlaceInterface # check Rooms package classes assert roomsPackage.eClassifiers.is_a?(Array) assert_equal 3, roomsPackage.eClassifiers.size assert roomsPackage.eClassifiers.all?{|c| c.is_a?(EClass)} roomClass = roomsPackage.eClassifiers.select{|c| c.name == "Room"}.first kitchenClass = roomsPackage.eClassifiers.select{|c| c.name == "Kitchen"}.first bathroomClass = roomsPackage.eClassifiers.select{|c| c.name == "Bathroom"}.first assert_not_nil roomClass assert_not_nil kitchenClass assert_not_nil bathroomClass # check Room inheritance assert kitchenClass.eSuperTypes.is_a?(Array) assert_equal 3, kitchenClass.eSuperTypes.size assert_equal roomClass.object_id, kitchenClass.eSuperTypes.select{|c| c.name == "Room"}.first.object_id assert_equal meetingPlaceClass.object_id, kitchenClass.eSuperTypes.select{|c| c.name == "MeetingPlace"}.first.object_id assert_equal cookingPlaceInterface.object_id, kitchenClass.eSuperTypes.select{|c| c.name == "CookingPlace"}.first.object_id assert bathroomClass.eSuperTypes.is_a?(Array) assert_equal 1, bathroomClass.eSuperTypes.size assert_equal roomClass.object_id, bathroomClass.eSuperTypes[0].object_id # check House-Room "part of" association assert houseClass.eAllContainments.eType.is_a?(Array) assert_equal 1, houseClass.eAllContainments.eType.size roomRef = houseClass.eAllContainments.first assert_equal roomClass.object_id, roomRef.eType.object_id assert_equal "room", roomRef.name assert_equal 1, roomRef.lowerBound assert_equal(-1, roomRef.upperBound) assert_not_nil roomRef.eOpposite assert_equal houseClass.object_id, roomRef.eOpposite.eType.object_id partOfRefs = roomClass.eReferences.select{|r| r.eOpposite && r.eOpposite.containment} assert_equal 1, partOfRefs.size assert_equal houseClass.object_id, partOfRefs.first.eType.object_id assert_equal "house", partOfRefs.first.name assert_equal roomRef.object_id, partOfRefs.first.eOpposite.object_id # check House OUT associations assert houseClass.eReferences.is_a?(Array) assert_equal 3, houseClass.eReferences.size bathRef = houseClass.eReferences.find {|e| e.name == "bathroom"} kitchenRef = houseClass.eReferences.find {|e| e.name == "kitchen"} roomRef = houseClass.eReferences.find {|e| e.name == "room"} assert_not_nil bathRef assert_nil bathRef.eOpposite assert_not_nil kitchenRef assert_not_nil roomRef assert_equal 1, kitchenRef.lowerBound assert_equal 1, kitchenRef.upperBound assert_equal 1, roomRef.lowerBound assert_equal(-1, roomRef.upperBound) # check House IN associations houseInRefs = env.find(:class => EReference, :eType => houseClass) assert_equal 3, houseInRefs.size homeEnd = houseInRefs.find{|e| e.name == "home"} assert_not_nil homeEnd assert_equal 0, homeEnd.lowerBound assert_equal(-1, homeEnd.upperBound) end end endrgen-0.7.0/test/environment_test.rb0000644000004100000410000000441712352210062017407 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/environment' require 'rgen/metamodel_builder' class EnvironmentTest < Test::Unit::TestCase class Model attr_accessor :name end class ModelSub < Model end class ClassSuperA < RGen::MetamodelBuilder::MMBase end class ClassSuperB < RGen::MetamodelBuilder::MMBase end class ClassC < RGen::MetamodelBuilder::MMMultiple(ClassSuperA, ClassSuperB) has_attr 'name', String end class ClassSubD < ClassC end class ClassSubE < ClassC end def test_find_mmbase env = RGen::Environment.new mA1 = env.new(ClassSuperA) mB1 = env.new(ClassSuperB) mD1 = env.new(ClassSubD, :name => "mD1") mD2 = env.new(ClassSubD, :name => "mD2") mE = env.new(ClassSubE, :name => "mE") resultA = env.find(:class => ClassSuperA) assert_equal sortById([mA1,mD1,mD2,mE]), sortById(resultA) resultNamedA = env.find(:class => ClassSuperA, :name => "mD1") assert_equal sortById([mD1]), sortById(resultNamedA) resultB = env.find(:class => ClassSuperB) assert_equal sortById([mB1,mD1,mD2,mE]), sortById(resultB) resultNamedB = env.find(:class => ClassSuperB, :name => "mD1") assert_equal sortById([mD1]), sortById(resultNamedB) resultC = env.find(:class => ClassC) assert_equal sortById([mD1,mD2,mE]), sortById(resultC) resultD = env.find(:class => ClassSubD) assert_equal sortById([mD1,mD2]), sortById(resultD) end def test_find m1 = Model.new m1.name = "M1" m2 = ModelSub.new m2.name = "M2" m3 = "justAString" env = RGen::Environment.new << m1 << m2 << m3 result = env.find(:class => Model, :name => "M1") assert result.is_a?(Array) assert_equal 1, result.size assert_equal m1, result.first result = env.find(:class => Model) assert result.is_a?(Array) assert_equal sortById([m1,m2]), sortById(result) result = env.find(:name => "M2") assert result.is_a?(Array) assert_equal 1, result.size assert_equal m2, result.first result = env.find(:class => [Model, String]) assert result.is_a?(Array) assert_equal sortById([m1,m2,m3]), sortById(result) end private def sortById(array) array.sort{|a,b| a.object_id <=> b.object_id} end end rgen-0.7.0/test/metamodel_order_test.rb0000644000004100000410000001303412352210062020200 0ustar www-datawww-data$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'rgen/ecore/ecore' require 'rgen/array_extensions' class MetamodelOrderTest < Test::Unit::TestCase include RGen::ECore module TestMM1 extend RGen::MetamodelBuilder::ModuleExtension class Class11 < RGen::MetamodelBuilder::MMBase end module Module11 extend RGen::MetamodelBuilder::ModuleExtension DataType111 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType111" ,:literals => {:b => 1}) DataType112 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType112", :literals => {:b => 1}) class Class111 < RGen::MetamodelBuilder::MMBase end # anonymous classes won't be handled by the order helper, but will be in eClassifiers Class112 = Class.new(RGen::MetamodelBuilder::MMBase) # classes that are not MMBase won't be handled class Class113 end # modules that are not extended by the ModuleExtension are not handled module Module111 end # however it can be extendend later on module Module112 # this one is not handled by the order helper since Module112 doesn't have the ModuleExtension yet # however, it will be in eClassifiers class Class1121 < RGen::MetamodelBuilder::MMBase end end # this datatype must be in Module11 not Module112 DataType113 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType113", :literals => {:b => 1}) Module112.extend(RGen::MetamodelBuilder::ModuleExtension) # this datatype must be in Module11 not Module112 DataType114 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType114", :literals => {:b => 1}) module Module112 # this one is handled because now Module112 is extended class Class1122 < RGen::MetamodelBuilder::MMBase end end DataType115 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType115", :literals => {:b => 1}) DataType116 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType116", :literals => {:b => 1}) end DataType11 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType11", :literals => {:a => 1}) class Class12 < RGen::MetamodelBuilder::MMBase end class Class13 < RGen::MetamodelBuilder::MMBase end end # datatypes outside of a module won't be handled DataType1 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType1", :literals => {:b => 1}) # classes outside of a module won't be handled class Class1 < RGen::MetamodelBuilder::MMBase end module TestMM2 extend RGen::MetamodelBuilder::ModuleExtension TestMM1::Module11.extend(RGen::MetamodelBuilder::ModuleExtension) # this is a critical case: because of the previous extension of Module11 which is in a different # hierarchy, DataType21 is looked for in Module11 and its parents; finally it is not # found and the definition is ignored for order calculation DataType21 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType21", :literals => {:b => 1}) module Module21 extend RGen::MetamodelBuilder::ModuleExtension end module Module22 extend RGen::MetamodelBuilder::ModuleExtension end module Module23 extend RGen::MetamodelBuilder::ModuleExtension end # if there is no other class or module after the last datatype, it won't show up in _constantOrder # however, the order of eClassifiers can still be reconstructed # note that this can not be tested if the test is executed as part of the whole testsuite # since there will be classes and modules created within other test files DataType22 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType22", :literals => {:b => 1}) end def test_constant_order assert_equal ["Class11", "Module11", "DataType11", "Class12", "Class13"], TestMM1._constantOrder assert_equal ["DataType111", "DataType112", "Class111", "DataType113", "Module112", "DataType114", "DataType115", "DataType116"], TestMM1::Module11._constantOrder assert_equal ["Class1122"], TestMM1::Module11::Module112._constantOrder if File.basename($0) == "metamodel_order_test.rb" # this won't work if run in the whole test suite (see comment at DataType22) assert_equal ["Module21", "Module22", "Module23"], TestMM2._constantOrder end end def test_classifier_order # eClassifiers also contains the ones which where ignored in order calculation, these are expected at the end # (in an arbitrary order) assert_equal ["Class11", "DataType11", "Class12", "Class13"], TestMM1.ecore.eClassifiers.name assert_equal ["DataType111", "DataType112", "Class111", "DataType113", "DataType114", "DataType115", "DataType116", "Class112"], TestMM1::Module11.ecore.eClassifiers.name assert_equal ["Class1122", "Class1121"], TestMM1::Module11::Module112.ecore.eClassifiers.name # no classifiers in TestMM2._constantOrder, so the datatypes can appear in arbitrary order assert_equal ["DataType21","DataType22"], TestMM2.ecore.eClassifiers.name.sort end def test_subpackage_order assert_equal ["Module11"], TestMM1.ecore.eSubpackages.name assert_equal ["Module112"], TestMM1::Module11.ecore.eSubpackages.name assert_equal [], TestMM1::Module11::Module112.ecore.eSubpackages.name assert_equal ["Module21", "Module22", "Module23"], TestMM2.ecore.eSubpackages.name end end rgen-0.7.0/checksums.yaml.gz0000444000004100000410000000041612352210062015761 0ustar www-datawww-dataw:Se;RdA 9\`[[ZcqzeeyY̗iBJ8esjҰ<[˪d~g~p|"Сr JT!u*;r|xa=0˗fsf #I^ZѠ`JidM t]@Y֎+EDAFؿt6s@$kgzO9"u0V ^Zz9퍫cIYQ,B(j P\mѾ Ѷ}