rgen-0.6.6/0000755000175000017500000000000012243455557010660 5ustar ssmssmrgen-0.6.6/metadata.yml0000644000175000017500000002001612243455557013162 0ustar ssmssm--- !ruby/object:Gem::Specification name: rgen version: !ruby/object:Gem::Version version: 0.6.6 prerelease: platform: ruby authors: - Martin Thiede autorequire: bindir: bin cert_chain: [] date: 2013-08-30 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: [] 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 none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rgen rubygems_version: 1.8.24 signing_key: specification_version: 3 summary: Ruby Modelling and Generator Framework test_files: [] rgen-0.6.6/Rakefile0000644000175000017500000000306112243455557012325 0ustar ssmssmrequire 'rubygems/package_task' require 'rdoc/task' RGenGemSpec = Gem::Specification.new do |s| s.name = %q{rgen} s.version = "0.6.6" 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.6.6/MIT-LICENSE0000644000175000017500000000204112243455557012311 0ustar ssmssmCopyright (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.6.6/CHANGELOG0000644000175000017500000002034212243455557012073 0ustar ssmssm=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 rgen-0.6.6/README.rdoc0000644000175000017500000000406712243455557012475 0ustar ssmssm= 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.6.6/test/0000755000175000017500000000000012243455557011637 5ustar ssmssmrgen-0.6.6/test/xml_instantiator_test/0000755000175000017500000000000012243455557016275 5ustar ssmssmrgen-0.6.6/test/xml_instantiator_test/simple_xmi_to_ecore.rb0000644000175000017500000000565212243455557022657 0ustar ssmssmrequire '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, "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.6.6/test/xml_instantiator_test/simple_xmi_metamodel.rb0000644000175000017500000000216412243455557023022 0ustar ssmssm# 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.6.6/test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb0000644000175000017500000000332012243455557024742 0ustar ssmssmrequire '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.6.6/test/xml_instantiator_test/simple_ecore_model_checker.rb0000644000175000017500000001011412243455557024131 0ustar ssmssmrequire '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.6.6/test/xml_instantiator_test.rb0000644000175000017500000001135412243455557016626 0ustar ssmssm$:.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.6.6/test/util_test.rb0000644000175000017500000000016012243455557014175 0ustar ssmssm$:.unshift File.dirname(__FILE__) require 'util/file_cache_map_test' require 'util/pattern_matcher_test' rgen-0.6.6/test/util/0000755000175000017500000000000012243455557012614 5ustar ssmssmrgen-0.6.6/test/util/pattern_matcher_test.rb0000644000175000017500000000477612243455557017376 0ustar ssmssm$:.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.6.6/test/util/file_cache_map_test/0000755000175000017500000000000012243455557016552 5ustar ssmssmrgen-0.6.6/test/util/file_cache_map_test/testdir/0000755000175000017500000000000012243455557020230 5ustar ssmssmrgen-0.6.6/test/util/file_cache_map_test/testdir/fileA0000644000175000017500000000001012243455557021162 0ustar ssmssmsomedatargen-0.6.6/test/util/file_cache_map_test.rb0000644000175000017500000000627012243455557017104 0ustar ssmssm$:.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.6.6/test/transformer_test.rb0000644000175000017500000001640712243455557015575 0ustar ssmssm$:.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.6.6/test/testmodel/0000755000175000017500000000000012243455557013637 5ustar ssmssmrgen-0.6.6/test/testmodel/object_model_checker.rb0000644000175000017500000000463712243455557020310 0ustar ssmssmrequire '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.6.6/test/testmodel/manual_testmodel.xml0000644000175000017500000000100312243455557017710 0ustar ssmssm before kitchen after kitchen within toms room after toms room rgen-0.6.6/test/testmodel/ecore_model_checker.rb0000644000175000017500000001027712243455557020134 0ustar ssmssmrequire '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.6.6/test/testmodel/ea_testmodel_regenerated.xml0000644000175000017500000021557012243455557021405 0ustar ssmssm Enterprise Architect 2.5 rgen-0.6.6/test/testmodel/ea_testmodel_partial.xml0000644000175000017500000005244012243455557020547 0ustar ssmssm Enterprise Architect 2.5 rgen-0.6.6/test/testmodel/ea_testmodel.xml0000644000175000017500000021531012243455557017030 0ustar ssmssm Enterprise Architect 2.5 HouseMetamodel Rooms HouseExampleModel rgen-0.6.6/test/testmodel/ea_testmodel.eap0000644000175000017500000461400012243455557017000 0ustar ssmssmStandard Jet DBµnb` ÂUé©gr@?œ~Ÿÿ…š1Åyºí0¼ßÌcÙíÇŸFûмN†ûì7]DœúÆ^(æ¶Š`T”{6õß±wôCϯ±34ay[’µ|*ñ|™˜ýOJ”l>`&_•øÐ‰$…gÆ'DÒîÏeíÿÇF¡x íé-¸è{ö%Ê &Ê&Ê&Ê'Ê'Ê'Ê(Ê(Ê(Ê)Ê)Ê)Ê*ê*ê*ê+ê+ê+ê,´&,´',´(-´)-´*-´+.´,.´-.´./´//·/·0·0·0·1·1·1·2·2· 2· 3· 3· 3· 4·4·4·5·5·5·6·6·6·€·%€¹€¹€·€·€¹€¹€¹€¹€¹€¹€·€·€·€·€· €·!€·"€·#€·$€$Ê €$Ê!€$Ê"€9Ê€9Ê€9Ê€>Ê€>Ê€>Ê€EÊ#€EÊ$€EÊ%€JÊ&€J΀J΀N΀N΀N΀S΀S΀S΀V΀VÎ €VÎ €\Î €\Î €\Î €_ê€_ê€_ê€h΀h΀h΀m΀m΀m΀q΀q΀q΀u΀u΀u΀y΀y΀y΀~΀~΀~΀„Î €šÙ€šÙ€ŸÙ€ŸÙ€ŸÙ€¤Ù€¤Ù €¤Ù €©Ù €©Ù €©Ù €­Ù€­Ù€­Ù€³Ù€³Ù€³Ù€¼Ù€¼Ù€¼Ù€¾Ù€¾Ù€¾Ù€ÁÙ€ÁÙ€ÁÙ€ÄÙ€ÄÙ€ÄÙ€ÈÙ €ÈÙ!€ÈÙ"€ÌÙ#€ÌÙ$€ÌÙ%€ÑÙ&€Ñ߀Ñ߀Ü߀Ü߀Ü߀ã߀ã߀ã߀ç߀çß €çß €êß €êß €êß €ï߀ï߀ï߀ô߀ô߀ô߀ù߀ù߀ù߀ÿ߀ÿ߀ÿ߀߀߀߀߀߀߀ ß € ß!€ a`øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVCĤS ¯¯ ä ä  äÿ ä ä  ä  ä2ÿ ä  ä  ä  äÿ  äÿ  ä  ä  ä  ä  äIdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtraÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿId ParentIdName        ÿÿ¡ÈE(nSâ@t_objectproblemsS@ä===1111111/ ÿ@ê;R.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVCßêS  ® ä  ä2ÿÿ ä äObjectIdSIDACM FInheritableÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿObjectIdÿÿ1111/ ÿ@m6Û*°,â@aø¯æ2â@t_connectortag//////////- ÿh’ø{ãá@aø¯æ2â@t_connectorconstraintå@ÏBBB66666664 ÿ@¯VC%{ãá@aø¯æ2â@t_complexitytypesL@Ï>>>22222220 ÿ@Sü¨{ãá@aø¯æ2â@t_clientsª@Ï666*******( ÿ@Nòär ô1â@aø¯æ2â@t_category++++++++++) ÿJ“î{ãá@aø¯æ2â@t_cardinalityÑ@ É:::......., ÿ@¯$6Û*°,â@aø¯æ2â@t_attributetag//////////- ÿ>ö{ãá@aø¯æ2â@t_attributeconstraintsÎ@ÍCCC77777775 ÿ@9Š— {ãá@/ïI(nSâ@t_attributeßÌ888,,,,,,,* ÿ@)€Ä±à<òá@ç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,,,,,,,* ÿ@ÝrÇAÑñá@–U°æ2â@usys_system-@÷888,,,,,,,* ÿ@™1QH{ãá@ú‘I(nSâ@t_trxtypes@÷777+++++++) ÿ@”G{ãá@–U°æ2â@t_testtypesƒ@ö888,,,,,,,* ÿ@ÝŒf)E{ãá@–U°æ2â@t_tcfœ@ö222&&&&&&&$ ÿ@‰³,¬ ô1â@¡ÈE(nSâ@t_tasks((((((((((& ÿ¶òC{ãá@|\B(nSâ@t_stereotypesÞ@õ:::......., ÿ@|)úB{ãá@e$£ñá@t_statustypes1@õ:::......., ÿ@wœB{ãá@–U°æ2â@t_scenariotypes‡@õ<<<0000000. ÿ@ÝdÍÀQÖñá@¯æ'7sâ@t_rtf9@ó222&&&&&&&$ ÿ@_®›>{ãá@–U°æ2â@t_roleconstraint:@ó===1111111/ ÿ@[!£={ãá@–U°æ2â@t_risktypes{@ó888,,,,,,,* ÿ@X8Xt*Mçá@–U°æ2â@t_resourcesª@ò888,,,,,,,* ÿ@ÝOFE°Ùìá@–U°æ2â@t_propertytypesÎ@ñ<<<0000000. ÿ@J]@.Nçá@–U°æ2â@t_projectroles@ñ;;;///////- ÿ@E¬m;{ãá@–U°æ2â@t_problemtypesÓ@ñ;;;///////- ÿ@Aü6:{ãá@–U°æ2â@t_primitives"@ð999-------+ ÿ@?‚Êøï¯2â@‚Êøï¯2â@t_paletteitem.........., ÿ=‚Êøï¯2â@‚Êøï¯2â@t_palette**********( ÿ4öhÒÝnæá@õN(nSâ@t_package”@ð666*******( ÿ@06Û*°,â@–U°æ2â@t_operationtag//////////- ÿ,áE8{ãá@–U°æ2â@t_operationpres7@Ç<<<0000000. ÿ@(x‹7{ãá@–U°æ2â@t_operationposts8@Å===1111111/ ÿ@"Ñ6{ãá@/ïI(nSâ@t_operationparams«@Ä>>>22222220 ÿ@VC S  äÿ ä ä ä  äÿ  äÿ  äÿ  äÿszRelationshipgrbitccolumnicolumnszObjectszColumnszReferencedObjectszReferencedColumnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿszObjectszReferencedObjectszRelationshipÿÿumlpatternq@Â999-------+ ÿ@ A‰F(nSâ@A‰F(nSâ@t_templateu@Á777+++++++) ÿ@Ö%F(nSâ@A‰F(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+++++++) ÿ@_+ì·kº2â@+ì·kº2â@t_xref''''''''''% ÿ+€/Ȫà<òá@À $ý÷á@zz_q_orphans³@ÁŒ@ËE99-------+ ÿ@¢Xª÷„Úðá@Æú|`nôá@usysOldTablesE@÷:::......., ÿ@‘`F{ãá@–U°æ2â@t_testclass#@ö888,,,,,,,* ÿ@pÈŒ@{ãá@–U°æ2â@t_rtfreportqô888,,,,,,,* ÿ@Spl<{ãá@–U°æ2â@t_requiretypesŒ@ò;;;///////- ÿ@C©3{ãá@–U°æ2â@t_objecttrx-@ç888,,,,,,,* ÿ@ùÇ/{ãá@–U°æ2â@t_objectrequiresû@å===1111111/ ÿ@Üý",{ãá@–U°æ2â@t_objectconstraintä@Þ???33333331 ÿ@Ä )"{ãá@aø¯æ2â@t_mainttypesr@Ü999-------+ ÿ@ {öqìgâ]ØSÎIÄ?º5T @p   € z ˆ²àþ÷? ‚@@@o{~oüíÞk\MÚ˼I:+¸©š' –‡xöçteVãÔaRCÐÁ² ô ôÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ô  Û‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  TÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  ÿÿ ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ÿÿ  €ÿÿ  €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  €ÿÿ 6€ÿÿ 6€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 6€þ 5€ÿÿ 5€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 5€þ 4€ÿÿ 4€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 4€þ 3€ÿÿ 3€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 3€þ 2€ÿÿ 2€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 2€þ 1€ÿÿ 1€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 1€þ 0€ÿÿ 0€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 0€þ  @o{~oüíÞk\MÚ˼I:+¸©š' –‡xöçteVãÔÅRC4Á²£Jÿÿ Eÿÿ EÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Eÿÿ $ÿÿ $ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o $ÿÿ >ÿÿ >ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o >ÿÿ 9ÿÿ 9ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 9ÿÿ )€ÿÿ )€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o )€ÿÿ (€ÿÿ (€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o (€ÿÿ '€ÿÿ '€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o '€ÿÿ &€ÿÿ &€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o &€ÿÿ %€ÿÿ %€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o %€ÿÿ $€ÿÿ $€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o $€ÿÿ #€ÿÿ #€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o #€ÿÿ "€ÿÿ "€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o "€ÿÿ • @tdg,ufm`wfvwr2 Øw,rakfbwfggruw€Ùw,vfbxvfuhurxs$™s`bl`hfdj`hu`o»ufsruwv 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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,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*»+»7»8»9» :»!;»"<»#=»$>»%?»&@»'A»(€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€l>€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€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+%ÿ {öqìgâ]ØSÎIÄ?U©%@ò%{\à ñ%U©%@ò%ݰà ñ%Ȩ%@ò%=á ñ%€ @XI€€€¦2 €€ˆ"Dá? €% #€Œ $€?H3                     $ %                !"#$%&      !" # $ %!&!!"""###$$ $ % % % &&&'''((())), &, ', (- )- *- +. ,. -. ./ ///00011122 2 3 3 3 444555666€%€€€€€€€€€€€€€€€ €!€"€#€$€$ €$!€$"€9€9€9€>€>€>€E#€E$€E%€J&€J€J€N€N€N€S€S€S€V€V €V €\ €\ €\ €m€m€m€r€r€r€v          ! " # #'Q @€ )+* ,-./#01+356@ 8"H P$IX ' ' ' ' ' ' ' ' ' ' ' ' ÿ' ' ' ' ' ' ' '! '" '# '$ '% '& '' '( ÿ' ') '+ ', '- ) ) ) ) ) ) ) )  )  ) ) ) ÿ'*) ))))))))) )ÿ) )))))ÿ))) )!)")#)$)%)&ÿ))')))*)+),)-).)/)0******* * ** ÿ)(-----+ ÿ@Û €@ w,brppfbwruw}sfvw,brppfbwruý w,dj`hu`ow,dj`hu`orakfbwvýw,dj`hu`ow}sfvw,dj`hu`oýw,ofwujbw}sfvw,rakfbwofwujbvý w,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ýw,rakfbwýbwruWýbww,brppfbwruWýbww,brppfbwruý ,rakfbwofwujbvý `hu`oý j`hu`oý á@–U°æ2â@Tablest_objecttypes8+%ÿ C©3{ãá@–U°æ2â@Tablest_objecttrx6+%ÿ “r2{ãá@–U°æ2â@Tablest_objecttests8+%ÿ )¸1{ãá@›RJ(nSâ@Tablest_objectscenarios<+%ÿ â;1{ãá@–U°æ2â@Tablest_objectrisks8+%ÿ uµÇfNçá@–U°æ2â@Tablest_objectresource;+%ÿ Ç/{ãá@–U°æ2â@Tablest_objectrequires;+%ÿ Zb Õìá@–U°æ2â@Tablest_objectproperties=+%ÿ ¥ /{ãá@¡ÈE(nSâ@Tablest_objectproblems;+%ÿ ;R.{ãá@–U°æ2â@Tablest_objectmetrics:+%ÿ ôÕ-{ãá@gøï¯2â@Tablest_objectfiles8+%ÿ Š-{ãá@–U°æ2â@Tablest_objecteffort9+%ÿ ý",{ãá@–U°æ2â@Tablest_objectconstraint=+%ÿ Ç%{ãá@/ïI(nSâ@Tablest_object3+%ÿ ­!#{ãá@aø¯æ2â@Tablest_metrictypes8+%ÿ f¥"{ãá@aø¯æ2â@Tablest_method3+%ÿ  )"{ãá@aø¯æ2â@Tablest_mainttypes7+%ÿ A‰F(nSâ@A‰F(nSâ@Tablest_lists2+%ÿ ±$µ×ñá@¡ÈE(nSâ@Tablest_issues3+%ÿ 5N”Uèá@Ôc–Üðá@Tablest_implement6+%ÿ ·'ùï¯2â@·'ùï¯2â@Tablest_image2+%ÿ “0!{ãá@FuœÜðá@Tablest_html1+%ÿ 8 {ãá@aø¯æ2â@Tablest_glossary5+%ÿK w,`wwujaxwfýw,brppfbwruý w,brppfbwruý w,brppfbwruýw,dj`hu`oýw,dj`hu`oýw,dj`hu`orakfbwvýw,dj`hu`ow}sfvýw,ofwirdýw,rakfbwýw,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,vbujswÝw,vfbhurxsÝ w,vfbhurxssfuojvvjrpÝ w,vfbmrblvÝ w,vfbsfuojvvjrpÝw,vfbsrmjbjfvÝw,vfbxvfuÝw,vfbxvfuhurxsÝw,vfbxvfusfuojvvjrpÝw,vw`wxvw}sfv$v$w,w`vlv$w,wbg$w,wfosm`wfÝw,wfvwbm`vv$w,wfvwsm`pvÝw,wfvww}sfv$w,wu|w}sfv$w,xoms`wwfupÝw,|ufgÝ w,|ufgv}vwfoÝw,|ufgxvfuÝxv}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[gWXWfX0¯s`bl`hfdj`hu`o¯s`bl`hfdj`hu`ow}sfv¯s`bl`hfrakfbw¯w,dj`hu`ow}sfvw,dj`hu`o¯ W@ @w,brppfbwruw}sfvý w,dj`hu`oýw,dj`hu`ow}sfvýw,ofwujbw}sfvý w,rakfbwý w,rakfbwýw,rakfbwýw,rakfbwýw,s`bl`hfýw,s`bl`hfýw,s`bl`hfýU°æ2â@usys_system-@÷888,,,,,,,* ÿ@™1QH{ãá@ú‘I(nSâ@t_trxtypes@÷777+++++++) ÿ@”G{ãá@–U°æ2â@t_testtypesƒ@ö888,,,,,,,* ÿ@ÝŒf)E{ãá@–U°æ2â@t_tcfœ@ö222&&&&&&&$ ÿ@‰³,¬ ô1â@¡ÈE(nSâ@t_tasks((((((((((& ÿ¶òC{ãá@|\B(nSâ@t_stereotypesÞ@õ:::......., ÿ@|)úB{ãá@e$£ñá@t_statustypes1@õ:::......., ÿ@wœB{ãá@–U°æ2â@t_scenariotypes‡@õ<<<0000000. ÿ@ÝdÍÀQÖñá@¯æ'7sâ@t_rtf9@ó222&&&&&&&$ ÿ@_®›>{ãá@–U°æ2â@t_roleconstraint:@ó===1111111/ ÿ@[!£={ãá@–U°æ2â@t_risktypes{@ó888,,,,,,,* ÿ@X8Xt*Mçá@–U°æ2â@t_resourcesª@ò888,,,,,,,* ÿ@ÝOFE°Ùìá@–U°æ2â@t_propertytypesÎ@ñ<<<0000000. ÿ@J]@.Nçá@–U°æ2â@t_projectroles@ñ;;;///////- ÿ@E¬m;{ãá@–U°æ2â@t_problemtypesÓ@ñ;;;///////- ÿ@Aü6:{ãá@–U°æ2â@t_primitives"@ð999-------+ ÿ@?‚Êøï¯2â@‚Êøï¯2â@t_paletteitem.........., ÿ=‚Êøï¯2â@‚Êøï¯2â@t_palette**********( ÿ4öhÒÝnæá@õN(nSâ@t_package”@ð666*******( ÿ@06Û*°,â@–U°æ2â@t_operationtag//////////- ÿ,áE8{ãá@–U°æ2â@t_operationpres7@Ç<<<0000000. ÿ@(x‹7{ãá@–U°æ2â@t_operationposts8@Å===1111111/ ÿ@"Ñ6{ãá@/ïI(nSâ@t_operationparams«@Ä>>>22222220 ÿ@"ÉQÒ™]Û×EŸg/ø£ŸDc!ߣfC·`\Bº¶AeAºg€€€uD«à<òá@¦ '-{ â@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ãá@aø¯æ2â@MSysModules2----------+ ÿümuãá@ümuãá@MSysModules,,,,,,,,,,* ÿèô1â@aø¯æ2â@MSysAccessObjects22222222220 ÿ €€ €ƒ¢ãnæá@ËøÐãÓsâ@AdminPS2&&&&&&&&&$ ÿ€ €¶‰luãá@¶‰luãá@UserDefined,,,,,,,,,,* ÿ€ €§îò|ãá@wþIOkâ@AccessLayout*@ @ NE99-------+ ÿ@€ Dmuãá@ Dmuãá@SysRel''''''''''% ÿ€ Dmuãá@ Dmuãá@Scripts((((((((((& ÿ€ Dmuãá@ Dmuãá@Reports((((((((((& ÿ€ Dmuãá@ Dmuãá@Modules((((((((((& ÿ»€QÙaô1â@QÙaô1â@DataAccessPages0000000000. ÿ¶‰luãá@¶‰luãá@€MSysRelationships22222222220 ÿ¶‰luãá@aø¯æ2â@€MSysQueries,,,,,,,,,,* ÿ¶‰luãá@aø¯æ2â@€MSysACEs))))))))))' ÿ¶‰luãá@¶‰luãá@€MSysObjects,,,,,,,,,,* ÿ¶‰luãá@º[Xô1â@€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à $*0éµIÞ£i/û»ÿÿÿÿ=Îj0—Á=Îj0—Áþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöò ÿÿÿÿForms ÿÿÿÿ=Îj0—Á=Îj0—ÁReportsöòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ˜l0—ÁÀPropDataöòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöòÐÏࡱá>þÿ   þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöò*ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌxÒÃÛ0öò $*0 @€ @€ÿÿÿÿ =Îj0—Á°Ãl0—ÁBlob ÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿCustomGroupsöò ÿÿÿÿÿÿÿÿÿÿÿÿ=Îj0—Á=Îj0—ÁDatabasesÿÿÿÿÿÿÿÿ =Îj0—Á°Ãl0—Á0öò =Îj0—Á°—Àl0—ÁCmdbarsÿÿÿÿÿÿÿÿÿÿÿÿ=Îj0—Á=Îj0—ÁDataAccessPages öò=Îj0—Á=Îj0—ÁScriptsÿÿÿÿÿÿÿÿÿÿÿÿ=Îj0—Á=Îj0—ÁVBAÿÿÿÿÿÿÿÿ öò ÿÿÿÿ Forms Modulesÿÿÿÿÿÿÿÿ öò ÿÿÿÿ=Îj0—Á=Îj0—ÁDatabasesÿÿÿÿÿÿÿÿ =Îj0—Á=Îj0—Á0 öòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿijäMSysDb öòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöò $*0ÿÿÿÿÿÿÿÿÿÿÿÿPROJECTÿÿÿÿ/_VBA_PROJECTöòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVBAÿÿÿÿÿÿÿÿp®@k0—ÁÀk¹l0—ÁPROJECTwmöòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöò ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ýÿÿÿþÿÿÿ þÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöòÁDirDataÿÿÿÿÿÿÿÿÿÿÿÿAcessVBADataÿÿÿÿÿÿÿÿÿÿÿÿöòustomGroups ÿÿÿÿ€iÕj0—Á€iÕj0—ÁVBAProjectÿÿÿÿ87k0—ÁÀk¹l0—öòÿÿÿÿÿÿÿÿÿÿÿÿAcessVBADataÿÿÿÿÿÿÿÿÿÿÿÿCöò ÿÿÿÿ€iÕj0—Á€iÕj0—ÁVBAProjectÿÿÿÿÿÿÿÿ87k0—Á87k0—ÁDirDataöò $*0ر€0* pH‚dädb2@Õ= d  ­€=¨ J< ˜ DAO>„D€AO ™*\G{00€025E01-:0C  0046}#5.0#0#C:\Program Files\Common Microsoft Shared\w350`.DLL# 3.51 Object LibrXary€Höò DPB="BAB80CB3E8B4E8B4E8" GC="9795219623AE01AF01AFFE" [Host Extender Info] &H00000001={3832D640-CF90-11CF-8E43-00A0C911005A};VBE;&H00000000 [Workspace] Á0öò =Îj0—Á=Îj0—ÁDaID="{B037F666-3984-44A7-B246-B64B4733A8F2}" Name="db2" HelpContextID="0" VersionCompatible32="393222000" CMG="DDDF6B48952199219921992199"öò=Îj0—ÁReportsÿÿÿÿ=Îj0—Á=Îj0—ÁijäMSysDböòPropData ÿÿÿÿForms ÿÿÿÿ=Îj0—ÁöòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ°Ãl0—Á € öò'()*+,-./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" [HoÌamÿ äú*\G{000204EF-0000-0000-C000-000000000046}#4.0#9#C:\PROGRA~1\COMMON~1\MIC#öòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀi"öòÿÿÿÿÿÿÿÿÿÿÿÿ Üÿÿÿÿÿÿÿÿÿÿÿÿ!öòUs@tdole>‚fstdolÔe^f€\€^X043„[W-^2^WINNT\System32\S‚12.tlb#OLE AutoÀmation/ÁVBIDE> VB IDEC·€†­€CE157ŸC5.3ïPVBA \À6E6EX T.OLBHRVisual Basic for A pplic1s Extensibdir öò   ÿü$AccessVBA÷âWin16Á~Win32Mac³²VBA6­#db2¦‚DAOž‚stdole“`VBIDEAÿÿÿHÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿ ÿÿÿÿÿÿ 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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@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ÿÿÿÿÿÿÿÿ&ÿÿÿÿIndex1ÿÿufsruwv vbujswv v}vufm w`amfvov}v`bbfvvrakfbwvov}v`bfvov}vrakfbwvov}vtxfujfvov}vufm`wjrpvijsv`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfdÌ{öqìgâ @€ @€      €€€€€@ >           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€92 üüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLVAL "i_VBA_PROJECTñÌa^ÿ ä*\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 ÿÿÿÿÿÿÿÿLZŽ9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ìHÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿx(jæùùKV‰ÿÿÿÿÿÿÿÿèÿÿÿÿ’üKÐoÛÿÿÿÿÿÿÿÿ€ƒ¢ÿŒ7Access€ÿAnd €ÿAs.€ÿDebug=€ÿdim@€ÿDoD€ÿelseG€ÿendH€ÿendifR„ÿfS€ÿFalseU€ÿForZ€ÿFunction`€ÿIfd€ÿInputk€ÿintegeru €ÿlineinputy€ÿLongz€ÿloop„€ÿNew…€ÿNext†€ÿNLVAL #ot€ÿOutput¥€ÿSet°€ÿsub³€ÿThen´€ÿTo¾€ÿWend¿€ÿWhile€ÿWriteVBA÷âWin16Á~Win32Mac³²DAOž‚db2¦‚Module1b €ÿ_EvaluateÙcopyDBþ~dbë\dbnewÀ×rs_ €ÿRecordsetÚænei`„ÿsql"ÕrsOldBùrsNewøòcnt+ €ÿCurrentDbS €ÿOpenDatabase` €ÿOpenRecordsetÕ|€ÿBOFéyEOFô‰ tablename` €ÿExecuteYÍ€ÿMoveNextL!€ÿAddNewa£€ÿFields7©Count0v€ÿUpdateÒüStr—ÕerrStop›MsgBox—Rmod_housekeepingJ©listqryý4 €ÿÿÿ_B_var_set €ÿTableDefs%iItem×z €ÿÿÿ_B_var_forjL €ÿQueryDefs‡& renametableU]„ÿtableñ €ÿÿÿ_B_var_Sub½’qdf‰È€ÿQueryDefÒÙ €ÿParameters`éstingå0cZ replacetablee€ÿÿÿ_B_var_replacetableÁLnewtable%€ÿÿÿ_B_var_Function™OrepExactåÎsOld¾sNewt €ÿÿÿ_B_var_ifPòprevcharó—nextcharsü _B_var_MidíplimŒ® _B_var_LeftQá testexact’¡FROM~ Package³INNEReõ replaceExact¯B€ÿÿÿ_B_var_replaceExact |€ÿÿÿDiagramObjectsîÕ€ÿÿÿ_B_var_DiagramObjects¿|€ÿÿÿ_B_var_Package¶ sFinda €ÿÿÿ_B_var_WhileIf fixQueriesX9 fixtables#³NewName#€ÿRefresh€ÿCollect querynameË renamequeryù)query%¾newqueryãñfixCode[ropenfileúï€ÿÿÿ_B_var_openfile¸diò\ €ÿÿÿ_B_var_dišñsfile8a €ÿÿÿ_B_var_sfile%%dmö\ €ÿÿÿ_B_var_dmžñ €ÿÿÿ_B_var_OpenÓlsourceG¶g^ €ÿÿÿ_B_var_OutputÃs €ÿÿÿ_B_var_NameXfixFilesd³ €ÿÿÿ_B_var_As5ñ €ÿÿÿ_B_var_Close×Énewdir\ olddirY;€ÿValueäK _B_var_Str¨’ _B_str_ErrorRî €ÿÿÿ_B_var_olddir¶ €ÿÿÿ_B_var_Write  €ÿMoveFirstNqsÝ^ €ÿÿÿ_B_var_qs…ó€ÿÿÿfiscodeט€ÿÿÿ_B_var_fiscodeÚŒChrK~ _B_str_Chrm# _B_var_Chr\;chÌ\ €ÿÿÿ_B_var_chtñ IsChildOfK3 PackageIDó*®LVALºID¦] €ÿdbOpenTableBvretÎ €ÿÿÿ_B_var_ret&‹€ÿIndexñ¿ Object_ID08ObjectPackage_IDÝâ Package_IDst curPackageÿParentID~© €ÿÿÿ_B_var_do ñ€ÿÿÿ_B_var_Package_IDÝâ Parent_IDfE modReportsdNÿÿ0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿdirýù°€0* pH‚dädb2@Õ= d  LZŽ9¨ J< ˜ DAO>„D€AO ™*\G{00€025E01-:0C  0046}#4.0#0#C:\Program Files\Common Microsoft Shared\w350`.DLL# 3.51 Object LibrXary€H„D‚ ì VCqNBB ä ä  äÿ  ä¸ÿ  ä  äÿÿ( PropertyID ElementIDPropertyVALUENOTESea_guidÿÿäÿÿÿÿÿÿÿÿ ÿÿÿÿäÿÿÿÿBCÿÿÿÿÿÿÿÿÿÿÿÿäÿÿÿÿÿÿBD ÿÿÿÿÿÿÿÿ ElementKey PrimaryKeyBBÿÿÆÒ"!MSysDb2#½ò@ov}vda€€ÿÿÍ%ÿ  ä  ä  ä  ä  äIdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtraÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿId ParentIdName        ÿÿ¡ÈE(nSâ@t_objectproblemsS@ä===1111111/ ÿ@ê;R.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ.íÚ¿¡m>ß­yJ7$ ëÈYã¨t=Ô¢|aC ç±t;Ì•^,úçÔ¹›x €ÿÿt_objectObject_1  €ÿÿt_connector  €ÿÿt_object  €ÿÿÿ  €ÿÿ  €t_objectt_connector0@(+  €t_connectorObject_1.@(+  €€t_connector.Connector_ID0 g €DestID€t_object.Object_ID0 o €DestName €t_object.Name- o €DestType€t_object.Object_Type4 o €€t_connector.Connector_Type2 g €SourceType€Object_1.Object_Type6 o €SourceName €Object_1.Name/ o €SourceID€Object_1.Object_ID2 o €t_objectObject_1  €t_connector  €t_object  €ÿ  €  €t_objectt_connector0@(+  €t_connectorObject_1.@(+  €€t_connector.Connector_ID0 g €DestID€Object_1.Object_ID0 o €DestName €Object_1.Name- o €DestType€Object_1.Object_Type4 o €€t_connector.Connector_Type2 g €SourceType€t_object.Object_Type6 o €SourceName €t_object.Name/ o €SourceID€t_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%Ö¨xJ켄K½ˆ_/×§yO(ùÏ¥uK&úѧwMíÕe7 ' ' '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, g€t_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$ g€€t_ecf.Description) g€ €t_ecf.ECFID# g€t_ecf €ÿ € €X7YZ_____2)@ (" 7€X7YZ_____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.*% g€t_diagramobjectsDiagramObjects_1,, €t_connector €t_diagramobjects €ÿ €  €t_objectt_connector0@(+  €t_connectorObject_1.@(+  € €t_connector.Notes) g € DestID€t_object.Object_ID0 o €DestName €t_object.Name- o €DestType€t_object.Object_Type4 o €€t_connector.Stereotype. g €€t_connector.Connector_Type2 g €SourceType€Object_1.Object_Type6 o €SourceName €Object_1.Name/ o €SourceID€Object_1.Object_ID2 o €ConName€t_connector.Name/ o*ÌŒV×—\á­{KúÇ´¡…jOë¿’f6Öª—„hM*Ζ]#é®}@€ @€€€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 €ÿ € €  €t_method.Name% '€ €t_method.Object_ID* '€t_objectt_method'@(( €t_diagramt_object*@() € €t_method.Type% g€€t_method.Scope& g€ €t_method.Name% g€€t_method.Object_ID* g€€t_diagram.Diagram_ID, g€t_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€ ImplementorType€t_object.Object_Type; o€ImplementorName €t_object.Name4 o€ImplementedByID€t_object.Object_ID9 o€Connector€t_connector.Connector_Type; o€ObjectType€Object_1.Object_Type6 o€ObjectName €Object_1.Name/ o€ObjectID€t_connector.End_Object_ID9 o€Package€t_package.Name- o, @€ @€ @€ @€ @€ @€ @€ ' ' ' ' ' ' ' '  '  ' ÿ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ÿ' ' ' ' ' ' ' '! '" '# '$ '% '& '' '( ÿ' ') '+ ', '- ) ) ) ) ) ) ) )  )  ) ) ) ÿ'*) ))))))))) )ÿ) )))))ÿ))) )!)")#)$)%)&ÿ))')))*)+),)-).)/)0******* * ** ÿ)(-----+ ÿ@+. @€ @€ @€ @€ @€ @€ @€  )  ) ) ) ÿ'*) ))))))))) )ÿ) )))))ÿ))) )!)")#)$)%)&ÿ))')))*)+),)-).)/)0******* * ** * * * *  *ÿ)(*********** * *ÿ**** *!*"*#*$*%*&*'*(*)- - - - - ----- - - - - -------ÿ*'(Í¡tF빇Z(úÍši6Êœd4Ó¢oAå·‰Z+üÍ 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€PackageName€t_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, 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 g€€t_objecttests.InputData/ g€€t_objecttests.Notes+ g€€t_objecttests.TestType. g€€t_objecttests.TestClass/ g€€t_objecttests.Test* g€€t_objecttests.Object_ID/ g€€t_object.Package_ID+ g€t_object €t_objecttests € G€ G€ÿ € €%@( '€t_packaget_object*@() €t_objecttypest_object0@(-! €€t_objecttypes.DesignObject2 g€Package€t_package.Name- o€Type€t_object.Object_Type0 o€ €t_object.Name% g€€t_object.Object_ID* g€t_object €t_objecttypes €t_package € G€ G€ÿ € €t_packaget_object*@() €t_objectt_object_1*@(* €t_objectt_diagramobjects/@(0$ €7€t_object.Multiplicity- g€6€t_object.PackageFlags- g€5€t_object.StateFlags+ g€4€t_object.IsActive) g€3€t_object.IsSpec' g€2€t_object.IsLeaf' g€1€t_object.IsRoot' g€0ClassName€t_object_1.Name0 o.3 @€ @€ @€ @€ @€ @€ @€- -!-"-#-$-%-&-'-(- )-!*-"+-#,-$--%.-&/-'0/1/2/3/4/5/6/7/// / ÿ*/ / ////////////ÿ/ ////// /!/"/#/$/%/&/' /( /) /* /+ /,1ÿ/11111111 1 1 1 1 1111ÿ11111111111111 1  1! 1" 1# 1$1%1&1'1(1)ÿ1-̹¦‹oL,Ì›h6Ó…U!åÒ¿¬™~b.ýʘl?â¶„R%óŘg4Ðj€€t_object.CreatedDate, g€€t_object.Bordercolor, g€€t_object.Fontcolor* g€€t_object.BorderWidth, g€€t_object.BorderStyle, g€€t_object.Backcolor* 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.Diagram_ID+ g€€t_object.Object_Type, g€€t_object.Object_ID* g€Package€t_package.Name- o€t_package €t_object € G€ G€ÿ € €€(((t_objecttypes.ImageID)>0))5 '€Object_1t_objecttypes0@(-! €t_packageObject_1*@() €t_objectt_package€t_object.Name = t_package.NameG €t_objectt_package)@() €€Object_1.Object_Type, g€€Object_1.Stereotype+ g€€t_package.Package_ID, g€€t_object.Object_ID* g€€t_objecttypes.ImageID- g€ €Object_1.Name% g€t_objecttypes €t_objectObject_1 €t_package €t_object €ÿ € €t_objecttestst_object,@(-!  ¬XTG°¬F^ F¼p)ßÛDŽ4ÜØC}5⣟BUÔ†‚A0ñ¤\zzzØt{ãá@aø¯æ2â@t_constants(@%888,,,,,,,* ÿ@v(>{ãá@4™ŽßÓsâ@t_connectortypes(@%===1111111/ ÿ@r6Û*°,â@aø¯æ2â@t_connectortag//////////- ÿm’ø{ãá@aø¯æ2â@t_connectorconstraintå@BBB66666664 ÿ@ VC%{ãá@aø¯æ2â@t_complexitytypesL@>>>22222220 ÿ@Sü¨{ãá@aø¯æ2â@t_clientsª@666*******( ÿ@Nòär ô1â@aø¯æ2â@t_category++++++++++) ÿJ“î{ãá@aø¯æ2â@t_cardinalityÑ@ :::......., ÿ@ $6Û*°,â@aø¯æ2â@t_attributetag//////////- ÿ>ö{ãá@aø¯æ2â@t_attributeconstraintsÎ@CCC77777775 ÿ@9Š— {ãá@kâYáÓsâ@t_attributeß888,,,,,,,* ÿ@)€Ä±à<òá@ç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 1111ÿ11111111111111 1  1! 1" 1# 1$1%1&1'1(1)1*1+1,4444444444  4 !4 "4 #4 $4%4&4'44ÿ14444444444444 4!4"4#4$4%ÿ44&4(4)4*4+4,4-4.555ÿ4'%/Ìžn@䶈Z'õÂ`1Ó¦vcP=*îÓµ‰RÞ¡h/ûÉ™zgTA.ò×¹ @€ @€€ €t_object.Name% g€t_connector €t_object €t_objecttypes €t_package € G€ G€ÿ € €.@"( '€t_packaget_object*@!() €t_objectt_connector0@ (+ €t_objecttypest_object0@(-! €€t_objecttypes.DesignObject2 g€€t_connector.Connector_Type2 g€RealizedByID€t_object.Object_ID6 o€ObjectID€t_connector.End_Object_ID9 o€Package€t_package.Name- o€Type€t_object.Object_Type0 o€ €t_object.Name% g€t_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+ g€€t_object.Concurrency, g€€t_object.PDATA5' g€€t_object.PDATA4' g€€t_object.PDATA3' g€€t_object.PDATA2' g€€t_object.PDATA1' g€€t_object.Tagged' g€€t_object.Abstract) g€€t_object.Status' g€€t_object.ModifiedDate- g0É•Sݤp>ïÜɦ‹Y ôÁ‰U!ì­t=óàÈ‘~kS öÞ´„Y/ϼ©–ƒkä€t_ocf € G€ G€ÿ € €ExValue€[Weight]*[Value]/ o€ €t_tcf.Notes# g€ €t_tcf.Value# g€ €t_tcf.Weight$ g€€t_tcf.Description) g€ €t_tcf.TCFID# g€t_tcf €ÿ € €TCF€Sum([Weight]*[Value])0 o€t_tcf €ÿ € €ECF€Sum([Weight]*[Value])0 o€t_ecf €ÿ € €t_objectresourcet_object/@70$ € €t_objectresource.DateEnd0 g€ €t_objectresource.DateStart2 g€ €t_objectresource.PercentComplete8 g€€t_objectresource.Notes. g€€t_objectresource.Time- g€€t_objectresource.Role- g€€t_objectresource.Resource1 g€€t_object.Object_Type, g€ €t_object.Name% g€€t_objectresource.Object_ID2 g€€t_object.Package_ID+ g€t_object €t_objectresource €ÿ € €.@7 '€t_packaget_object*@7) €t_objectt_connector.@$(+ €t_objecttypest_object0@#(-! €€t_objecttypes.DesignObject2 g€€t_connector.Connector_Type2 g€RealizedByID€t_object.Object_ID6 o€ObjectID€t_connector.Start_Object_ID; o€Package€t_package.Name- o€Type€t_object.Object_Type0 o38 @€ @€ @€ @€ @€ @€ @€1,4444444444  4 !4 "4 #4 $4%4&4'44ÿ14444444444444 4!4"4#4$4%ÿ44&4(4)4*4+4,4-4.5555555555 ÿ4'5 5 5 55555555 5 5 55ÿ5 555ÿ555 5!ÿ55"5$5%5&5'5(5)5*ÿ5#5+5-5.5/@@@@@@@@ÿ5,LVAL"Ö¨yEô®~ZØ®„c?ßµ‹`"øÎ£Þ®‡]3Ñ¢xP€ @€ @€ @€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 55ÿ5 555ÿ555 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$€ÿ $€ #€ d€t_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&& {öqìgâ]ØSÎIÄ?Ô•UÝœ`"øÎ£Ýª~R!—n2 ðÕ¹~CÛ¯ƒQ!ñÀ­š '€Object '€ÿ '€ &€t_packaget_diagram+@7* &€t_objectt_diagram*@7) &€t_packaget_object* @@û9 `ddufvvÎ           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€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ÿ9€<Îÿ9€ÎVCN?? ä  äœÿ  ä 'ÿ  äœÿ  ä ' ä Object_ID ConstraintAttNameTypeNotesIDÿÿ'ÿÿ ÿÿœÿÿÿÿ'ÿÿ ÿÿœÿÿ? ÿÿÿÿ PrimaryKey??ÿÿS{öqìg3äÉ–jAá´ˆX9&øØ¯w> Öš‡t[H* Ý­~kX?&òÓÀ­’v[8ܤk1÷¼‹ ä"€€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- g€€t_objecttypes.DesignObject2 g€€t_objecttypes.Description1 g€ €t_object.*" g€t_objecttypes €t_object €ÿ € €F@7 '€t_packaget_object*@7) €t_ocft_object'@7% €€t_object.Phase& g€€t_package.Package_ID, g€€t_package.Name& g€Complexity4@7" o€ €t_object.Name% g€€t_object.Object_Type, g€t_object €t_package 1Ô¨‰vcG,Õše2Ú¨l< Û¼©–{X<ݪ~R!ðѾ«˜…gK+é¶‚IÖ¬|ÿ *€ImplementedByID€"") o*€Connector€""# o*€ObjectType€Object_1.Object_Type6 o*€ObjectName €Object_1.Name/ o*€ObjectID€Object_1.Object_ID2 o*€Package€t_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) (€Tag€IIf([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 Name€t_diagram.Name4 o(€t_package Name€t_package.Name4 o(€t_diagram (€t_object (€t_package (€ÿ (€ '€>@7 ''€ €t_object.Note% g'€ €t_object.Name% gÌ{öqìgâ$           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€92€>2$VCÈNFF  äÿ  äÿÿ  äP(ÿ AuthorNameRolesNotesÿÿÿÿÿÿÿÿÿÿPÿÿàÿÿÿÿ(ÿÿFG ÿÿÿÿ PrimaryKeyÿÿa{öq€E           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2'(Í¡tF빇Z(úÍši6Êœd4Ó¢oAå·‰Z+üÍ 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"€PackageName€t_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, g4É›m?Ý©u> ݾ«˜lN/РzgR?íÚDz—n2 ðÕ¹~CÛ¯ƒQ!ñÀ­š'€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 Name€t_diagram.Name4 o&€t_package Name€t_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$€ÿ $€ #€ d€t_operation.Name) /#€ €t_operation.Scope) '#€ d€t_operation.Pos( /#€$@7 '#€t_operation #€ G#€Object O#€ÿ #€ "€!@ 7 '"€t_packaget_object*@ 7) "€t_objectt_object_1*@ 7* "€t_objectt_diagramobjects/@ 70$ "€7€t_object.Multiplicity- g"€6€t_object.PackageFlags- g"€5€t_object.StateFlags+ g"€4€t_Object.IsActive) g"€3€t_Object.IsSpec' g"€2€t_Object.IsLeaf' g"€1€t_object.IsRoot' g"€0ClassName€t_object_1.Name0 oVC™NKK ä2 CardinalityÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿKM ÿÿÿÿ PrimaryKeyÿÿa{ö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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVCèNOO ä  äÿÿ  äÿ  ä CategoryIDNameTypeNOTESÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿOR ÿÿÿÿ PrimaryKeyOOÿÿS{öqìg8X @€ @€ @€ @€ @€ @€ @€@ ÿ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€€€€€€€€$2€92€>2€E2€J2VCZN TT  äW(ÿ  ä„ÿ  äW(2  ä„2  äW(2  ä„2  äW(2  ä„ÿ  äW(ÿName OrganisationPhone1Phone2MobileFaxEmailRolesNotesÿÿÿÿ(ÿÿWÿÿ„ÿÿÿÿ(ÿÿWÿÿ„ÿÿTU ÿÿÿÿ PrimaryKeyÿÿa{öq S           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2VC NWW ä2 ä Complexity NumericWeightÿÿÿÿÿÿÿÿäÿÿWÿÿÿÿÿÿÿÿWZÿÿÿÿÿÿäÿÿWÿÿÿÿÿÿÿÿÿÿäW[ ÿÿÿÿÿÿÿÿ NumericWeight PrimaryKeyÿÿÚ{öqìPQ @€ @€ @€ @€ @€ @€ @€"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)ÿAÿÿÿÿÿÿÿÿÿÿÿ•Vðã×ȹ«@@ @ @@@ @@€  @€€€@@€€€@`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 @€Y€Y€Y€Y€Y€Y ä  ä  ä  äIdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtraÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿId ParentIdName        ÿÿ¡ÈE(nSâ@t_objectproblemsS@ä===1111111/ ÿ@ê;R.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@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 ätrÿE,F äF,G ä G,H äreÿH-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 {öqìgâ]ØSÎIÄ?º5€€€€ÃáÈÈÈÈÈÈÈÈ8v±ìèD"^ŒÂñ9EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿtÏÅØã@tÏÅØã@C958PackageObjectModel1.01Proposed46Java1.0Public{06C9C958-C14A-41f4-89A9-6873CCED37A7}œœœœœœœœœvvvpmmmmiiiiiiiiigg__^^^[[[9EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿtÏÅØã@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%OÝÿb9C,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿaõ3Ý*ÿâ@|ó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%OÝÿb9A+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÛcëýâ@sEnëýâ@atioClassBathroom1.01Proposed00Java1.0Public{244CC9E5-1F81-4164-9215-C048EC679543}—————————qqqkhhhhddddddccccbZZYYYVVVNI%OÝÿbå9?,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ±ú™Nkýâ@±ú™Nkýâ@VaPackageRooms1.01Proposed43Java1.0Public{F9D8C6E3-4DAD-4aa2-AD47-D0ABA4E93E08}–––––––––pppjggggcccccccccaaYYXXXUUUPI%OÝ¿b9>+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzêÙãâ@û™ŽX\ýâ@naliClassKitchen1.01Proposed00Java1.0Public{9CE44C59-37E4-4117-8C05-F87C4DC33529}–––––––––pppjggggccccccbbbbaYYXXXUUUNI%OÝÿb9=+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿotÏzÚâ@í%´W\ýâ@àClassRoom1.01Proposed00Java1.0Public{14DB5E54-CD7B-4c84-998C-44960049D7E0}“““““““““mmmgdddd``````____^VVUUURRRNI%OÝÿb9<,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜ºÜ~zÚâ@4(rQ ïâ@èClassHouse1.0dummy1Proposed00Java1.0Public{436D81AD-A9B0-44d8-8AD1-86BB0808DA32}™™™™™™™™™sssmjjjjffffffeeeed\\[VVSSSNI%Oßÿb“\ @€ €_€_€_€_€ _€ _€ _€G€G€G€G€G€Go{ö #\ @€  `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{“\ @€ €G€G€G€G€G€G€_€_€_€_€_€_€_o{ “\ @€ €<_€<_€<_€=_€=_€A_€D_€GG€GG€GG€GG€GG€PGo{€Ì\.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{“\ @€ €_€_€_€_€ _€ _€ _€G€G€G€G€G€Go{“\ @€ €<_€=_€>G€>_€>_€>_€A_€B_€HG€LG€MG€NG€OGVCNþþ  ä(  äL(  äøvd  äL  äøv PropertyID ElementID BaseClassTagValueNotesÿÿÿÿÿÿÿÿÿÿÌÿÿÿÿÿÿÿÿPþA ÿÿÿÿ PrimaryKeyþþþþÿÿVC£Nnn ä  ä”ÿ  ä&2  ä” ConnectorID ConstraintConstraintTypeNotesÿÿäÿÿÿÿ&ÿÿÿÿÿÿÿÿ'ÿÿÿÿnoÿÿnÿÿdÿÿÿÿ”ÿÿÿÿ&ÿÿÿÿ”ÿÿnpÿÿÿÿ”ÿÿÿÿ&ÿÿÿÿÿÿÿÿ$nq ÿÿÿÿÿÿÿÿÿÿÿÿObjectConstraintConstraintObjectID PrimaryKeynnÿÿE{öqìgâ]€m           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2mmVCqNss ä ä  äÿ  ä¸ÿ  ä  äÿÿ( PropertyID ElementIDPropertyVALUENOTESea_guidÿÿäÿÿÿÿÿÿÿÿ ÿÿÿÿäÿÿÿÿstÿÿÿÿÿÿÿÿÿÿÿÿäÿÿÿÿÿÿsu ÿÿÿÿÿÿÿÿ ElementKey PrimaryKeyssÿÿÌ{öqìgâ r€S           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2r€SVCºNww  äÿÿ2  ä2Connector_Type DescriptionÿÿoÿÿeÿÿoÿÿoÿÿeÿÿoÿÿTÿÿeÿÿcwy ÿÿÿÿ PrimaryKeyÿÿ.rB PrimaryKeyÿÿa{öq”väȨŽ|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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVCºN{{ ä2  äÿ ConstantName ConstantValueÿÿÿÿÿÿÔÿÿÿÿÿÿÿÿÿÿÿÿ{} ÿÿÿÿ PrimaryKeyÿÿa{öq bzâÓÁ®š‹z@@ @ @@@ @@€  @€€€@@€€@ @`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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVCØN ä  äÿ2  äP( Constraint DescriptionNotesÿÿÿÿÿÿPÿÿàÿÿÿÿ(ÿÿÿÿÿÿ‚ ÿÿÿÿ PrimaryKeyÿÿS{öqìg!²®Gh)Ü‘JFFü¸84Eü´o+âÞC”OüB²fÊ}yA/á—OC©3{ãá@–U°æ2â@t_objecttrx-@2888,,,,,,,* ÿ@“r2{ãá@.‹ÍTâ@t_objecttests£@O:::......., ÿ@)¸1{ãá@›RJ(nSâ@t_objectscenarios‘@1>>>22222220 ÿ@â;1{ãá@–U°æ2â@t_objectrisks‰@0:::......., ÿ@Ç/{ãá@–U°æ2â@t_objectrequiresû@/===1111111/ ÿ@Zb Õìá@–U°æ2â@t_objectpropertiesi@/???33333331 ÿ@þ¥ /{ãá@¡ÈE(nSâ@t_objectproblemsS@.===1111111/ ÿ@ù;R.{ãá@ÒˆàÓsâ@t_objectmetricsñ@.<<<0000000. ÿ@öôÕ-{ãá@gøï¯2â@t_objectfilesÖ@-:::......., ÿ@íý",{ãá@–U°æ2â@t_objectconstraintä@-???33333331 ÿ@áÇ%{ãá@Þ¿âÓsâ@t_objecti*555)))))))' ÿ@Ü­!#{ãá@ÒˆàÓsâ@t_metrictypes@):::......., ÿ@Ò )"{ãá@aø¯æ2â@t_mainttypesr@)999-------+ ÿ@ÏA‰F(nSâ@A‰F(nSâ@t_listse@444(((((((& ÿ@̱$µ×ñá@ümŠÍTâ@t_issuesV@M555)))))))' ÿ@É5N”Uèá@Ôc–Üðá@t_implement2@%888,,,,,,,* ÿ@Ç·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ¸8 {ãá@aø¯æ2â@t_glossaryÅ@&777+++++++) ÿ@´1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ±A‰F(nSâ@væF(nSâ@t_filesƒ@444(((((((& ÿ@¬œ}{ãá@aø¯æ2â@t_efforttypesÎ@:::......., ÿ@ ¤Ö%F(nSâ@ŹuTâ@t_documentˆ@777+++++++) ÿ@ŸŒ{ãá@™ 8ãÓsâ@t_diagramtypesò@;;;///////- ÿ@š {ãá@oÊ ãÓsâ@t_diagramobjects<@===1111111/ ÿ@••ú|-â@/ïI(nSâ@t_diagramlinks//////////- ÿŒ¬é{ãá@oÊ ãÓsâ@t_diagram@ '666*******( ÿ@ ~B/{ãá@aø¯æ2â@t_constrainttypesº@%>>>22222220 ÿ@ù~À> gâ]ØSÎIÄ?º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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVC\ëìN „„Ÿ   ä2  äÿ2  ä2 ä ä ä ä  ä ä  ä  ä  ä!ÿ  äÿ  äØÿ  äŸ'ÿ  ä”2  ä'ÿ  ä Type ProductNameDataTypeSizeMaxLenMaxPrecMaxScale DefaultLen DefaultPrec DefaultScaleUserPDATA1PDATA2PDATA3PDATA4 HasLength GenericType DatatypeIDÿÿÿÿ”ÿÿÿÿ'ÿÿÿÿ”ÿÿÿÿ'ÿÿ„‹ ÿÿÿÿ PrimaryKeyÿÿa{öqà ƒ¼q'á•O¿n)ßÛD—W͈<òª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.(% ÿ;ƒ°bÅu&ÞŒ>ðžšDTÀr&à—M·fÈycess6CodeVisualcess6CodeVisual 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È~6ê§dÚ‘N Â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)% ¿9ƒ»v1ä›V Ç}:õ°g&ÛKÐLăBÿ¾{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/)% ¿)ƒ»w2è ZÒŽDü¸v.âŸZÓ’Q Å~zA9ù¸mŠDŠDDLDB2TIMESTAMPtimestamp=444444+(% ÿ‰DDLDB2TIMEtime3//////+(% ÿessA pro that must oˆDDLDB2SMALINT2222222+(% O‡DDLDB2REALreal3//////+(% ÿ!…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+)% ¿4ƒ¹t.åšQ¿z3âŸV Ê<8Cõ¬¨Be¸e¿vÿ ¦DDLInterBasencÿ ¦DDLInterBasencharnchar;6666661(% ÿ¥DDLSQL Server 2000bitbooleanA::::::7(% ÿ@2¤DDLSQL Server 2000varbinaryvarbinaryI@@@@@@7(% ÿ&&& £DDLSQL Server 2000numericnumericE>>>>>>7(% ÿ¢DDLSQL Server 2000sql_variantsqlvariantLBBBBBB7(% ÿ&&& ¡DDLSQL Server 2000decimaldecimalE>>>>>>7(% ÿ DDLMySqlTEXTtext5111111-(% ÿ "ÿ2žDDLMySqlVARCHARvarchar;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+(% ÿmƒ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!„B€…………………… … … … … … … ……………………………………††† †!†"†#†$†%†&† '† († )† *† +†,†-†.†/†0†1†2†3†4†5†6†7‡8‡9‡:‡;‡<‡=‡>‡?‡@‡ A‡ B‡ C‡ D‡ E‡F‡G‡H‡I‡J‡K‡L‡M‡N‡O‡P‡Q‡RˆSˆTˆUˆVˆWˆXˆYˆZˆ[ˆ \ˆ ]ˆ ^ˆ _ˆ `ˆaˆbˆcˆdˆeˆfˆgˆhˆiˆjˆkˆlˆmˆn‰o‰p‰q‰r‰s‰t‰u‰v‰w‰ 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ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿcÿÿgÿÿIÿÿPÿÿeÿÿIÿÿPÿÿm‘ ÿÿÿÿÿÿÿÿÿÿÿyÿÿyÿÿÿÿÿÿ ’ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ “ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ” ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Diagram_ID Diagram_TypeIDX_GUID Package_IDParentID PrimaryKeyÿÿÿÿtypest_diagramÿÿagramÿÿ¢ {öqìgâ]ØSÎIÄ€@@FŒÈÈÈÈÈÈÈÈÈÈ99Æ9Æ9ÆppÄ/*Zd€â@ZÑHlâ@TEXTLogicalLogical Model1.0Geoffrey SparksPHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=/*Zd€â@ZÑHlâ@TEXTLogicalLogical Model1.0Geoffrey SparksPHideRel=0;ShowTags=0;ShowReqs=0;Sh/*Zd€â@ZÑHlâ@TEXTLogicalLogical Model1.0Geoffrey SparksPHideRel=0;ShowTags=0;ShowReqs=0;ShowCons=0;///*Zd€â@ZÑHlâ@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.nd¹ýAÆØã@øñ–&úã@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 ¿ü÷öŒ€Ž €0Ž€1Ž€/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž ïŒ mrhjb`mŽ rakfbwŽvw`wfbi`uwŽrhjb`mŽ mrhjb`mŽ mrhjb`mŽ mrhjb`mŽ Ž mrhjb`mŽ Ž mrhjb`mŽ mrhjb`mŽ vw`wfbi`uwŽw`wfbi`uwŽw`wfbi`uwŽxvfb`vfŽreignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtraÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿId ParentIdName        ÿÿ¡ÈE(nSâ@t_objectproblemsS@ä===1111111/ ÿ@ê;R.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@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Ž öŒ€,Ž €.Ž€.Ž€*Ž €*Ž €*Ž €*Ž €*Ž €*Ž €*Ž €*Ž €*Ž €*Ž €*Ž öŒ€Ž €Ž€Ž€Ž €Ž €Ž €Ž €Ž €Ž €Ž €Ž €Ž €Ž €Ž öŒ€Ž €0Ž€1Ž€/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž €/Ž VCÜ N–– ä ä  ä¡'  äÔÿ ä  äÔÿ ä DiagramID ConnectorIDGeometryStyleHiddenPath Instance_IDÿÿÿÿ'ÿÿ¡ÿÿÔÿÿÿÿ'ÿÿ¡ÿÿÔÿÿ–—ÿÿ'ÿÿ¡ÿÿÔÿÿÿÿ'ÿÿ¡ÿÿÔÿÿÿÿ'–˜ÿÿ¡ÿÿÔÿÿÿÿ'ÿÿ¡ÿÿÔÿÿÿÿ'ÿÿ¡–™ ÿÿÿÿÿÿÿÿÿÿÿÿ ConnectorID DiagramID PrimaryKey––ÿÿE{öqìgâ]€@@“• @€ €b€b€b€b€ b€ b€ b€b €b €b €b €b€b  !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€“• @€ €b€b€b€b€b€b€b€b€0b €0b €0b €0b €0b“• @€ €b€b€b€b€b€b€ b€ b € b €b €b €b€bVCN  ››  ä ä ä ä  ä ä ä  äÿ ä Diagram_ID Object_IDRectTopRectLeft RectRight RectBottomSequence ObjectStyle Instance_IDÿÿÿÿÿÿäÿÿÿÿÿÿÿÿÿÿÿÿT›œÿÿoÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›ž ÿÿÿÿÿÿÿÿÿÿÿÿ DiagramIDObjectID PrimaryKeyÿÿ-81D5-714093282A5D} DiagramIDObjectID PrimaryKeyÿÿS{öqìg@ €€Šš @€ @€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ €ÿ€0ÿ €0ÿ €0ÿ€0ÿ€0ÿ€0ÿ !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€Šš @€ @€<ÿ€=ÿ€>ÿ€Aÿ€Bÿ€Cÿ€Dÿ €Gÿ €Hÿ €Lÿ€Mÿ€Nÿ€Oÿ€PÿŠš @€ @€ÿ€ ÿ€ ÿ€ ÿ€ ÿ€ ÿ€ÿ €ÿ €ÿ €ÿ€ÿ€ÿ€ÿ€ÿVCN     ä÷S2  ä4ÿ ä Diagram_TypeName Package_IDÿÿÿÿSÿÿôÿÿhÿÿÿÿTÿÿÿÿÿÿ ¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ £ ÿÿÿÿÿÿÿÿ PackageID PrimaryKeyÿÿeID PrimaryKeyÿÿgramTypes 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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ@€@@€€`bwjzjw}¡`p`m}vjv¡brmm`aru`wjrp¡ brosrpfpw¡brosrvjwfvwuxbwxuf¡bxvwro¡dfsmr}ofpw¡jpwfu`bwjrprzfuzjf{¡ mrhjb`m¡rakfbw¡ s`bl`hf¡ vftxfpbf¡vw`wfbi`uw¡wjojph¡ xvfb`vf¡VCN ¥¥  ä(  äd  äÿ  äÿ  ä(  ä2  ä  ä  äd äÿ äN2 ä ä  äDocIDDocNameNotesStyle ElementID ElementType StrContent BinContentDocTypeAuthorVersionIsActiveSequenceDocDateÿÿ¥ÿÿ¦ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¦ ÿÿÿÿ PrimaryKey¥¥¥¥ÿÿE{öqìgâ]@¤           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€VCKN¨¨ ä  ä2 ä ä  äÿECFID DescriptionWeightValueNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨ªÿÿDÿÿgÿÿmÿÿDÿÿbÿÿcÿÿIÿÿRÿÿt¨« ÿÿÿÿÿÿÿÿ NumericWeight PrimaryKeyÿÿÚ{öqìM§¾ŒV#ýΡ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 language44ð¿ECF07Part-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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°§@€ fbgVW©fbgVX©fbgVY©fbgVZ©fbgV[©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 user²5 ð?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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯¬@`p`m}vjv®brdjph®brpvwuxbwjrp®dfvjhp®fm`aru`wjrp®wu`pvjwjrp®VCQN²²  ä2  äÿ2  äd  ä–  äÿ  ä ä äFileID AppliesToCategoryNameFileNotesFileDateFileSizeÿÿnÿÿnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²³ ÿÿÿÿ PrimaryKey²²ÿÿS{öqìg±           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€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 GlossaryIDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿO¹½ ÿÿÿÿ PrimaryKey¹¹ÿÿS{öqìg RLVAL žÞLö¥ÁŠyn@€ @€ @€ @€ @€ @€ @€ @€ @€          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`wjrp»bm`vv»brosrpfpwordfm»bxvwrofu»dfsmr}ofpw`ubijwfbwxuf»dfsmr}ofpwordfm»f|wfpdvufm`wjrpvijs»jpbmxdfvufm`wjrpvijs»xvfb`vf» VCiN¿¿ ä2  äTypeTemplate¿¿ÿÿÚ{öqì }ÎLVALèÿuà #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#

 

 

VC—NÈÈ ä  äÿÿÿ  äÿ  äImageIDNameTypeImageÈÈÿÿÚ{öqìVCDNÊÊ  ä2Typeÿÿè{öÆÉðäÖÒ•\(ì¶FÛ¡É£úW}‹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 VCêN ÍÍ  äøúÿ ä  äøúÿ  ä”2  äøú  ä”ÿ ä  ä” ä  ä”ÿ  äøú2  ä”2 äøúdIssue IssueDateOwnerStatusNotesResolver DateResolved ResolutionIssueIDCategoryPrioritySeverity IssueTypeÿÿÿÿúÿÿøÿÿ”ÿÿÿÿúÿÿøÿÿ”ÿÿÍ  ÿÿÿÿ PrimaryKeyÍÍÍÍÿÿC{öqìgââÄ]O9[N  ÿÿ ÿ ÿÿ ÿ      ÿ <ProducaddressPrivateNot Specified1100String{A8DF581B-9AC6-4f75-AB48-8FAEDFC6E068} €volatile=0;xRLLKKKJJJIH;;4-÷çPVCÿNÐÐ  ä2  äd  ä– ä  äListIDCategoryNameNValNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÑ ÿÿÿÿ PrimaryKeyÐÐÿÿS{öqìgÏ.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€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€VC>NÓÓ ä¡'  äÔ2 ä  äÔÿ MaintType Description NumericWeightNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÕ ÿÿÿÿÿÿÿÿ NumericWeight PrimaryKeyÿÿÚ{öqì Ò           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€ÒVC*N×× ä  äÿ  ä2  ä2 Object_IDNameScopeTypeÿÿhÿÿNÿÿeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×Úÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×Û ÿÿÿÿÿÿÿÿ Object_ID PrimaryKeyÿÿF3CF-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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,o`jpww}sfv€w,ofwird€w,ofwujbw}sfv€w,rakfbw€w,rakfbwbrpvwu`jpw€w,rakfbwfggruw€w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€VC;NÝÝ ä  ä2 ä  äÿMetric Description NumericWeightNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝà ÿÿÿÿÿÿÿÿ NumericWeight PrimaryKeyÿÿght PrimaryKeyÿÿÚ{öqì€@@Zܬm©ntdg,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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌÜ@auf`l`hfÞbi`phfÞbrvwÞsurhufvvÞwf`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*ÿÿsÿÿaÿÿ ÿÿsÿÿcÿÿsÿÿDÿÿtÿÿeçè ÿÿeÿÿpÿÿSÿÿrÿÿRÿÿeÿÿtÿÿSÿÿréê ÿÿSÿÿrÿÿIÿÿgÿÿeÿÿtÿÿSÿÿrÿÿIëìÿÿÿÿÿÿÿÿÿÿÿÿIDX_GUID Object_ID Package_IDââ#ââ$ââ'â â( â â, â â6âãÿÿ â, â â6âãÿÿ â6âãÿÿ â6âãÿÿ â6âãÿÿ â6âãÿÿ {öqìgâ]ØSÎIÄ?º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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,o`jpww}sfv€w,ofwird€w,ofwujbw}sfv€`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd¬LVALȺqìgÿ ÿ               €t_diagramobjects.Diagram_ID=222t_packaget_objectt_object_1t_diagramobjectst_objectt_objectt_package*@%?t_objectt_object_1*@&?t_objectt_diagramobjects/@, ?B€t_object.Classifier_guid,3A€t_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)­á È""Æ"Æ"ÆT…f{¥Ï  ÿÿ9P,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ6Ð)ë)ã@d¨ì0ë)ã@àInterfaceCookingPlace1.0interface1Proposed1Java1.0Public{E21E535F-E300-4405-A917-28FFB4B2DB6E}§§§§§§§§§{xxxxttttttttttskkjaa^^^RI%Oßÿb9O.ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!Ceúã@¨÷ñúã@Aor.EObjectWetRoom1.01Proposed0Java1.0Public{783325F8-9AA7-4836-A0D9-DDA9103CDC71}{244CC9E5-1F81-4164-9215-C048EC679543}¼¼¼¼¼¼¼––pppjggggccccccccccbZZYYYVVVOI%OÝÿb.9N.ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?é“þùã@Çqúã@BagraObjectSomeone1.01Proposed0Java1.0Public{960E757D-3D81-43e2-BA2E-5F7341421EA5}{2F1D9CC6-F38F-4a34-B3C4-B92915108384}¼¼¼¼¼¼¼––pppjggggccccccccccbZZYYYVVVOI%OÝÿb.9M.ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿd¨ìðùã@ôT`úã@>_IDCObjectHotRoom1.01Proposed0Java1.0Public{9907C98A-7E63-47dc-8A4D-ED020B68C41D}{9CE44C59-37E4-4117-8C05-F87C4DC33529}¼¼¼¼¼¼¼––pppjggggccccccccccbZZYYYVVVOI%OÝÿb.9L.ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿG÷ü×ùã@@ÈPúã@=ctorObjectYellowRoom1.01Proposed0Java1.0Public{5D770C43-247F-41e6-BC35-93C5A9204E76}{14DB5E54-CD7B-4c84-998C-44960049D7E0}¿¿¿¿¿¿¿™™sssmjjjjffffffffffe]]\\\YYYOI%OÝÿb.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%OÝÿb.9G.ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿq2ÉØã@ ÞÇúã@<ObjectSomeonesHouse1.01Proposed0Java1.0Public{3D59084A-BBC6-4d6b-B8E5-9A764D27563B}{436D81AD-A9B0-44d8-8AD1-86BB0808DA32}œœvvvpmmmmiiiiiiiiiih``___\\\OI%OÝÿb.‡+“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 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿo{oá @€ @€€<^€=^ €>^ €?^ €@^ €A^ €B^€C^€D^€E^€Gå€Hå€Lå€Må€Nå €Oå €På €=^ €=^ €=^ €=^ €=^ €=^ €=^ o{oá @€ @€€^ €^€+^ €+^ €+^ €,^€,^ €,^€,^€,^€,å €.å€.å€.å€.å€.å €.å €^ €^ €^ €^ €^ €^ €^ VCÓNîî ä  äÿâÿ  ä.( ä  äª'  ä2 Object_ID ConstraintConstraintTypeWeightNotesStatusÿÿ2ÿÿ0ÿÿ9ÿÿ9ÿÿEÿÿ¯ÿÿ¯ÿÿ¯ÿÿ‰îïÿÿ~ÿÿvÿÿÿÿÿÿ#ÿÿÿÿÿÿÿÿîðÿÿdÿÿÿÿ'ÿÿªÿÿdÿÿÿÿ'îñ ÿÿÿÿÿÿÿÿÿÿÿÿObjectConstraintConstraintObjectID PrimaryKeyîîÿÿE{öqìgâ]€í           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€ííVCTNóó ä  äÿ  ä  ä  ä Object_IDEffort EffortTypeEValueNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóõ ÿÿÿÿÿÿÿÿObjectID PrimaryKeyóóÿÿÌ{öqìgâ ò           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€òVC N÷÷ ä  äœÿ  ä '2  äœ  ä 'ÿ  äÿ Object_IDFileNameTypeNoteFileSizeFileDateÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ø ÿÿÿÿ PrimaryKey÷÷ÿÿS{öqìgö           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€VC«Núú ä  äpeÿ  ät_  ä  äes Object_IDMetric MetricTypeEValueNotesÿÿÿÿÿÿÿÿ4ÿÿÿÿÿÿÿÿ8ÿÿúûÿÿÿÿÿÿ;ÿÿÿÿÿÿÿÿ:ÿÿÿÿúüÿÿ=ÿÿÿÿÿÿÿÿAÿÿÿÿÿÿúý ÿÿÿÿÿÿÿÿÿÿÿÿObjectIDObjectMetricsMetric PrimaryKeyúúÿÿ&{4284C791-A819-44C8-B0AD-41BCCD533E6A}ObjectIDObjectMetricsMetric PrimaryKeyúúÿÿC{öqìgâ]]Ä ù           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€ùùVC¬N ÿÿ ä  äÿÿ  ä'ÿ ä  ä'2  ä  äÿ  äÿ ä   ä2  ä  äb2 ä2 Object_IDProblem ProblemType DateReportedStatus ProblemNotes ReportedBy ResolvedBy DateResolvedVersion ResolverNotesPrioritySeverityÿÿ”ÿÿÿÿ'ÿÿÿÿ”ÿÿÿÿ'ÿÿÿÿ”ÿÿÿÿÿ'ÿÿÿÿ”ÿÿÿÿ'ÿÿÿÿ”ÿÿÿÿÿ”ÿÿÿÿ'ÿÿÿÿ”ÿÿÿÿ'ÿ ÿÿÿÿÿÿÿÿÿÿÿÿObjectIDObjectRequiresRequirement PrimaryKeyÿÿ ÿÿÿÿ7 {öqìgâ]ØSþ€9           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþvrofwijphþ€9dfgfbwvrofwijphVCpN ä ä  äÿ  ä¸ÿ  ä  äÿÿ( PropertyID Object_IDPropertyValueNotesea_guidÿÿäÿÿÿÿÿÿÿÿ ÿÿÿÿäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿ Object_ID PrimaryKeyÿÿÌ{öqìgâ@            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€VC…N   ä ä  äÿ  äÿ  äÿÿ2  ä  äÿÿ2  ä002  ä"#2  äReqID Object_ID RequirementReqTypeStatusNotes Stability DifficultyPriority LastUpdateÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ( ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0 ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”  ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿObjectIDObjectRequiresRequirement PrimaryKeyReqIDÿÿ¾{öqìgâ]Ø           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€VCN   ä  äÿ  äÕÿ ä  ä ä  ä ä  äor  ä  ä" Object_IDResourceRoleTimeNotesPercentComplete DateStartDateEndHistory ExpectedHours ActualHoursÿÿÿÿÿÿÿÿÿÿÿÿ2ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿObjectID PrimaryKeyÿÿ¾{öqìgâ]Ø€            !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€ VCPN ä  äÿ  ä  ä  ä Object_IDRiskRiskTypeEValueNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿObjectID PrimaryKeyÿÿÌ{öqìgâ           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €VC™N ä  ä”ÿ  ä'  ä  ä'  ä  ä( Object_IDScenario ScenarioTypeEValueNotes XMLContentea_guidÿÿeÿÿPÿÿcÿÿtÿÿmÿÿeÿÿ ÿÿtÿÿtÿÿrÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿObjectID PrimaryKeyÿÿ¾{öqìgâ]Ø€           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€VC1N  ä  äefÿ ä  äl  ä  äV ä  äcr  äInÿ  äÿ  ä2  äec Object_IDTest TestClassNotes InputDataAcceptanceCriteriaDateRunResultsRunByCheckByTestTypeStatusÿÿÿÿÿÿ ÿÿÿÿÿÿ ÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿObjectID PrimaryKey  ÿÿž{öqìgâ]ØSÎIIÂIÂÄ€           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€„­·¸€@ €€@ €@ €@ @@€ @@brosrpfpwf|fbxw`amf±brosrpfpwgjmf±brosrpfpwmjau`u}± brosrpfpww`amf± brpvwu`jpwjpz`uj`pw± brpvwu`jpwsrvwbrpdjwjrp± brpvwu`jpwsufbrpdjwjrp± dfsfpdfpb}`bbfvv±dfsfpdfpb}ajpd±dfsfpdfpb}b`mm±dfsfpdfpb}dfujzf²dfsfpdfpb}gujfpd²dfsfpdfpb}josruw²dfsfpdfpb}jpvw`pbfrg²dfsfpdfpb}jpvw`pwj`wf²dfsfpdfpb}sr{fuw}sf²dfsfpdfpb}ufgjpf²dfsfpdfpb}vfpd²dfsfpdfpb}wu`bf²dfsfpdfpb}xvf² hfpfu`mj~`wjrpjosmfofpw`wjrp² hxjfmfofpwaxwwrp² hxjfmfofpwbifblar|² hxjfmfofpwbroarar|² hxjfmfofpwd`wf²hxjfmfofpwdj`mrh²hxjfmfofpwdursdr{p²hxjfmfofpwgruo²hxjfmfofpwimjpfµ hxjfmfofpwmjvw³hxjfmfofpwmjvwzjf{³hxjfmfofpws`pfm³hxjfmfofpwu`djr³hxjfmfofpwufsruw³hxjfmfofpww`a³hxjfmfofpwwf|war|³hxjfmfofpwwjof³hxjfmfofpwwuffmjvw³rrrrrrrrrrrrrnnffeeebSSPI#oÝ¿`7ü'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€â@XÏJw7â@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ù'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€â@’un¾2â@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ßÿ`VC¬N ä  ädÿ  äª'  ä  äª' Object_IDTRXTRXTypeWeightNotesÿÿsÿÿÿÿÿÿ'ÿÿªÿÿdÿÿÿÿ'ÿÿªÿÿÿÿÿÿ'ÿÿªÿÿdÿÿÿÿ'ÿÿªÿÿd ÿÿÿÿdÿÿÿÿ'ÿÿªÿÿdÿÿ! ÿÿÿÿÿÿÿÿÿÿÿÿObjectConstraintConstraintObjectID PrimaryKeyÿÿE{öqìgâ]€           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVC;:N##:  ä2  äÔÿ ä ä Object_Type Description DesignObjectImageIDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ#&ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ#' ÿÿÿÿÿÿÿÿImageID PrimaryKeyÿÿÚ{öqì€@ C!üGºr$×ÓF”NÖB÷óD¨`ËÇC;益BU¾Ax-Ý“@­­»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 ÿ@ŽA‰F(nSâ@A‰F(nSâ@t_scriptk@555)))))))' ÿ@‰œB{ãá@–U°æ2â@t_scenariotypes‡@;<<<0000000. ÿ@†væF(nSâ@væF(nSâ@t_rulesi@444(((((((& ÿ@ÈŒ@{ãá@–U°æ2â@t_rtfreportq:888,,,,,,,* ÿ@n®›>{ãá@–U°æ2â@t_roleconstraint:@9===1111111/ ÿ@j!£={ãá@–U°æ2â@t_risktypes{@9888,,,,,,,* ÿ@g8Xt*Mçá@–U°æ2â@t_resourcesª@8888,,,,,,,* ÿ@bpl<{ãá@–U°æ2â@t_requiretypesŒ@8;;;///////- ÿ@Y]@.Nçá@–U°æ2â@t_projectroles@6;;;///////- ÿ@T¬m;{ãá@–U°æ2â@t_problemtypesÓ@6;;;///////- ÿ@Pü6:{ãá@–U°æ2â@t_primitives"@7999-------+ ÿ@N‚Êøï¯2â@‚Êøï¯2â@t_paletteitem.........., ÿL‚Êøï¯2â@‚Êøï¯2â@t_palette**********( ÿCöhÒÝnæá@[,ãâÓsâ@t_package”@7666*******( ÿ@?6Û*°,â@–U°æ2â@t_operationtag//////////- ÿ7x‹7{ãá@–U°æ2â@t_operationposts8@5===1111111/ ÿ@2Ñ6{ãá@/ïI(nSâ@t_operationparams«@5>>>22222220 ÿ@+]š5{ãá@/ïI(nSâ@t_operation°@4888,,,,,,,* ÿ@(С4{ãá@hï*Üðá@t_ocf¿@2222&&&&&&&$ ÿ@¶":èÖ¸ ŒzX>&Ù¿­›‹{gQ6úâã}mWG3ṳ́ŒN(þÞªŽ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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@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ÿÿè{öÌ(îÚ(C»X}‹Sâ@C»X}‹Sâ@t_ocf$$$$$$$$$$$ ¿"C»X}‹Sâ@C»X@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_guidStyleExÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0 ,-ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ” ,.ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿ,/ÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(01 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿName Object_ID OperationID PrimaryKey ,, ,, ,,, , , ,ÿÿ {öqìgâ]ØSÎIÄ?º5€@ @@ý+fpwfuæ"           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($ÿ+€=æÿ+€æo{ÿ+€æVCSN 33 ä  äÿÿ  äÚ&ÿ  äÿ  ä0( ä ä  äÿ  ä  ä2  äpe2  äp OperationIDNameTypeDefaultNotesPosConstStyleKind Classifierea_guidStyleExÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”34ÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿ35ÿÿ0ÿÿ”ÿÿÿÿ(ÿÿ0ÿÿ”ÿÿÿÿ(36 ÿÿÿÿÿÿÿÿÿÿÿÿ OperationIDParam PrimaryKey33 33ÿÿ7 {öqìgâ]ØS@ 2€P€P          !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$2€€P€€P2€suoXP€suoXPVCAN88 ä  äÔÿ  äÿ  ä OperationID PostConditionTypeNotesÿÿeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ89ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8: ÿÿÿÿÿÿÿÿ OperationID PrimaryKey88ÿÿÌ{öqìgâ7           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$7VC@N<< ä  äÔÿ  ä2  ä OperationID PreConditionTypeNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<> ÿÿÿÿÿÿÿÿ OperationID PrimaryKey<<ÿÿÌ{öqìgâ@ ;           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$;VCqN@@ ä ä  äÿ  ä¸ÿ  ä  äÿÿ( PropertyID ElementIDPropertyVALUENOTESea_guidÿÿäÿÿÿÿÿÿÿÿ ÿÿÿÿäÿÿÿÿ@Aÿÿÿÿÿÿÿÿÿÿÿÿäÿÿÿÿÿÿ@B ÿÿÿÿÿÿÿÿ ElementKey PrimaryKey@@ÿÿÌ{öqìgâ?€R           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€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 BatchLoadÿÿtÿÿrÿÿAÿÿPÿÿ ÿÿiÿÿtÿÿiÿÿDH ÿÿeÿÿeÿÿaÿÿ ÿÿdÿÿiÿÿDÿÿeÿÿTDIÿÿeÿÿnÿÿhÿÿBÿÿdÿÿÿÿoÿÿaÿÿaDJÿÿTÿÿLÿÿkÿÿÿÿ_ÿÿiÿÿTÿÿsÿÿwDK ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIDX_GUID Package_IDParentID PrimaryKeyDDÿÿyKeyDDÿÿyKeyDDÿÿyKeyDDÿÿ¾{öqìgâ]Ø ý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 GŠLVAL ÈÈÈÈÈÌ깪ÿÿÿ&ÿ&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>PÿÿÿÿnRDSource -> DestinationDependencyPublicPublicUnspecifiedUnspecified«implements»implements0{9613E9DD-8709-4e9e-92D8-2F6CA9835851}ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ­­­­­­­¬¢¢––––––‹‹‹‹‹€€€€€zzztttjjUUÿ5•„à ýÿÀQOGÿÿÿÿdiagSource -> DestinationAggregationStrongPublicPublicUnspecifiedUnspecified0SX=36;SY=-9;EX=45;EY=-9;{FF2ECD20-22FF-4734-9DB4-8316A98DDC16}roomààÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜܶžžžžžž’’’’’‡‡‡‡‡{{ujjUUÿ5µ„à ü¿à€QNGÿÿÿÿdiagUnspecifiedAssociationPublicPublicUnspecifiedUnspecified0{AFD66AB6-337B-49c5-9FA9-0CFAFEB77AA7}home¸´´´´´´´´´´´´´´´´´ŽŽŽŽŽŽŽ‚‚‚‚‚wwwwwqqqkkk``UU5•„à ü¿À QMGÿÿÿÿdiagSource -> DestinationAggregationStrongPublicPublicUnspecifiedUnspecified0{9DDBD985-D9D5-408c-A8F4-40085F2E8E5B}roomÈÈÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄžžžžžžž’’’’’‡‡‡‡‡{{ujjUUÿ5µ„à ü¿À€QHGÿÿÿÿdiagSource -> DestinationAggregationStrongPublicPublicUnspecifiedUnspecified0{3F0E9949-A749-4958-9A1B-40E3F0E12393}roomÈÈÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄžžžžžžž’’’’’‡‡‡‡‡{{ujjUUÿ5µ„à ü¿À€QLGÿÿÿÿýRDSource -> DestinationAggregationStrongPublicPublicUnspecifiedUnspecified0{D775B2C1-C7AF-4a19-A4D5-7B3AC816664C}roomÈÈÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄžžžžžžž’’’’’‡‡‡‡‡{{ujjUUÿ5µ„à ü¿À€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 äC€E€+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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäC€E€E€E€,E€,E€ G€ G€ G€ G€ G€ G€ G€ G€ G€ G€ G€ G€ G€ G€ GäC€E€+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€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$è{öVC´NQQ ä2  ä2Datatype DescriptionÿÿeÿÿÿÿÿÿÿÿÔÿÿÿÿÿÿÿÿQS ÿÿÿÿ PrimaryKeyÿÿa{öqZPéÖÄ´Ÿƒr@€ €@@ €€€€ @€@€@@€@@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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,o`jpww}sfv€w,ofwird€w,ofwujbw}sfv€w,rakfbw€w,rakfbwbrpvwu`jpw€w,rakfbwfggruw€w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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/false½P €@arrmf`pRbi`uRdrxamfRjpwRmrphRvwujphR|omR  ä  äIdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtraÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿId ParentIdName        ÿÿ¡ÈE(nSâ@t_objectproblemsS@ä===1111111/ ÿ@ê;R.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVC@NUU  ä  äÔÿ ä  äÿ ProblemType Description NumericWeightNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<ÿÿ=ÿÿUWÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<ÿÿ>ÿÿUX ÿÿÿÿÿÿÿÿ NumericWeight PrimaryKeyÿÿÚ{öqì€@@íTß«n>@€ €@@ €€€€ @€@€@@€@€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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,o`jpww}sfv€w,ofwird€w,ofwujbw}sfv€w,rakfbw€w,rakfbwbrpvwu`jpw€w,rakfbwfggruw€w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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 €¿ðV¿ðV¿ðV¿øVÀV ä  ä  äIdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtraÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿId ParentIdName        ÿÿ¡ÈE(nSâ@t_objectproblemsS@ä===1111111/ ÿ@ê;R.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔT i{Vpfw{rulVsfugruoVv{VxvfuVVCÒ NZZ  äÿ  äÿÿ  äP(Role DescriptionNotesÿÿsÿÿÿÿÿÿÿÿPÿÿàÿÿÿÿ(ÿÿZ] ÿÿÿÿ PrimaryKeyZZÿÿS{öqìg  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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,o`jpww}sfv€w,ofwird€w,ofwujbw}sfv€w,rakfbw€w,rakfbwbrpvwu`jpw€w,rakfbwfggruw€w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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 schedule€Manage the project schedule GJava ProgrammerJava programming DeveloperApplication development!! C++ ProgrammerProgramming in Visual C++((Business AnalystModel business processes))Application AnalystDefine and model the application structure>>ÅLVALÑDefine 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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVCÖN__  ä2  äÿ2  äP(Property DescriptionNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_a ÿÿÿÿ PrimaryKey__ÿÿS{öqìg~^⯎@€ €@@ €€€€ @€@€@@€@€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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,o`jpww}sfv€w,ofwird€w,ofwujbw}sfv€w,rakfbw€w,rakfbwbrpvwu`jpw€w,rakfbwfggruw€w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,o`jpww}sfv€w,ofwird€w,ofwujbw}sfv€w,rakfbw€w,rakfbwbrpvwu`jpw€w,rakfbwfggruw€w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,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 €@¿ðd¿ðd¿ðd¿ðd¿ðd¿ðd¿ù™™™™™šdä  äIdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtraÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿId ParentIdName        ÿÿ¡ÈE(nSâ@t_objectproblemsS@ä===1111111/ ÿ@ê;R.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥b @ djvsm`}dgxpbwjrp`mdsfugruo`pbfdsujpwjphdufsruwdwfvwjphdz`mjd`wfdVCZN hh  äÿ  äÿÿ  äÿ2  ä2  ä2  ä2  äÿ  äÿ  äÿName OrganisationPhone1Phone2MobileFaxEmailRolesNotesÿÿpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿhi ÿÿÿÿ PrimaryKeyÿÿa{öqg           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$VC9Nkk ä  äÔ2 ä  äÿRisk Description NumericWeightNotesÿÿeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿklÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿkm ÿÿÿÿÿÿÿÿ NumericWeight PrimaryKeyÿÿÚ{öqì j           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$jVCÂNoo ä  ädÿ  äª'2  ä  äª' ConnectorID Constraint ConnectorEndConstraintTypeNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿopÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿoqÿÿÿÿÿÿÿÿÿÿÿÿÿÿor ÿÿÿÿÿÿÿÿÿÿÿÿObjectConstraintConstraintObjectID PrimaryKeyooÿÿE{öqìgâ]n           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€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\cgridasìØ¼¤v\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 )}}$LVALiÕ4\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 }LVALʦjÇ'\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 ?;}{\levelnum÷LVALbers;}\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\leve…LVAL‘lfollow0\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€€€€ÿÿ¾{öqìgâ]Ø  ÖLVAL‘n“)î @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @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 ÿÿ¢LVALT°The 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@@`ubijwfbwxufordfm‚bm`vvordfm‚brosrpfpwordfm‚dfsmr}ofpw‚dfzfmrsofpwsurdxbwv‚dus‚d}p`ojbordfm‚jpwfuzjf{v‚ufmf`vfo`p`hfofpw‚xvfb`vfordfm‚ oreignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtraÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿId ParentIdName        ÿÿ¡ÈE(nSâ@t_objectproblemsS@ä===1111111/ ÿ@ê;R.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿH@@`ubijwfbwxufordfm‚bm`vvordfm‚brosrpfpwordfm‚dfsmr}ofpw‚dfzfmrsofpwsurdxbwv‚dus‚d}p`ojbordfm‚jpwfuzjf{v‚ufmf`vfo`p`hfofpw‚xvfb`vfordfm‚ VC„N  ‡‡  ä2  äÿÿ  äriÿ ä  äÿ  äÿ  ä  äc  äRuleIDRuleNameRuleType RuleActiveErrorMsgFlagsRuleOCLNotesRuleXMLÿÿÿÿÿÿÿÿÿÿÿÿ(ÿÿÿÿÿÿÿ‡ˆ ÿÿÿÿ PrimaryKey‡‡‡‡‡‡ÿÿ7 {öqìgâ]ØS†           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$VCANŠŠ ä  äÔ2 ä  äÿ ScenarioType Description NumericWeightNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿkÿÿlÿÿŠŒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿkÿÿmÿÿŠ ÿÿÿÿÿÿÿÿ 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}sfv€w,d`w`w}sfv€w,dj`hu`o€w,dj`hu`omjplv€w,dj`hu`orakfbwv€w,dj`hu`ow}sfv€w,drbxofpw€w,fbg€w,fggruww}sfv€w,gjmfv€ w,hfprsw€ w,hmrvv`u}€ w,iwom€ w,jo`hf€ w,josmfofpw€w,jvvxfv€w,mjvwv€w,o`jpww}sfv€w,ofwird€w,ofwujbw}sfv€w,rakfbw€w,rakfbwbrpvwu`jpw€w,rakfbwfggruw€w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ݉€€`mwfup`wf‹a`vjbs`wi‹vjosmf‹VC8N ä  äœd  ä '–  äœÿ  ä '  äScriptIDScriptCategory ScriptName ScriptAuthorNotesScriptÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿøÿÿÿÿÿÿ ÿÿÿÿ PrimaryKeyÿÿE{öqìgâ]Ž           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$VCÏN’’  ä(  äÿ  äP(dGroupID GroupName Descriptionÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ’“ ÿÿÿÿ PrimaryKeyÿÿa{öq‘           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$VC´N••  ä( äGroupID PermissionIDÿÿÿÿÿÿÿÿÔÿÿÿÿÿÿÿÿ•– ÿÿÿÿ PrimaryKeyÿÿa{öq@”           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$VCN˜˜  ä(  äœ(  ä '  äœ( ä  äÿUserIDGroupID EntityTypeEntityID TimestampLockTypeÿÿpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜š ÿÿÿÿ PrimaryKeyÿÿa{öqdÙ€ €€ €@@@€€€€ w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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`vlv»w,wbg»w,wfosm`wf»w,wfvwbm`vv»w,wfvwsm`pv»w,wfvww}sfv»w,wu|w}sfv»w,xoms`wwfup»w,zfuvjrp»w,|ufg» w,|ufgv}vwfo» w,|ufgxvfu» xv}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[gWXWfX0»s`bl`hfdj`hu`o»— VC»Nœœ ä  ä2 PermissionIDPermissionNameÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ ÿÿÿÿ PrimaryKeyÿÿ           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€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€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$VC®NŸŸ  äd  äÿPropertyValueÿÿsÿÿnÿÿmÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ  ÿÿÿÿ PrimaryKeyÿÿa{öqž           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVCN¢¢  ä(  äœ  ä '2  äœ2  ä2  ä UserID UserLogin FirstNameSurname DepartmentPasswordÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢£ ÿÿÿÿ PrimaryKeyÿÿa{öq¡           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$VC®N¥¥  ä(  ä(UserIDGroupIDÿÿnÿÿmÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¦ ÿÿÿÿ PrimaryKeyÿÿa{öq@¤           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$VC³N¨¨  ä( äUserID PermissionIDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥ÿÿ¦¨© ÿÿÿÿ PrimaryKeyÿÿa{öq§           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$€¤$VCdN«« ä2  ä2Status Descriptionÿÿè{öWªÜ¾§„k™\$ì°u8û½€F Í™_)ë´{8ÿÁ…MÎ’ª»BZ}‹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 ¿‘PßY}‹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/////////// ¿j¯Y}‹Sâ@¯Y}‹Sâ@t_risktypes*********** ¿g¯Y}‹Sâ@¯Y}‹Sâ@t_resources*********** ¿b¯Y}‹Sâ@¯Y}‹Sâ@t_requiretypes----------- ¿^¯Y}‹Sâ@¯Y}‹Sâ@t_propertytypes........... ¿Y¯Y}‹Sâ@¯Y}‹Sâ@t_projectroles----------- ¿T¯Y}‹Sâ@¯Y}‹Sâ@t_problemtypes----------- ¿P¯Y}‹Sâ@¯Y}‹Sâ@t_primitives+++++++++++ ¿N¯Y}‹Sâ@¯Y}‹Sâ@t_paletteitem,,,,,,,,,,, ¿L¯Y}‹Sâ@¯Y}‹Sâ@t_palette((((((((((( ¿C¯Y}‹Sâ@¯Y}‹Sâ@t_package((((((((((( ¿?¯Y}‹Sâ@¯Y}‹Sâ@t_operationtag----------- ¿;¯Y}‹Sâ@¯Y}‹Sâ@t_operationpres........... ¿7¯Y}‹Sâ@¯Y}‹Sâ@t_operationposts/////////// ¿2¯Y}‹Sâ@¯Y}‹Sâ@t_operationparams00000000000 ¿+¯Y}‹Sâ@¯ImplementedFinished ValidatedApproved and Checked MandatoryRequired ApprovedItem is approved ProposedItem has been proposed VC…wN  ®®tw  äbÿ  ä˜ÿ  ägÿ ä  äkÿ  äÔ  än  ä2  äád Stereotype AppliesTo Description MFEnabledMFPathMetafileStyleea_guid VisualTypeÿÿèÿÿÿÿÿÿÿÿéÿÿŒÿÿÿÿ®¶ ÿÿÿÿ PrimaryKey®®®®ÿÿE{öqìgâ]À €?`­}‘`ÆYûsšˆ 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 ‡r­¡3Ômìb’&±?è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---- ‡$­põ¦6µ:Ó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­*±LÜY¿h ²U™L 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‡:­ªM↷Rõ… ˜—-Á\ô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$$$$‡*­£Ÿ=Ü{²Në“6Ði œ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++++‡7­cÜo oùœ4Ì] processactivityA classifier whose instances represent a flow{321DF02A-95C4-4473-A0FF-9C6D1B7C64EE}cc====‡ hlineGUIElement€Fill=-1;Border=-1;Font=-1;{116D042D-995D-4535-95AF-E1FA9E2F178E}\\6à vlineGUIElement€Fill=-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‡Í­¸ brosrpfpwdrbxofpw±·hxjfmfofpwwuffmjvw³vbm`vvb`vf{rulfu¯axvjpfvvbm`vvfpwjw}¯axvjpfvvbm`vvjpwfup`m{rulfu¯axvjpfvvbm`vv{rulfu¯axvjpfvvordfmrakfbwv}vwfo¯axvjpfvvordfmruh`pj~`wjrpxpjw¯axvjpfvvordfm{rulxpjw¯bm`vv`vss`hf¯ bm`vvarxpd`u}¯ bm`vvbmjfpws`hf¯ bm`vvbmjfpwvbujsw¯ bm`vvbrpwurm¯ bm`vvfpwjw}¯bm`vvfpxofu`wjrp°bm`vvf|bfswjrp°bm`vvgruo°bm`vvgu`ofvfw°bm`vvjosmfofpw`wjrpbm`vv°bm`vvjpwfug`bf°bm`vvkvss`hf°bm`vvsr{fuw}sf°bm`vvsurbfvv°bm`vvvbujswmjau`u}° bm`vvvfuzfus`hf° bm`vvvfuzmfw° bm`vvvjhp`m° bm`vvvwfufrw}sf° bm`vvw`amf°bm`vvw`uhfw°bm`vvwiuf`d°bm`vvw}sf±bm`vvxwjmjw}±bm`vv{fas`hf±bm`vvjgjfuofw`bm`vv±broofpwuftxjufofpw±broofpwufvsrpvjajmjw}±brosrpfpwdrbxofpw±brosrpfpwf|fbxw`amf±brosrpfpwgjmf±brosrpfpwmjau`u}± brosrpfpww`amf± brpvwu`jpwjpz`uj`pw± brpvwu`jpwsrvwbrpdjwjrp± brpvwu`jpwsufbrpdjwjrp± dfsfpdfpb}`bbfvv±dfsfpdfpb}ajpd±dfsfpdfpb}b`mm±dfsfpdfpb}dfujzf²dfsfpdfpb}gujfpd²dfsfpdfpb}josruw²dfsfpdfpb}jpvw`pbfrg²dfsfpdfpb}jpvw`pwj`wf²dfsfpdfpb}sr{fuw}sf²dfsfpdfpb}ufgjpf²dfsfpdfpb}vfpd²dfsfpdfpb}wu`bf²dfsfpdfpb}xvf² hfpfu`mj~`wjrpjosmfofpw`wjrp² hxjfmfofpwaxwwrp² hxjfmfofpwbifblar|² hxjfmfofpwbroarar|² hxjfmfofpwd`wf²hxjfmfofpwdj`mrh²hxjfmfofpwdursdr{p²hxjfmfofpwgruo²hxjfmfofpwmjvw³hxjfmfofpwmjvwzjf{³hxjfmfofpws`pfm³hxjfmfofpwu`djr³hxjfmfofpwufsruw³hxjfmfofpww`a³hxjfmfofpwwf|war|³hxjfmfofpwwjof³hxjfmfofpwwuffmjvw³³ÿÿÿÿÿÿÿÿÿÿc­€ @@@ @ @@€ €€@ `bwjzjw}surbfvvµ `vvrbj`wjrpvxavbujaf¯`wwujaw`amfbrmxop¯axvjpfvvbm`vvb`vf{rulfu¯axvjpfvvbm`vvfpwjw}¯axvjpfvvbm`vvjpwfup`m{rulfu¯axvjpfvvbm`vv{rulfu¯axvjpfvvordfmrakfbwv}vwfo¯axvjpfvvordfmruh`pj~`wjrpxpjw¯axvjpfvvordfm{rulxpjw¯bm`vv`vss`hf¯ bm`vvarxpd`u}¯ bm`vvbmjfpws`hf¯ bm`vvbmjfpwvbujsw¯ bm`vvbrpwurm¯ bm`vvfpwjw}¯bm`vvfpxofu`wjrp°bm`vvf|bfswjrp°bm`vvgruo°bm`vvgu`ofvfw°bm`vvjosmfofpw`wjrpbm`vv°bm`vvjpwfug`bf°bm`vvkvss`hf°bm`vvsr{fuw}sf°bm`vvsurbfvv°bm`vvvbujswmjau`u}° bm`vvvfuzfus`hf° bm`vvvfuzmfw° bm`vvvjhp`m° bm`vvvwfufrw}sf° bm`vvw`amf°bm`vvw`uhfw°bm`vvwiuf`d°bm`vvw}sf±bm`vvxwjmjw}±bm`vv{fas`hf±bm`vvjgjfuofw`bm`vv±broofpwuftxjufofpw±broofpwufvsrpvjajmjw}±brosrpfpwdrbxofpw±±brosrpfpwgjmf±brosrpfpwmjau`u}± brosrpfpww`amf± brpvwu`jpwjpz`uj`pw± brpvwu`jpwsrvwbrpdjwjrp± brpvwu`jpwsufbrpdjwjrp± dfsfpdfpb}`bbfvv±dfsfpdfpb}ajpd±dfsfpdfpb}b`mm±dfsfpdfpb}dfujzf²dfsfpdfpb}gujfpd²dfsfpdfpb}josruw²dfsfpdfpb}jpvw`pbfrg²dfsfpdfpb}jpvw`pwj`wf²dfsfpdfpb}sr{fuw}sf²dfsfpdfpb}ufgjpf²dfsfpdfpb}vfpd²dfsfpdfpb}wu`bf²dfsfpdfpb}xvf² hfpfu`mj~`wjrpjosmfofpw`wjrp² hxjfmfofpwaxwwrp² hxjfmfofpwbifblar|² hxjfmfofpwbroarar|² hxjfmfofpwd`wf²hxjfmfofpwdj`mrh²hxjfmfofpwdursdr{p²hxjfmfofpwgruo²hxjfmfofpwmjvw³hxjfmfofpwmjvwzjf{³hxjfmfofpws`pfm³hxjfmfofpwu`djr³hxjfmfofpwufsruw³hxjfmfofpww`a³hxjfmfofpwwf|war|³hxjfmfofpwwjof³hxjfmfofpwwuffmjvw³³ÿÿÿÿÿÿÿÿÿÿ§­€ €€@@ @ € @€  @hxjfmfofpwzmjpfµ mjplfpdhmra`m³ mjplfpdmrb`m³ mjplfpds`u`ofwfu³ mjplfpdvfmg³ ofvv`hfafbrof³ ofvv`hfbrs}³ofvv`hfbuf`wf³ofvv`hfdfvwur}³ordfm`p`m}vjvv}vwfo³ordfmdfvjhpv}vwfo´ordfmjosmfofpw`wjrpv}vwfo´ordfmxvfb`vfv}vwfo´prdfbduro´prdfbduro´prdfbrosxwfu´prdfdjvl`uu`}´prdfsb´prdfsbbmjfpw´prdfsbvfuzfu´ prdfvfbxuf´ prdfvfuzfu´ prdfvwru`hf´ prdfxpj|vfuzfu´ prdfxvfusb´rsw`amfbifbl´rsw`amfgl´rsw`amfjpdf|´rsw`amfsl´rsw`amfsurb´rsw`amfwujhhfuµrsw`amfxpjtxfµs`bl`hfg`b`dfµs`bl`hfgu`of{rulµs`bl`hfordfmµs`bl`hfvwxaµs`bl`hfvxav}vwfoµs`bl`hfv}vwfoµxvfvbrooxpjb`wfµxvfvf|wfpdµ xvfvjpbmxdfµ VCN ºº ä  äÿ  äÿ  ä  äÿ  äÿ  äÿ ä ä   ä 2  ä   ä  ä  ä  äkIdTaskIDNameTaskTypeNOTESPriorityStatusOwner StartDateEndDatePhaseHistoryPercent TotalTime ActualTime AssignedToÿÿºÿÿÿÿÿÿÿÿÿÿÿÿÖÿÿðÿÿº¼ ÿÿÿÿ PrimaryKeyºº ººÿÿE{öqìgâ]–)Ȇ‚G:òª¦F]à£h ÖÒD‹2.D.Ä.Ä.Ä.Ä.Ä.Ä.Ä.Ä.Ä.Ä.Äøƒ¬_Ö’QÌ„<ò€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @:€OõÛàÓsâ@;€@€™ A€oÊ ãÓsâ@oÊ ãÓsâ@t_diagramt_diagramobjects::::::::::8 ÿ@€™ 8ãÓsâ@™ 8ãÓsâ@t_diagramtypest_diagram88888888886 ÿ?€[,ãâÓsâ@[,ãâÓsâ@t_packaget_diagramtypes88888888886 ÿ>€Ä"râÓsâ@Ä"râÓsâ@t_packaget_diagram33333333331 ÿ=€Þ¿âÓsâ@Þ¿âÓsâ@t_packaget_object22222222220 ÿ<€ N¸áÓsâ@ N¸áÓsâ@t_objectt_method1111111111/ ÿ;€kâYáÓsâ@kâYáÓsâ@t_objectt_attribute44444444442 ÿ:€OõÛàÓsâ@OõÛàÓsâ@t_objectt_connector155555555553 ÿ9€ÀBpàÓsâ@ÀBpàÓsâ@t_objectt_connector44444444442 ÿ8€ÒˆàÓsâ@ÒˆàÓsâ@t_metrictypest_objectmetrics==========; ÿ7€4™ŽßÓsâ@4™ŽßÓsâ@t_connectortypest_connector<<<<<<<<<<: ÿ€ümuãá@ümuãá@Forms&&&&&&&&&&$ ÿ>*€ñ˜¨à<òá@±T¡uù÷á@zz_q_implements2I@@$@I==1111111/ ÿ@÷xÃhanôá@–U°æ2â@usysTables’@@777+++++++) ÿ@>ðXª÷„Úðá@Æú|`nôá@usysOldTablesE@=:::......., ÿ@ìrÇAÑñá@–U°æ2â@usys_system-@=888,,,,,,,* ÿ@æA‰F(nSâ@A‰F(nSâ@t_xrefuser++++++++++) ÿàA‰F(nSâ@A‰F(nSâ@t_xrefsystem----------+ ÿÚ+ì·kº2â@+ì·kº2â@t_xref''''''''''% ÿÖvæF(nSâ@væF(nSâ@t_versionp@666*******( ÿ@ÔA‰F(nSâ@A‰F(nSâ@t_umlpatternq@999-------+ ÿ@>ËG{ãá@–U°æ2â@t_testtypesƒ@<888,,,,,,,* ÿ@ÈA‰F(nSâ@A‰F(nSâ@t_testplanse@888,,,,,,,* ÿ@Å`F{ãá@–U°æ2â@t_testclass#@<888,,,,,,,* ÿ@½f)E{ãá@–U°æ2â@t_tcfœ@<222&&&&&&&$ ÿ@¹³,¬ ô1â@¡ÈE(nSâ@t_tasks((((((((((& ÿ¹w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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ÿÿÚ{öq쀀7½ Ò‰Qè½–rH"æ£[ €€ € @@@€@€@€ €w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿy½@€ @€wbgVW¿wbgVX¿wbgVY¿wbgVZ¿wbgV[¿wbgV\¿wbgV]¿wbgV^¿wbgV_¿wbgWV¿ wbgWW¿ wbgWX¿ wbgWY¿ VC+NÃà  ä(  äœ2  ä 'd  äœÿ  äÿ  ä TemplateID TemplateType TemplateNameNotesStyleTemplateÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃÄ ÿÿÿÿ PrimaryKeyÃÃÿÿS{öqìg           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$€¤$€§$€ª$€­$ €¹»€½»VCµNÆÆ ä2  ä2 TestClass Descriptionÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨ÆÇ ÿÿÿÿ PrimaryKeyÿÿa{öq€Å           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$€¤$€§$€ª$€­$ €¹»€½»€Â»VC&NÉÉ  ä2  äœd  ä '–  äœÿ  ä  äPlanIDCategoryNameAuthorNotesTestPlanÿÿeÿÿeÿÿlÿÿeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÊ ÿÿÿÿ PrimaryKeyÉÉÉÉÿÿE{öqìgâ]È           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$€¤$€§$€ª$€­$ €¹»€½»€Â»€Å»VC=NÌÌ ä  äÔ2 ä  äÿTestType Description NumericWeightNotesÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌÏ ÿÿÿÿÿÿÿÿ NumericWeight PrimaryKeyÿÿÚ{öqì€@ AËÉ”Q€ €€ € @@@€@€@€@€€w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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»w,wbg»w,wfosm`wf»w,wfvwbm`vv»w,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.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@t_objecteffort@ã;;;///////- ÿ@ÝÑÇ%{ãá@/ïI(nSâ@t_objectià555)))))))' ÿ@Ì­!#{ãá@aø¯æ2â@t_metrictypes@Þ:::......., ÿ@Èf¥"{ãá@aø¯æ2â@t_method7@Ü555)))))))' ÿ@ÝÁ±$µ×ñá@¡ÈE(nSâ@t_issues/@Ü555)))))))' ÿ@¾5N”Uèá@Ôc–Üðá@t_implement2@Û888,,,,,,,* ÿ@¼·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ³“0!{ãá@FuœÜðá@t_html(@Û333'''''''% ÿ@­8 {ãá@aø¯æ2â@t_glossaryÅ@Û777+++++++) ÿ@©1bËÿâ@1bËÿâ@t_genopt))))))))))' ÿ¯Ÿ…{ãá@aø¯æ2â@t_ecfœ@Ú222&&&&&&&$ ÿ@šŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàËmr`dÍufhufvvjrpÍvw`pd`udÍVC}NÑÑ  ä2 ä  ä  ä¸ÿ ä  äÿÿ Description NumericWeightNotesTRXTRX_IDStyleÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÓ ÿÿÿÿÿÿÿÿ NumericWeight PrimaryKeyÑÑÑÑÿÿ¾{öqìgâ]ØÐ           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$€¤$€§$€ª$€­$ €¹»€½»€Â»€Å»€È»€Ë»ÐVCNÕÕ ä  äd  ä–  äÿ  ä  ä  ä2 PatternIDPatternCategory PatternNameStyleNotes PatternXMLVersionÕÕÕÕÿÿÌ{öqìgâVCãN ××  ä2  äÿ  äd  äÿ  äÿ  äÿ  äÿ ä  ä ÿ  ä ElementID VersionID ElementTypeFlags ExternalFileNotesOwner VersionDateBranch ElementXMLÿÿkÿÿpÿÿNÿÿEÿÿPÿÿoÿÿtÿÿSÿÿtרÿÿeÿÿnÿÿaÿÿÿÿaÿÿÿÿsÿÿr×Ù ÿÿÿÿÿÿÿÿ ElementID PrimaryKey ××ÿÿ22222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$€¤$€§$€ª$€­$ €¹»€½»€Â»€Å»€È»€Ë»€Ð»Ì{öqìgâÖ           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$€¤$€§$€ª$€­$ €¹»€½»€Â»€Å»€È»€Ë»€Ð»€Ô»ÖVCÊN ÛÛ  äÿ  äÿ  äÿ  äÿ  äÿÿÿ  äÿ  äÿÿÿ  äÿ  äÿ ä äÿ äÿ ä<(ÿXrefIDNameType Visibility Namespace Requirement ConstraintBehavior Partition DescriptionClientSupplierLinkÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÛÜ ÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÛÝ ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÛÞÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$Ûßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ PrimaryKey XRefClient XRefSupplierXRefType ÛÛÿÿ¾{öqìgâ]Ø€@ „Ú.^``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€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€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}\VCãNáá  äÿ  ä2  äÿ  äÿ  äÿÿÿ  äÿ  äÿÿÿ  äÿ  äÿ äÿ ä äÿ ä<(ÿ  ä$ÿXrefIDToolIDNameType Visibility Namespace Requirement ConstraintBehavior Partition DescriptionClientSupplierLinkÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$áâ ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿáã ÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(áäÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=áåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ PrimaryKey XRefClient XRefSupplierXRefType ááÿÿ¾{öqìgâ]Ø à           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$€¤$€§$€ª$€­$ €¹»€½»€Â»€Å»€È»€Ë»€Ð»€Ô»€Ö»€Ú» àààVCãNçç  äÿ  ä2  äÿ  äÿ  äÿÿÿ  äÿ  äÿÿÿ  äÿ  äÿ äÿ ä äÿ ä<(ÿ  ä$ÿXrefIDToolIDNameType Visibility Namespace Requirement ConstraintBehavior Partition DescriptionClientSupplierLinkÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$çè ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿçé ÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(çêÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=ÿÿ$ÿÿÿÿ(ÿÿ=çëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ PrimaryKey XRefClient XRefSupplierXRefType ççÿÿ¾{öqìgâ]Øæ           !222222222 2 !2 "2 #2 $2 %2&2'2(2)2€€€€€€€€$2€92€>2€E2€J2€N2€S2€V2€\2€m2€r2€v2€z2€~€€ƒ€€Œ€€•€€š€€Ÿ€€¤€€§€€¬€€±€ €´€ €¸€ €¾€ €Ç€ €É€€Ì€€Ï€€Ò€€Ö€€Ü€€á€€í€€ò€€ö€€ù€€þ€€€€€€ €€€€€€€€€ €"$€($€+$€2$€7$€;$€?$€C$€L$€N$ €P$ €T$ €Y$ €^$ €b$€g$€j$€n$€s$€$€†$€‰$€Ž$€‘$€”$€—$€›$€ž$€¡$€¤$€§$€ª$€­$ €¹»€½»€Â»€Å»€È»€Ë»€Ð»€Ô»€Ö»€Ú» €à» æææVC®SNííHJ ä2  ä2PropertyValueÿÿoÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíï ÿÿÿÿ PrimaryKeyÿÿa{öq€@@SìSíÛÇ®ŠxfR=- øÛÁ°žŠq]J5$ÿìÕ÷ zl`VD+ÿïÛǺ¬›…zhYI8%ÿóäÔ¿°¡”€jZK9,ÿãÓæŽ}jT?*@@w,rakfbwgjmfv€w,rakfbwofwujbv€w,rakfbwsuramfov€w,rakfbwsursfuwjfv€w,rakfbwuftxjufv€w,rakfbwufvrxubf€w,rakfbwujvlv€w,rakfbwvbfp`ujrv€w,rakfbwwfvwv€w,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,brmxopvîYWV,gjmfw`amfîYWV,hfpfu`mj~`wjrpîYWV,jo`hfvîYWV,ofw`gjmfîYWV,s`mfwwfîYWV,trakfbwîYWV,w`amfmjvwîYWV,w`amfmjvwXî YWV,w`vlvî YWV,|ufgî Y[V,`wwhxjdî Y[V,d`w`w}sfvî Y[V,dj`hu`obrppfbwrujdîY[V,dj`hu`orakfbwjdîY[V,drbxofpwf|îPY[V,gf`wxufsrvîOY[V,gm`hvîIY[V,jvvxff|îQY[V,rshxjdîY[V,s`bl`hfîY[V,s`u`ohxjdîY[V,si`vfvîLY[V,ufvrxubfirxuvîKY[V,ufvrxubfw`amfvîY[V,urmff|wu`îY[V,vbfp`ujrîY[V,vp`svirwîMY[V,vwfufrw}sfîY[V,vw}mfvîY[V,v}vwfow`hhfdz`mxfvîJY[V,w`amfmjvwîY[V,w`amfmjvwf|îNY[V,w`amfvîY[V,wfvww`amfvîRY[V,wu|w}sfvîY[V,xvfuvfbxujw}î`vvrbj`wjrpî`wwjdîbifblrakfbww}sfvîbm`vvjgjfuîbm`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`amfî0m`phdwX[î1p`ofvs`bfî2prdfvwfufrî3rakfbws`ufpwî4rakfbwvbrsfî5rsfu`wjrpbrdfî6rssrvî7rsvbmf`pî8rusi`pvYVî9s`bl`hfbrpwurmî:s`bl`hfvî;s`u`ojd|î<tdg,X[î=txfu}dfgv,WW\î>urmfbrpvwu`jpwvî?uwggjfmdvî@uxpvw`wfîAvwfufrw}sfvîBvw}mfvîCw`hhfdz`mvîDwsrvîEzfuvjrpîFzfuvjrpd`wfîG{favwfufrîHŒ{ãá@aø¯æ2â@t_diagramtypesò@Ú;;;///////- ÿ@” {ãá@ú‘I(n üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVC˜<Nññ  ä2  äÿÿ2 ä ä TableNameNewNameRelOrderFixCodeÿÿè{ö "ð9䯍–tR,üÔ¶˜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ÿÿè{ö@@gô寥„iN?"îÙ´•~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^NøøX^  ä2 ä  ä2  ä2  ä2 TableNameRelOrder DisplayNameFromVerToVerÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøü ÿÿÿÿ PrimaryKeyÿÿa{öq)÷(Î\.ùË”i)øÃ™b7ߪyQ,ýÛ«ƒ`)þÜ©„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@ Þ¼‰d5úÌœh<Õ¦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ß©†]5÷t_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,`wwujaxwfùw,`wwujaxwfbrpvwu`jpwvùw,`wwujaxwfw`hùw,`xwiruvùw,b`udjp`mjw}ùw,b`wfhru}û w,bmjfpwvùw,brosmf|jw}w}sfvùw,brppfbwruùw,brppfbwrubrpvwu`jpwùw,brppfbwruw`hù w,brppfbwruw}sfvù w,brpvw`pwvù w,brpvwu`jpww}sfvù w,d`w`w}sfvù w,dj`hu`oùw,dj`hu`omjplvùw,dj`hu`orakfbwvùw,dj`hu`ow}sfvùw,drbxofpwùw,fbgùw,fggruww}sfvùw,gjmfvùw,hfprswùw,hmrvv`u}ùw,iwomû w,jo`hfùw,josmfofpwùw,jvvxfvùw,mjvwvùw,o`jpww}sfvùw,ofwirdùw,ofwujbw}sfvùw,rakfbwùw,rakfbwbrpvwu`jpwù w,rakfbwfggruwù!w,rakfbwgjmfvù"w,rakfbwofwujbvù#w,rakfbwsuramfovù$w,rakfbwsursfuwjfvù%w,rakfbwuftxjufvù&w,rakfbwufvrxubfù'w,rakfbwujvlvúw,rakfbwvbfp`ujrvúw,rakfbwwfvwvúw,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,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,vp`svirwû w,vw`wxvw}sfvú!w,vwfufrw}sfvú"w,w`hhfdz`mxfûw,w`vlvú#w,wbgú$w,wfosm`wfú%w,wfvwbm`vvú&w,wfvwsm`pvú'w,wfvww}sfvú(w,wu|w}sfvûw,xoms`wwfupûw,zfuvjrpûw,|ufgûw,|ufgv}vwfoûw,|ufgxvfuûxv}v,v}vwfoûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(ÈÈÈÈÈÈÈÈÈÈÈ™<ë—J¸k¹^ @€ @€ @€ @€ @€ @€ @€ @€ @€$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{öqìgâ]    ÿ ÑšÈÈÈÇŽUãªqqÆ=  Æ Æ ÆÕ¡m9 ÿ +Persistence€NULL#;*Multiplicity€NULL$;)EventFlags€NULL";(ActionFlags€NULL#;'PackageFlags€NULL$;&StateFlags€NULL";%IsActive€0;$IsSpec€0;#IsLeaf€0;"IsRoot€0;!RunState€NULL ; Phase€'1.0' ;Header2€NULL;Header1€NULL;GenLinks€NULL ;GenFile€NULL;GenType€'Java'!;Fontcolor€-1;Backcolor€-1;BorderWidth€-1!;Bordercolor€-1!;PDATA5€NULL;ModifiedDate€#2003-08-22 13:36:21#5;Tagged€0;Classifier_guid€NULL'; P|ÿÿÿlÆ"ÿÿÿDUID=1CE36E20;/!ÿ 0Oßþÿÿy­þÿÿDUID=81FBAF85;/!ÿ 0Nxÿÿÿ.ˆFÿÿÿDUID=31760B86;/!ÿ 0Mßþÿÿžø­þÿÿDUID=EE2397B7;/!ÿ 0Lßþÿÿq­þÿÿDUID=DFC93F21;/!ÿ 0Hàþÿÿ‘ë®þÿÿDUID=E585EE32;/!ÿ 0GwÿÿÿòEÿÿÿDUID=3D79E0A4;/!ÿ DÿÿÿoÉþÿÿDUID=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!ÿ <™ÿÿÿgSÿÿÿDUID=CDDEF3BC;LBL=;4!ÿÂРg3ΞL9&å¦rAâ¶„Mþ ä ä  äÿ ä ä  ä  ä2ÿ ä  ä  ä  äÿ  äÿ  ä  ä  ä  ä  äIdParentIdNameType DateCreate DateUpdateOwnerFlagsDatabaseConnect ForeignName RmtInfoShort RmtInfoLongLvLvPropLvModuleLvExtraÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿId ParentIdName        ÿÿ¡ÈE(nSâ@t_objectproblemsS@ä===1111111/ ÿ@ê;R.{ãá@–U°æ2â@t_objectmetricsñ@ã<<<0000000. ÿ@çôÕ-{ãá@gøï¯2â@t_objectfilesÖ@ã:::......., ÿ@ãŠ-{ãá@–U°æ2â@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+€Package€t_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€"") o LVAL¬öhowBorder ÿÿÿÿ   Yes/No  Yes  jlShowPackageContents ÿÿÿÿ   Yes/No  Yes  jN PDATA ÿÿÿÿ     mT Locked ÿÿÿÿ   Yes/No  jM Name ^     mO Author À     mP ea_guid ÿÿÿÿ     mK'~oüíÞk\MÚËXI:+¸©š' –‡xöçteVãÔÅRC4Á²£Òÿÿ Ïÿÿ ÏÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Ïÿþ Ìÿÿ ÌÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Ìÿÿ Éÿÿ ÉÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Éÿÿ Çÿÿ ÇÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Çÿþ ¾ÿÿ ¾ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ¾ÿÿ ¸ÿÿ ¸ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ¸ÿÿ ´ÿÿ ´ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ´ÿÿ ±ÿÿ ±ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ±ÿþ ¬ÿÿ ¬ÿÿ ¬ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o §ÿÿ §ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o §ÿÿ ¤ÿÿ ¤ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ¤ÿþ Ÿÿÿ ŸÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Ÿÿÿ šÿÿ šÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o âLVAL Ä<¹Të€2áX%KKD€Required! PermissionID #PermissionName KKD€Required UserID  EntityType EntityID  Timestamp KKD€Required GroupID ! PermissionID KKD€Required GroupID  GroupName KKD€RequiredScriptID  ScriptName  Script KKD€Required RuleID RuleName RuleType KKD€Required ListID Category  Name KKD€Required FileID  AppliesTo Category  Name KKD€Required 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Ã<ñ¡,ÇVæ33Â3ÂÄÄÁvvÁvÁvÁvÁvÁKKDi€ AccessVersionBuildTrack Name AutoCorrect InfoPerform Name AutoCorrectProjVer EADiffViewso  07.53    & t_datatypes|t_object|t_packageKKD€Required PhaseID  PhaseName KKD€Required PropertyID  ElementID  BaseClass KKD~€ ColumnWidth ColumnHidden RecordLocks ODBCTimeout MaxRecords RecordsetTypeFilterOrderBy OrderByOn Replicable1  <  KKD€Required ElementID  VersionID   ElementType KKD€Required PatternID   PatternName  PatternXML KKD€Required PlanID  Name TestPlan KKD€Required TemplateID ! TemplateType ! TemplateName KKD€Required UserID ! PermissionID KKD€Required UserID  GroupID KKD€Required UserID  UserLogin  FirstName  Surname KKD€RequiredProperty  Value KKDÛ€ OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValueFilterOrderByValidationRuleValidationText DescriptionFormat InputMaskCaption U Diagram_Type ž     m\ Package_ID Ì   ÿ  0  mM Name ¼     m£LVALddŵµÄ% &&&'''((())), &, ', (- )- *- +. ,. -. ./ ///00011122 2 3 3 3 444555666€%€€€€€€€€€€€€€€€ €!€"€#€$€$ €$!€$"€9€9€9€>€>€>€E#€E$€E%€J&€J€J€N€N€N€S€S€S€V€V €V €\ €\ €\ €m€m€KKDi€ AccessVersionBuildTrack Name AutoCorrect InfoPerform Name AutoCorrectProjVer EADiffViewsT  07.53     tmpKKD€Required 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&LVAL2®Gh)Ü‘JÚ¤m4ÿÉX"ç°t=ü¿ƒEņG ËUC»X}‹Sâ@C»X}‹Sâ@t_objecttrx*********** ¿C»X}‹Sâ@C»X}‹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   mÿ1>>>22222220 ÿ@â;1{ãá@–U°æ2â@t_objectrisks‰@0:::......., ÿ@Ç/{ãá@–U°æ2â@t_objectrequiresû@/===1111111/ ÿ@Zb Õìá@–U°æ2â@t_objectpropertiesi@/???33333331 ÿ@þ¥ /{ãá@¡ÈE(nSâ@t_objectproblemsS@.===1111111/ ÿ@ù;R.{ãá@–U°æ2â@t_objectmetricsñ@.<<<0000000. ÿ@öôÕ-{ãá@gøï¯2â@t_objectfilesÖ@-:::......., ÿ@íý",{ãá@–U°æ2â@t_objectconstraintä@-???33333331 ÿ@áÇ%{ãá@ŸM—¤¯Sâ@t_objecti*555)))))))' ÿ@Ü­!#{ãá@aø¯æ2â@t_metrictypes@):::......., ÿ@Ò )"{ãá@aø¯æ2â@t_mainttypesr@)999-------+ ÿ@ÏA‰F(nSâ@A‰F(nSâ@t_listse@444(((((((& ÿ@̱$µ×ñá@ümŠÍTâ@t_issuesV@M555)))))))' ÿ@É5N”Uèá@Ôc–Üðá@t_implement2@%888,,,,,,,* ÿ@Ç·'ùï¯2â@·'ùï¯2â@t_image((((((((((& ÿ¸8 {ãá@aø¯æ2â@t_glossaryÅÒ™ @€€ @€€ @ @@@w,vfbxvfusfuojvvjrp$w,vp`svirw>w,vw`wxvw}sfv$w,vwfufrw}sfv$ w,w`hhfdz`mxf>w,w`vlv»w,wbg»w,wfosm`wf»w,wfvwbm`vv»w,wfvwsm`pv»w,wfvww}sfv»w,wu|w}sfv»w,xoms`wwfup»w,zfuvjrp»w,|ufg» w,|ufgv}vwfo» w,|ufgxvfu» xv}v,v}vwfo» xv}vrmdw`amfv» xv}vtxfujfv»xv}vw`amfv»~~,t,josmfofpwvX»~~,t,rusi`pv»`bbfvvm`}rxwov}vdavxoo`u}jpgrxvfudfgjpfd.^Z_g`W\bg]VZZXbZ^Wd[]WZV_YX^X`[d0»s`bl`hfdj`hu`o»^Wd[]WZV_YX^X`[d0»s`bl`hfdj`hu`o»af\aX``Wb[gWXWfX0»s`bl`hfdj`hu`o»af\aX``Wb[gWXWfX0»s`bl`hfdj`hu`o»af\aX``Wb[gWXWfX0»s`bl`hfdj`hu`o»af\aX``Wb[gWXWfX0»s`bl`hfdj`hu`o»af\aX``Wb[gWXWfX0»s`bl`hfdj`hu`o»üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ̤@€@@w,brppfbwruw}sfvw,brppfbwru»w,dj`hu`ow,dj`hu`orakfbwv»(w,dj`hu`ow}sfvw,dj`hu`o»'w,ofwujbw}sfvw,rakfbwofwujbv»w,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ÏÀ±¢/ ó€qbïàÑÂO@1"¯ ‘‚sñâÓ`QBBÂBÂBÂBÂBÂBÂBÂBÂBÂBÂ3À±¢/ €<€ÿÿ <€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o <€þ :€þ 8€ÿÿ 8€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 8€þ 7€ÿÿ 7€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 7€þ € € Û‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o   ÿÿ ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ÿþ þ €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ ÿÿ ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  þ €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ  €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ ìLVALÈÀ4¨@@(êGÿÿÿÿ» (êÿÿÿÿÿ»Hí)Connector)œäObject»aÌObject_1(êGÿÿÿÿ» (êÿÿÿÿÿ»Hí)Connector)œäObject»aÌObject_1(êÿÿÿÿÿ»Hí)Connector)œäObject»aÌObject_1( GÿÿÿÿÛ&†bAttributeÑ1qObject4LVALÖÖÇqÙW¬NKKD~€ 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  <  KKD€TitleAuthorCompanyC db2 Geoffrey Sparks  Sparx SystemsKKD€ KeepLocal T ¸‡b‡‡¹†`† †»…c……Å„„7„ƒjƒ%ƒÚ‚‚C‚÷«i"Ø€Ž€G€×˜YÝÂA‰F(nSâ@A‰F(nSâ@t_templateu@777+++++++) ÿ@­¶òC{ãá@|\B(nSâ@t_stereotypesÞ@;:::......., ÿ@žÖ%F(nSâ@Ö%F(nSâ@t_secpoliciesK@:::......., ÿ@‘¡ÈE(nSâ@Ö%F(nSâ@t_secgroupN@777+++++++) ÿ@sÍÀQÖñá@¯æ'7sâ@t_rtf9@9222&&&&&&&$ ÿ@^FE°Ùìá@–U°æ2â@t_propertytypesÎ@5<<<0000000. ÿ@;áE8{ãá@–U°æ2â@t_operationpres7@6<<<0000000. ÿ@"p*+{ãá@–U°æ2â@t_objecttypesO@2:::......., ÿ@ uµÇfNçá@*§Ÿ¤¯Sâ@t_objectresourced@0===1111111/ ÿ@òŠ-{ãá@–U°æ2â@t_objecteffort@-;;;///////- ÿ@Öf¥"{ãá@ N¸áÓsâ@t_method7@)555)))))))' ÿ@¾“0!{ãá@FuœÜðá@t_html(@%333'''''''% ÿ@§…{ãá@aø¯æ2â@t_ecfœ@222&&&&&&&$ ÿ@ƒ½$lËÿâ@.I(nSâ@t_datatypes@&888,,,,,,,* ÿ@\Ð{ãá@OõÛàÓsâ@t_connectoråW888,,,,,,,* ÿ@E)4{ãá@aø¯æ2â@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`íÞÏ\MÚ˼I:+©š' –‡xöçteVãÔÅRC4Á²Package_IDÿÿpÿÿiÿÿLÿÿeÿÿTÿÿ_ÿÿdÿÿaÿÿl ¢A€ÿÿ A€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o A€þ @€ÿÿ @€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o @€þ ?€ÿÿ ?€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ?€þ >€ÿÿ >€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o >€þ =€ÿÿ =€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o =€þ ;€ÿÿ ;€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ;€þ :€ÿÿ :€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 9€ÿÿ 9€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 9€þ  ô ôÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ô  Û‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  TÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  ÿÿ ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ÿÿ  €ÿÿ  €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#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'~oüíÞk\MÚ˼I:+¸©š' –‡xöçteVãÔÅRC4Á²£€ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ  €ÿÿ  €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  €ÿÿ  €ÿÿ  €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  €ÿÿ  €ÿÿ  €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  €ÿÿ  €ÿÿ  €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  €ÿÿ  Û‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o   Û‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o   TÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 0LVALtèôÐD™]Û×EŸg/ø£ŸDc!ߣfCÑ”Z ì±üÿéÿuÿÿÿÿý €eMethodÕ5qObject^¾nDiagram(©æÿÿÿÿv/&†qt_objecttypes¬ qt_object2’qt_connectorÏ/rObject_1} Ývt_package(êGÿÿÿÿ·&5{ECF(êÿÿÿÿ·ç·M9Ç'Connector0sDiagramObjects[ »tDiagramObjects_1(êÿÿÿÿÿ»Hí)Connector)œäObject»aÌObject_1™LVAL ¥ K³Ô<¤Ãµ×EŸg/ø£Ÿ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_packageBú6Object_1‘ñ}t_objecttypesüÿéÿÁÿÿÿÿº&†qt_objecttests¬ qt_objectüÿéÿÁÿÿÿÿ¾ä&†qt_package¬ qt_objecttypes2’qt_objectþÿÀŽÿÿÿÿ»Ô&†qt_package¬ q"t_object2’qt_diagramobjectsK'~oüíÞk\MÚ˼I:+¸©š' –‡xöçteVãÔÅRC4Á²£€êñT}‹Sâ@êñT}‹Sâ@q_packages!€ÿÿ  €ÿÿ  €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o €ÿÿ €ÿÿ €ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o LVAL(P(4¤ÃÛ×EŸg/ø£ŸDc!ߣf(êGÿÿÿÿ·&†qTCF(êGÿÿÿÿ·&†qTCFa*#[ÿÿÿÿ·&†qECFüÿéÿ»ÿÿÿÿ´&†qObjectResourceéIoObjectüÿéÿÁÿÿÿÿ¾æ&†qt_package¬ qt_objecttypes2’qt_object¸qt_connectorüÿéÿÁÿÿÿÿ¾æ&†qt_package¬ qt_objecttypes2’qt_object¸qt_connectorÒLVALÒ¤ñYÁ)„ì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¨´( @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€     úÿçÿwÿÿÿÿ·ïAØzObjectý…PackagekF˱Diagramúÿçÿvÿÿÿÿý&†qObjectüÿéÿrÿÿÿÿùïAØzObjectý…PackagekF˱Diagramüÿéÿuÿÿÿÿý&†qObjectÌ,oObject_Types(ª§ÿÿÿÿ{ð&§St_ocfºFÏt_package€ Àt_object£LVAL »v1ì§b¯Ô”à @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€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'~oüíÞk\MÚ˼I:+¸©š' –‡xöçteVãÔÅRC4Á²£Jÿÿ Eÿÿ EÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Eÿÿ $ÿÿ $ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o $ÿÿ >ÿÿ >ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o >ÿÿ 9ÿÿ 9ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o 9ÿÿ )€ÿÿ )€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o )€ÿÿ (€ÿÿ (€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o (€ÿÿ '€ÿÿ '€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o '€ÿÿ &€ÿÿ &€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o &€ÿÿ %€ÿÿ %€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o %€ÿÿ $€ÿÿ $€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o $€ÿÿ #€ÿÿ #€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o #€ÿÿ "€ÿÿ "€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o "€ÿÿ !€ÿÿ !€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ²LVALtPÄÄÂ`† †»…c……ʾÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿt_rtfreportIq_packages 6-Î!ÿÿÿÿüÿéÿÁÿÿÿÿ¾• õut_object~rt_diagramobjects&†qt_package(©óÿÿÿÿz<+§Ct_implement+T¨Ýt_package o:Út_objecttypesù rîObject_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^TG°¬F^ F¼p)ßÛDŽ4ÜØC—]Û£g.ö¶|8û¼‚*z+sV}‹Sâ@+sV}‹Sâ@t_constants*********** ¿vöV}‹Sâ@Çf[}‹Sâ@t_connectortypes/////////// ¿röV}‹Sâ@öV}‹Sâ@t_connectortag----------- ¿möV}‹Sâ@öV}‹Sâ@t_connectorconstraint44444444444 ¿\öV}‹Sâ@Çf[}‹Sâ@t_connector*********** ¿VвU}‹Sâ@вU}‹Sâ@t_complexitytypes00000000000 ¿SвU}‹Sâ@вU}‹Sâ@t_clients((((((((((( ¿NвU}‹Sâ@вU}‹Sâ@t_category))))))))))) ¿JвU}‹Sâ@вU}‹Sâ@t_cardinality,,,,,,,,,,, ¿EвU}‹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'~oüíÞk\MÚ˼I:+¸©š' –‡xöçteVãÔÅRC4Á²£šÿÿ •ÿÿ •ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o •ÿÿ Œÿÿ ŒÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Œÿÿ ƒÿÿ ƒÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ƒÿÿ ~ÿÿ ~ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ~ÿÿ zÿÿ zÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o zÿÿ vÿÿ vÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o vÿÿ rÿÿ rÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o rÿÿ mÿÿ mÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o mÿÿ \ÿÿ \ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o \ÿÿ Vÿÿ VÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Vÿÿ Sÿÿ SÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Sÿÿ Nÿÿ NÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Nÿÿ Jÿÿ JÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o LVALV %°¬F^ F¼p)ßÛDŽ4ÜØC}5⣟Bc*ò²x4÷¸~**z+sV}‹Sâ@+sV}‹Sâ@t_constants*********** ¿vöV}‹Sâ@Çf[}‹Sâ@t_connectortypes/////////// ¿röV}‹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 ÿÿÿÿ     mÆLVAL3ÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈ››Ç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;2ƒ³dÏ…?ó¦O½hÉtÑ‚ƒ@ò¤\ Àn @€ @€ @€ @€ @€ @¾DDLSQL Server 2000moneycurrencyD<<<<<<7(% ÿ&&& ½DDLSybasenumericnumeric<555555.(% ÿ¼DDLInterBaseblob sub_type 0blobD@@@@@@1(% ÿ5»DDLSybasedoubledouble:444444.(% ÿ@2ºDDLPostgreSQLvarcharvarchar@9999992(% ÿ¹DDLPostgreSQLintegerinteger@9999992(% ÿ¸DDLDB2FLOATfloat5000000+(% ÿ&& ·DDLPostgreSQLnumericnumeric@9999992(% ÿ†DDLDB2LONG VARCHARtext;777777+(% ÿ¶DDLSQL Server 2000smalldatetimedatetimeLDDDDDD7(% ÿ 2µDDLSQL Server 2000nvarcharnvarcharG??????7(% ÿ´DDLSQL Server 2000imageblob@<<<<<<7(% ÿ@ ³DDLSQL Server 2000binaryBinaryC======7(% ÿ²DDLInterBasedouble precisiondoubleGAAAAAA1(% ÿ@2±DDLSybasevarcharvarchar<555555.(% ÿ°DDLSybasebigintbigint:444444.(% ÿ¯DDLSQL Server 2000timestamptimestampI@@@@@@7(% ÿ@ ®DDLSQL Server 2000charchar?;;;;;;7(% ÿ­DDLSybasesmallintsmallint>666666.(% ÿ¬DDLSybasebinaryblob8444444.(% ÿ55«DDLPostgreSQLrealdouble<6666662(% ÿªDDLInterBasetimestampdatetimeB::::::1(% ÿÿ ©DDLMySqlNCHARnchar7222222-(% ÿ ¨DDLInterBasesmallintsmallintA9999991(% ÿ §DDLInterBaseintegerinteger?8888881(% ÿ\ƒ±XЄ;÷³…gÖ‡D„äƒäÃ@ñ¤V ¿v'Úš^XRLF@:4.(" þøòìæàÚÔÎȼ¶°ª¤ž˜’tructor=pyConInline=ìCodePHPvarvar2//////,)% OÔDDLSQL Server 2000texttext?;;;;;;7(% ÿ55ÓDDLSQL Server 2000realdoubleA;;;;;;7(% ÿÒDDLMSAccessBytetinyint;4444440(% ÿÿ2ÑDDLInterBasevarcharvarchar?8888881(% ÿÐDDLSybasetinyinttinyint<555555.(% ÿÏDDLSybasetimestamptimestamp@777777.(% ÿ 2ÎDDLOracleNVARCHAR2nvarchar?777777.(% ÿ  ÍDDLSQL Server 2000ncharncharA<<<<<<7(% ÿ55ÌDDLSQL 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.(% ÿ55ÁDDLSybaserealreal6222222.(% ÿÀDDLSQL Server 2000uniqueidentifierguidKGGGGGG7(% ÿ¿DDLSQL Server 2000ntextntextA<<<<<<7(% ÿ‡$                         $ %                !"#$%&      !" # $ %!&!!"""###$$ $ % % % &&&'''((())), &, ', (- )- *- +. ,. -. ./ ///00011122 2 3 3 3 444555666€%€€€€€€€€€€€€€€€ €!€"€#€$€$ €$!€$"€9€9€9€>€>€>€E#€E$€E%€J&€J€J€N€N€N€S€S€S€V€V €V €\ €\ €\ €m€m€m€r€r€r€v          ! " # #?#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<€%€€€€€€€€€€€€€€€ €!€"€#€$€$ €$!€$"€9€9€9€>€>€>€E#€E$€E%€J&€J€J€N€N€N€S€S€S€V€V €V €\ €\ €\ €lL€lL€lL€m€m€m€r€r€r€v€v€v€z€z€z€~€~€~€ƒ€ƒ€ƒ€Œ €Ÿ€Ÿ€¤€¤€¤€§€§ €§ €¬ €¬ €¬ €±€±€±€´€´€´€¸€¸€¸€¾€¾€¾€Ç€Ç€Ç€É€É€É€Ì €Ì!€Ì"€Ï#€Ï$€Ï%€Ò&€Ò(€Ò(€Ö(€Ö(€Ö(€Ü(€Ü(€Ü(€á(€á( €á( €í( €í( €í( €ò(€ò(€ò(€ö(€ö(€ö(€ù(€ù(€ù(€þ(€þ(€þ(€(€(€(€(€(€(€ ( € (!€ ("€(#€($€(%€(&€H€H€H€H€H€H€H€H€"H€"H €"H €(H €(H €(H €+H€+H          ! " #ˆLVALذöΜ% &&&'''((())), &, ', (- )- *- +. ,KKDÌ€ValidationRuleValidationTextFilterOrderBy 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*LVALý8TG°¬F^ F¼p)ßÛDŽ4ÜØC}5⣟BKKDÌ€ OrderByOn ColumnWidth ColumnOrder ColumnHiddenRequiredAllowZeroLengthDisplayControlFilterOrderByValidationRuleValidationText DescriptionFormat InputMaskCaption DefaultValue F Meaning     M Term ÿÿÿÿ     mM Type ÿÿÿÿ     mKKDÛ€ValidationRuleValidationTextFilterOrderBy 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'~oüíÞk\MÚ˼I:+¸©š' –‡xöƒteVãÔÅRC4Á²£t_C»X}‹Sâ@C»X}‹Sâ@t_objecttrÿÿ ÿÿ ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ÿÿ  ÿÿ  ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o  ÿÿ ÿÿ ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ÿÿ ÿÿ ÿÿ ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o þÿÿ þÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o þÿÿ ùÿÿ ùÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ùÿÿ öÿÿ öÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o öÿÿ òÿÿ òÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o òÿÿ íÿÿ íÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o íÿÿ áÿÿ áÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o áÿÿ Üÿÿ ÜÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Üÿÿ Öÿÿ ÖÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Öÿÿ Òÿÿ ÒÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o ÆLVALŽWÖ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   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 ÿÿÿÿ    ©LVAL¹KKD€ 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 ÿÿÿÿ     m®LVAL¼KKDÛ€ 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 ÿÿÿÿ      mŽLVAL—œ% &&&'''((())), &, ', (- )- *- +. ,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     mKKDÛ€ValidationRuleValidationTextFilterOrderBy 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 ­   aLVALooÅKKDÛ€ 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 ÿÿÿÿ     mµLVALÓ„Å)Ü‘JFFü¸84Eü´o+âÞC”OüB²fÊ}yA/á¥kC»X}‹Sâ@C»X}‹Sâ@t_objecttrx*********** ¿C»X}‹Sâ@C»X}‹Sâ@t_objecttests,,,,,,,,,,, ¿)¸1{ãá@›RJ(nSâ@t_objectscenarios‘@1>>>22222220 ÿ@â;1{ãá@–U°æ2â@t_objectrisks‰@0:::......., ÿ@Ç/{ãá@–U°æ2â@t_objectrequiresû@/===1111111/KKDŽ€ OrderByOn ColumnWidth ColumnOrder ColumnHidden DescriptionRequiredAllowZeroLengthDisplayControl DecimalPlaces DefaultValue ƒ ObjectType ÿÿÿÿ  0 (Type of Object e.g Actor, UseCase, Class   m•ComplexityWeight ÿÿÿÿ  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 ÿÿÿÿ    ‡$?€Œ!€Œ"€•#€•$€•%€š€š€š&€Ÿ€Ÿ€Ÿ€¤€¤€¤€§€§ €§ €¬ €¬ €¬ €±€±€±€´€´€´€¸€¸€¸€¾€¾€¾€Ç€Ç€Ç€É€É€É€Ì €Ì!€Ì"€Ï#€Ï$€Ï%€Ò&€Ò(€Ò(€Ö(€Ö(€Ö(€Ü(€Ü(€Ü(€á(€á( €á( €í( €í( €í( €ò(€ò(€ò(€ö(€ö(€ö(€ù(€ù(€ù(€þ(€þ(€þ(€(€(€(€(€(€(€ ( € (!€ ("€(#€($€(%€(&€H€H€H€H€H€H€H€H€"H€"H €"H €(H €(H €(H €+H€+H€+H€2H€2H€2H€7H€7H€7H€;H€;H€;H€?H€?H€?H€CH€CH€CH€LH €LH!€LH"€NH#€NH$€NH%€PH&€PI€PI€TI€TI€TI€YI€YI€YI€^I€^I €^I €bI €bI €bI €gI€gI€gI€jI€jI€jI€nI€nI€nI€sI€sI€sI€I€I€I€†I€†I€†I€‰I €‰I!€‰I"€ŽI#€ŽI$€ŽI%€‘I&€‘J€‘J€”J€”J€”J€—J€—J€—J€›J€›J €›J €žJ €žJ €žJ €¡J€¡J€¡J€¤J€¤J€¤J€§J€§J€§J€ªJ€ªJ€ªJ€­J€­J€­J€¹J€¹J€¹J€½J €½J!€½J"€ÂJ#€ÂJ$€ÂJ%€ÅJ&€ÅK€ÅK€ÈK€ÈK€ÈK€ËK€ËK€ËK€ÐK€ÐK €ÐK           ! " #DLVALPöqìgâ]ØSÎIÄ?­ƒ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@ÆNÚŸb%çªp6÷ÉSÞ¥b)ë¯w:ø¼€KKDÌ€ValidationRuleValidationTextFilterOrderBy 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 ÿÿÿÿ     mÔLVALÉöäKKDÛ€ 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 ÿÿÿÿ     m¼LVALtÊ€Œ!€Œ"€•#€•$€•%€š€š€š&€Ÿ€Ÿ€Ÿ€¤€¤€¤€§€§ €§ €¬ €¬ €¬ €±€±€±€´€´€´€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   mLVAL…K€Œ!€Œ"€•#€•$€•%€š€š€š&€Ÿ€Ÿ€Ÿ€¤€¤€¤€§€§ €§ €¬ €¬ €¬ €±€±€±€´€´€´€¸€¸€¸€¾€¾€¾€Ç€Ç€Ç€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‹~oüíÞk\MÚ˼I:+¸©š' –‡xöçtKKDÛ€ 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   m®LVALdA¾€Œ!€Œ"€•#€•$€•%€š€š€š&€Ÿ€Ÿ€Ÿ€¤€¤€¤€§€§ €§ €¬ €¬ €¬ €±€±€±€´€´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  m‹LVALë¾yKKDÌ€ValidationRuleValidationTextFilterOrderBy 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  1¹‡q‡‡ÒŽGE•  ¤¯Sâ@•  ¤¯Sâ@t_snapshot¯@777+++++++) ÿ@B*§Ÿ¤¯Sâ@*§Ÿ¤¯Sâ@t_phaseN@444(((((((& ÿ@lðXª÷„Úðá@Æú|`nôá@usysOldTablesE@=:::......., ÿ@ìrÇAÑñá@–U°æ2âEÿÿ EÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Eÿþ Bÿÿ BÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o Bÿþ lÿÿ lÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o lÿþ +€ÿÿ +€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o +€ÿÿ *€ÿÿ *€ÿÿÛ‡“ O«8ßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKrÌväwl±rßV#jKßV#jKßV#jKßV#jKßV#o žLVALªöKKDÌ€ 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 ÿÿÿÿ     mÒLVAL ÈÈÈÈÈÈÈÈÈÈòâ¬o6ý¼~CËTâ¬p0ò²w ^|-â@þ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)Ü‘JFFü¸84Eü´o+âÞC”OüB²fÊ}yA/á—OC©3{ãá@–U°æ2â@t_objecttrx-@2888,,,,,,,* ÿ@“r2{ãá@FèSßTâ@t_objecttests@:::......., ÿ@)¸1{ãá@›RJ(nSâ@t_objectscenarios‘@1>>>22222220 ÿ@â;1{ãá@–U°æ2â@t_objectrisks‰@0:::......., ÿ@Ç/{ãá@–U°æ2â@t_objectrequiresû@/===1111111/ ÿ@Zb Õìá@–U°æ2â@t_objectpropertiesi@/???33333331 ÿ@þ¥ /{ãá@¡ÈE(nSâ@t_objectproblemsS@.===1111111/ ÿ@ù;R.{ãá@–U°æ2â@t_objectmetricsñ@.<<<0000000. ÿ@öôÕ-{ãá@gøï¯2â@t_objectfilesÖ@-:::......., ÿ@íý",{ãá@–U°æ2â@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 òŒÈÈqìg          ÿ  !!""##$$%%&&''(())*ÿnd â@­såzÚâ@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 â@­såzÚâ@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ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ]_ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ`a6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿbcÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿde7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿfg ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ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 ÿ>*€ñ˜¨à<òá@±T¡uù÷á@zz_q_implements2I@@$@I==1111111/ ÿ@÷xÃhanôá@–U°æ2â@usysTables’@@777+++++++) ÿ@>ðXª÷„Úðá@Æú|`nôá@usysOldTablesE@=:::......., ÿ@ìrÇAÑñá@–U°æ2â@usys_system-@=888,,,,,,,* ÿ@æA‰F(nSâ@A‰F(nSâ@t_xrefuser++++++++++) ÿàA‰F(nSâ@A‰F(nSâ@t_xrefsystem----------+ ÿÚ+ì·kº2â@+ì·kº2â@t_xref''''''''''% ÿÖvæF(nSâ@væF(nSâ@t_versionp@666*******( ÿ@ÔA‰F(nSâ@A‰F(nSâ@t_umlpatternq@999-------+ ÿ@>ËG{ãá@–U°æ2â@t_testtypesƒ@<888,,,,,,,* ÿ@ÈA‰F(nSâ@A‰F(nSâ@t_testplanse@888,,,,,,,* ÿ@Å`F{ãá@–U°æ2â@t_testclass#@<888,,,,,,,* ÿ@½f)E{ãá@–U°æ2â@t_tcfœ@<222&&&&&&&$ ÿ@¹³,¬ ô1â@¡ÈE(nSâ@t_tasks((((((((((& ÿ LVAL¬ÈÈ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ ÷ÿ¹aÿÿÿÿ·= ³“ t_objectt_object“}ït_methodt_method-Mt_connectortypest_connectortypes¸qt_connectort_connectorP °ft_metrictypest_metrictypesÿ_st_objectmetricst_objectmetricsÉf)Ñt_diagramt_diagram#fƒÑt_diagramobjectst_diagramobjectsqyÑät_object_1t_object¸~ét_attributet_attributes¬Óùt_diagramtypest_diagramtypesT´‚t_packaget_package2Ï·m$Ú”Hÿ   ÿ Àrob€€ate'{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:+ ôLVALÈâNÿÿÿ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_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 ÿÿÿÿ     mËLVALŸ>ÝÝÆNAAÿÿ!****!!!!!!!!  !  !  !  !  !!!!!!!!!!!!!!!!!!!  !!!!""!##!$$!%%!&&!''!((!))!**!++*,*-*.*/*0*1*2*3*4* 5* 6* 7* 8* 9*:*;*<*=*>*?*@*A*B*****ÿ!'37€t_object.ActionFlags(36€t_object.StateFlags'35€t_object.IsActive%34€t_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;&ÚhÐ88Æ-ÿ-     ÿNULL$;&StateFlags€NULL";%IsActive€0;$IsSpec€0;#IsLeaf€0;"IsRoot€0;nd\@-ndt_packagendt_objectt_object_1ndt_diagramobjectsndt_objectt_objectt_package*@-%?t_objectt_object_1*@-&?t_objectt_diagramobjects/@-, ?B€t_object.Classifier_guid,3A€t_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)39€t_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_IDÿÿÿÿÿÿäÿÿÿÿÿÿÿÿÿÿÿÿT›œÿÿoÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›ž ÿÿÿÿÿÿÿÿÿÿÿÿ DiagramIDObjectID PrimaryKeyÿÿ-81D5-714093282A5D} DiagramIDObjectID PrimaryKeyÿÿSELECT 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/@, ?B€t_object.Classifier_guid,3A€t_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 >DÿÿÿÿSource -> DestinationGeneralizationPublicPublicSX=-24;SY=-16;{E824691D-2AE7-4c9c-8408-881A2B85516F}¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸’„„„„„„„„„„„„„„„„„„„„„„„„„~~~xxxjjUU5• ü?àQ B<ÿÿÿÿ;**Source -> DestinationAssociationPublic0..*PublicUnspecifiedUnspecified0{A9112D1C-DCB6-4040-B466-D5F560898B33}homeÆÂœœœœœœœ›››››››››……………{{uuujjUUÿ5•†Ã ü¿ÀQ <Aÿÿÿÿ;**Source -> DestinationAssociationPublic1PublicUnspecifiedUnspecified0SX=8;SY=5;EX=8;EY=5;{161BF4FA-8F48-441f-AF1F-D36014D57A1F}bathroomÛÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ­™™™™™™˜˜˜˜˜˜˜˜˜‚‚‚‚‚|{{uuujjUUÿ5•†Ã ü¿à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åàÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙ³““““““’’’’’’’’’‡‡‡‡‡|||||vuuonnccUUÿ5Նà ü¿à €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êåáááááááááááááááợ£££££¢¢¢¢¢¢¢¢¢—————ŒŒŒŒŒ†……{ujjUUÿ5õ†Ã ü¿à€ƒ­]ºg†Ù‘Cûª`Íy'àBñ¦]Êjd^XRLF@:4.(" þøòìæàÚÔÎȼ¶°ª¤ž˜’Œ†€ztnhb\VPJD>82,& üöðêäÞØÒÌÆÀ@@ ëDDLInterBasedecimaldecimal?8888881(% ÿêDDLSybasebitboolean8111111.(% ÿéDDLPostgreSQLbyteablob;7777772(% ÿÿ2èDDLMySqlNVARCHARnvarchar=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-(% ÿ@2ÙDDLSQL Server 2000varcharvarcharE>>>>>>7(% ÿØDDLSQL Server 2000smallintsmallintG??????7(% ÿ×DDLPostgreSQLnumbercurrency@8888882(% ÿÖDDLPostgreSQLsmallintsmallintB::::::2(% ÿÕDDLSQL Server 2000tinyinttinyintE>>>>>>7(% ÿyLVALdÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈ™2ËdââÅâÅ•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=;|•¾¾Ç|:ø¶t22Æ2Æð®l*è¦ÿ      ÿ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.6.6/test/testmodel/class_model_checker.rb0000644000175000017500000001216312243455557020140 0ustar ssmssmrequire '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.6.6/test/template_language_test/0000755000175000017500000000000012243455557016354 5ustar ssmssmrgen-0.6.6/test/template_language_test/testout.txt0000644000175000017500000000110512243455557020621 0ustar ssmssm 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.6.6/test/template_language_test/templates/0000755000175000017500000000000012243455557020352 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/template_resolution_test/0000755000175000017500000000000012243455557025507 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/template_resolution_test/test.tpl0000644000175000017500000000015612243455557027211 0ustar ssmssm<% define 'Test', :for => Object do %> <% expand 'sub1::Sub1' %> <% expand 'sub1/sub1::Sub1' %> <% end %>rgen-0.6.6/test/template_language_test/templates/template_resolution_test/sub1/0000755000175000017500000000000012243455557026361 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/template_resolution_test/sub1/sub1.tpl0000644000175000017500000000010012243455557027743 0ustar ssmssm<% define 'Sub1', :for => Object do %> Sub1 in sub1 <% end %>rgen-0.6.6/test/template_language_test/templates/template_resolution_test/sub1.tpl0000644000175000017500000000030212243455557027075 0ustar ssmssm<% define 'Sub1', :for => Object do %> Sub1 <% end %> <% define 'Test', :for => Object do %> <% expand 'Sub1' %> <% expand 'sub1::Sub1' %> <% expand 'sub1/sub1::Sub1' %> <% end %> rgen-0.6.6/test/template_language_test/templates/root.tpl0000644000175000017500000000152412243455557022060 0ustar ssmssm<% 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.6.6/test/template_language_test/templates/null_context_test.tpl0000644000175000017500000000071212243455557024650 0ustar ssmssm<% 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.6.6/test/template_language_test/templates/no_indent_test/0000755000175000017500000000000012243455557023366 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/no_indent_test/test3.tpl0000644000175000017500000000024212243455557025147 0ustar ssmssm<% define 'Test', :for => Object do %> <%iinc%> l1<% expand 'Call1' %> <%idec%> <% end %> <% define 'Call1', :for => Object do %> <--- l2 <% end %> rgen-0.6.6/test/template_language_test/templates/no_indent_test/test2.tpl0000644000175000017500000000041512243455557025150 0ustar ssmssm<% 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.6.6/test/template_language_test/templates/no_indent_test/test.tpl0000644000175000017500000000104212243455557025063 0ustar ssmssm<% 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.6.6/test/template_language_test/templates/no_indent_test/sub1/0000755000175000017500000000000012243455557024240 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/no_indent_test/sub1/no_indent.tpl0000644000175000017500000000010612243455557026733 0ustar ssmssm<% define 'NoIndent', :for => Object do %> <---<%nows%> <% end %> rgen-0.6.6/test/template_language_test/templates/no_indent_test/no_indent.tpl0000644000175000017500000000010612243455557026061 0ustar ssmssm<% define 'NoIndent', :for => Object do %> <---<%nows%> <% end %> rgen-0.6.6/test/template_language_test/templates/no_backslash_r_test.tpl0000644000175000017500000000031512243455557025101 0ustar ssmssm<% 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.6.6/test/template_language_test/templates/index/0000755000175000017500000000000012243455557021461 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/index/chapter.tpl0000644000175000017500000000013112243455557023623 0ustar ssmssm<% define 'Root' do |idx, doc| %> <%= idx%> <%= title %> in <%= doc.title %> <% end %>rgen-0.6.6/test/template_language_test/templates/index/c/0000755000175000017500000000000012243455557021703 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/index/c/cmod.tpl0000644000175000017500000000006412243455557023346 0ustar ssmssm<% define 'cmod' do %>Module C is special !<% end %>rgen-0.6.6/test/template_language_test/templates/indent_string_test.tpl0000644000175000017500000000042112243455557024776 0ustar ssmssm<% 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.6.6/test/template_language_test/templates/evaluate_test/0000755000175000017500000000000012243455557023217 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/evaluate_test/test.tpl0000644000175000017500000000030212243455557024712 0ustar ssmssm<% 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.6.6/test/template_language_test/templates/define_local_test/0000755000175000017500000000000012243455557024015 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/define_local_test/test.tpl0000644000175000017500000000026412243455557025517 0ustar ssmssm<% define 'Test', :for => Object do %> <% expand 'local::CallLocal1' %> <% end %> <% define 'TestForbidden', :for => Object do %> <% expand 'local::Local1' %> <% end %> rgen-0.6.6/test/template_language_test/templates/define_local_test/local.tpl0000644000175000017500000000023112243455557025624 0ustar ssmssm<% define 'CallLocal1', :for => Object do %> <% expand 'Local1' %> <% end %> <% define_local 'Local1', :for => Object do %> Local1 <% end %> rgen-0.6.6/test/template_language_test/templates/content/0000755000175000017500000000000012243455557022024 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/content/chapter.tpl0000644000175000017500000000012612243455557024172 0ustar ssmssm<% define 'Root', :for => Chapter do %> *** <%= title %> ***<%nows%> <% end %>rgen-0.6.6/test/template_language_test/templates/content/author.tpl0000644000175000017500000000030512243455557024045 0ustar ssmssm<% define 'Author', :for => Author do %> <% expand 'SubAuthor' %> <% end %> <% define 'SubAuthor', :for => Author do %> <%= name %>, EMail: <%= email.sub('@','(at)') %><%nows%> <% end %> rgen-0.6.6/test/template_language_test/templates/code/0000755000175000017500000000000012243455557021264 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/code/array.tpl0000644000175000017500000000060112243455557023120 0ustar ssmssm<% 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.6.6/test/template_language_test/templates/callback_indent_test/0000755000175000017500000000000012243455557024506 5ustar ssmssmrgen-0.6.6/test/template_language_test/templates/callback_indent_test/b.tpl0000644000175000017500000000016112243455557025446 0ustar ssmssm<% define 'do_callback', :for => Object do %> <%iinc%> <% expand 'a::callback' %> <%idec%> <% end %> rgen-0.6.6/test/template_language_test/templates/callback_indent_test/a.tpl0000644000175000017500000000034312243455557025447 0ustar ssmssm<% 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.6.6/test/template_language_test/indentStringTestTabIndent.out0000644000175000017500000000001112243455557024176 0ustar ssmssm <- tab rgen-0.6.6/test/template_language_test/indentStringTestDefaultIndent.out0000644000175000017500000000003012243455557025055 0ustar ssmssm <- your default here rgen-0.6.6/test/template_language_test/expected_result3.txt0000644000175000017500000000023012243455557022372 0ustar ssmssmThis 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.6.6/test/template_language_test/expected_result2.txt0000644000175000017500000000013212243455557022372 0ustar ssmssmint myArray[5] = { 1, 2, 3, 4, 5 }; Text from Root Text from Root rgen-0.6.6/test/template_language_test/expected_result1.txt0000644000175000017500000000110512243455557022372 0ustar ssmssm 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.6.6/test/template_language_test.rb0000644000175000017500000001433512243455557016707 0ustar ssmssm$:.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.6.6/test/rgen_test.rb0000644000175000017500000000133112243455557014154 0ustar ssmssm$:.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.6.6/test/reference_resolver_test.rb0000644000175000017500000001022412243455557017101 0ustar ssmssm$:.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.6.6/test/qualified_name_resolver_test.rb0000644000175000017500000000737212243455557020120 0ustar ssmssm$:.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.6.6/test/qualified_name_provider_test.rb0000644000175000017500000000247512243455557020110 0ustar ssmssm$:.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.6.6/test/output_handler_test.rb0000644000175000017500000000300212243455557016253 0ustar ssmssm$:.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.6.6/test/model_fragment_test.rb0000644000175000017500000000133112243455557016204 0ustar ssmssm$:.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.6.6/test/model_builder_test.rb0000644000175000017500000000033712243455557016034 0ustar ssmssm$:.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.6.6/test/model_builder/0000755000175000017500000000000012243455557014445 5ustar ssmssmrgen-0.6.6/test/model_builder/test_model/0000755000175000017500000000000012243455557016604 5ustar ssmssmrgen-0.6.6/test/model_builder/test_model/statemachine1.rb0000644000175000017500000000132212243455557021655 0ustar ssmssmstatemachine "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.6.6/test/model_builder/statemachine_metamodel.rb0000644000175000017500000000225212243455557021467 0ustar ssmssm# 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.6.6/test/model_builder/serializer_test.rb0000644000175000017500000000455412243455557020212 0ustar ssmssm$:.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.6.6/test/model_builder/reference_resolver_test.rb0000644000175000017500000001201112243455557021703 0ustar ssmssm$:.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.6.6/test/model_builder/ecore_original_regenerated.rb0000644000175000017500000002314412243455557022324 0ustar ssmssmePackage "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.6.6/test/model_builder/ecore_original.rb0000644000175000017500000003064312243455557017761 0ustar ssmssmePackage "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.6.6/test/model_builder/ecore_internal.rb0000644000175000017500000002351412243455557017770 0ustar ssmssmePackage "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 => ["EClassifier", "ETypedElement", "EEnumLiteral", "EPackage"], :instanceClassName => "RGen::ECore::ENamedElement" do eAttribute "name", :eType => "" end eClass "ETypedElement", :abstract => false, :interface => false, :eSubTypes => ["EOperation", "EStructuralFeature", "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"], :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, :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, :eSuperTypes => ["EClassifier"], :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, :eSuperTypes => ["EStructuralFeature"], :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, :eSuperTypes => ["EClassifier"], :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.6.6/test/model_builder/builder_test.rb0000644000175000017500000002050212243455557017456 0ustar ssmssm$:.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.6.6/test/model_builder/builder_context_test.rb0000644000175000017500000000362612243455557021232 0ustar ssmssm$:.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.6.6/test/method_delegation_test.rb0000644000175000017500000001317012243455557016700 0ustar ssmssm$:.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.6.6/test/metamodel_roundtrip_test/0000755000175000017500000000000012243455557016753 5ustar ssmssmrgen-0.6.6/test/metamodel_roundtrip_test/using_builtin_types_serialized.ecore0000644000175000017500000000266212243455557026312 0ustar ssmssm rgen-0.6.6/test/metamodel_roundtrip_test/using_builtin_types.ecore0000644000175000017500000000265212243455557024076 0ustar ssmssm rgen-0.6.6/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb0000644000175000017500000000246012243455557024455 0ustar ssmssmrequire '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_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.6.6/test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore0000644000175000017500000003730512243455557025262 0ustar ssmssm
rgen-0.6.6/test/metamodel_roundtrip_test/houseMetamodel.ecore0000644000175000017500000000435412243455557022753 0ustar ssmssm
rgen-0.6.6/test/metamodel_roundtrip_test/TestModel_Regenerated.rb0000644000175000017500000001211312243455557023503 0ustar ssmssmrequire '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_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.6.6/test/metamodel_roundtrip_test/TestModel.rb0000644000175000017500000001212612243455557021202 0ustar ssmssmrequire '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_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.6.6/test/metamodel_roundtrip_test.rb0000644000175000017500000000636712243455557017314 0ustar ssmssm$:.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::EFloat), RGen::ECore::EAttribute.new(:name => "a4", :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::EFloat, a3.eType) a4 = env.find(:class => RGen::ECore::EAttribute, :name => "a4").first assert_equal(RGen::ECore::EBoolean, a4.eType) end end rgen-0.6.6/test/metamodel_order_test.rb0000644000175000017500000001303412243455557016366 0ustar ssmssm$:.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.6.6/test/metamodel_from_ecore_test.rb0000644000175000017500000000345512243455557017401 0ustar ssmssm$:.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 end rgen-0.6.6/test/metamodel_builder_test.rb0000644000175000017500000011475212243455557016712 0ustar ssmssm$:.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 '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 'oneChild', ContainedClass, 'parentOne' contains_many_uni 'manyChildUni', ContainedClass contains_many 'manyChild', ContainedClass, 'parentMany' 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 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_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 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_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 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 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_nil b.eContainer assert_nil b.eContainingFeature a.oneChildUni = b assert_equal a, b.eContainer assert_equal :oneChildUni, b.eContainingFeature a.oneChildUni = c assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal a, c.eContainer assert_equal :oneChildUni, c.eContainingFeature a.oneChildUni = nil assert_nil c.eContainer assert_nil c.eContainingFeature end def test_container_many_uni a = mm::ContainerClass.new b = mm::ContainedClass.new c = mm::ContainedClass.new a.addManyChildUni(b) assert_equal a, b.eContainer assert_equal :manyChildUni, b.eContainingFeature a.addManyChildUni(c) assert_equal a, c.eContainer assert_equal :manyChildUni, c.eContainingFeature a.removeManyChildUni(b) assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal a, c.eContainer assert_equal :manyChildUni, c.eContainingFeature a.removeManyChildUni(c) assert_nil c.eContainer assert_nil c.eContainingFeature 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 c.oneChild = d assert_equal c, d.eContainer assert_equal :oneChild, d.eContainingFeature a.oneChild = d assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal a, d.eContainer assert_equal :oneChild, d.eContainingFeature 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 c.oneChild = d assert_equal c, d.eContainer assert_equal :oneChild, d.eContainingFeature d.parentOne = a assert_nil b.eContainer assert_nil b.eContainingFeature assert_equal a, d.eContainer assert_equal :oneChild, d.eContainingFeature 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 a.oneChild = nil assert_nil b.eContainer assert_nil b.eContainingFeature 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 b.parentOne = nil assert_nil b.eContainer assert_nil b.eContainingFeature 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 a.removeManyChild(b) assert_nil b.eContainer assert_nil b.eContainingFeature 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 d.addManyChild(b) assert_equal d, b.eContainer assert_equal :manyChild, b.eContainingFeature end def test_conainer_many_bi_steal_ref 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 b.parentMany = d assert_equal d, b.eContainer assert_equal :manyChild, b.eContainingFeature 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 end rgen-0.6.6/test/json_test.rb0000644000175000017500000001452212243455557014200 0ustar ssmssm$:.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.6.6/test/environment_test.rb0000644000175000017500000000441712243455557015575 0ustar ssmssm$:.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.6.6/test/ecore_self_test.rb0000644000175000017500000000374412243455557015341 0ustar ssmssm$:.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.6.6/test/ea_serializer_test.rb0000644000175000017500000000133512243455557016043 0ustar ssmssm$:.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.6.6/test/ea_instantiator_test.rb0000644000175000017500000000211712243455557016410 0ustar ssmssm$:.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.6.6/test/array_extensions_test.rb0000644000175000017500000000310012243455557016612 0ustar ssmssm$:.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.6.6/lib/0000755000175000017500000000000012243455557011426 5ustar ssmssmrgen-0.6.6/lib/transformers/0000755000175000017500000000000012243455557014153 5ustar ssmssmrgen-0.6.6/lib/transformers/uml13_to_ecore.rb0000644000175000017500000001070512243455557017323 0ustar ssmssmrequire '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.6.6/lib/transformers/ecore_to_uml13.rb0000644000175000017500000000521612243455557017324 0ustar ssmssmrequire '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.6.6/lib/rgen/0000755000175000017500000000000012243455557012361 5ustar ssmssmrgen-0.6.6/lib/rgen/util/0000755000175000017500000000000012243455557013336 5ustar ssmssmrgen-0.6.6/lib/rgen/util/pattern_matcher.rb0000644000175000017500000002341012243455557017043 0ustar ssmssmmodule 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.6.6/lib/rgen/util/name_helper.rb0000644000175000017500000000124412243455557016143 0ustar ssmssm# 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.6.6/lib/rgen/util/model_dumper.rb0000644000175000017500000000104712243455557016341 0ustar ssmssmmodule 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.6.6/lib/rgen/util/model_comparator_base.rb0000644000175000017500000000663212243455557020213 0ustar ssmssmrequire '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.6.6/lib/rgen/util/model_comparator.rb0000644000175000017500000000400112243455557017205 0ustar ssmssmrequire '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.6.6/lib/rgen/util/method_delegation.rb0000644000175000017500000000537612243455557017351 0ustar ssmssmmodule 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.6.6/lib/rgen/util/file_change_detector.rb0000644000175000017500000000455512243455557020011 0ustar ssmssmrequire '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.6.6/lib/rgen/util/file_cache_map.rb0000644000175000017500000000705612243455557016572 0ustar ssmssmrequire '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.6.6/lib/rgen/util/cached_glob.rb0000644000175000017500000000344312243455557016101 0ustar ssmssmmodule 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.6.6/lib/rgen/util/auto_class_creator.rb0000644000175000017500000000176212243455557017545 0ustar ssmssm# 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.6.6/lib/rgen/transformer.rb0000644000175000017500000005066612243455557015265 0ustar ssmssmrequire '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.6.6/lib/rgen/template_language/0000755000175000017500000000000012243455557016037 5ustar ssmssmrgen-0.6.6/lib/rgen/template_language/template_helper.rb0000644000175000017500000000052312243455557021536 0ustar ssmssm# 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.6.6/lib/rgen/template_language/template_container.rb0000644000175000017500000001654512243455557022254 0ustar ssmssm# 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.6.6/lib/rgen/template_language/output_handler.rb0000644000175000017500000000443412243455557021426 0ustar ssmssm# 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.6.6/lib/rgen/template_language/directory_template_container.rb0000644000175000017500000000416112243455557024327 0ustar ssmssm# 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.6.6/lib/rgen/template_language.rb0000644000175000017500000002773512243455557016402 0ustar ssmssm# 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.6.6/lib/rgen/serializer/0000755000175000017500000000000012243455557014532 5ustar ssmssmrgen-0.6.6/lib/rgen/serializer/xml_serializer.rb0000644000175000017500000000434512243455557020116 0ustar ssmssmmodule 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.6.6/lib/rgen/serializer/xmi20_serializer.rb0000644000175000017500000000432712243455557020255 0ustar ssmssmrequire '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::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.6.6/lib/rgen/serializer/xmi11_serializer.rb0000644000175000017500000000574312243455557020260 0ustar ssmssmrequire '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.6.6/lib/rgen/serializer/qualified_name_provider.rb0000644000175000017500000000265612243455557021745 0ustar ssmssmmodule 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.6.6/lib/rgen/serializer/opposite_reference_filter.rb0000644000175000017500000000112312243455557022301 0ustar ssmssmmodule 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.6.6/lib/rgen/serializer/json_serializer.rb0000644000175000017500000000720312243455557020263 0ustar ssmssmmodule 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.6.6/lib/rgen/model_builder/0000755000175000017500000000000012243455557015167 5ustar ssmssmrgen-0.6.6/lib/rgen/model_builder/reference_resolver.rb0000644000175000017500000001050312243455557021372 0ustar ssmssmrequire '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.6.6/lib/rgen/model_builder/model_serializer.rb0000644000175000017500000001730612243455557021054 0ustar ssmssmrequire '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.6.6/lib/rgen/model_builder/builder_context.rb0000644000175000017500000002551712243455557020720 0ustar ssmssmrequire '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.6.6/lib/rgen/model_builder.rb0000644000175000017500000000174612243455557015524 0ustar ssmssmrequire '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.6.6/lib/rgen/metamodel_builder/0000755000175000017500000000000012243455557016036 5ustar ssmssmrgen-0.6.6/lib/rgen/metamodel_builder/module_extension.rb0000644000175000017500000000146612243455557021753 0ustar ssmssmrequire '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.6.6/lib/rgen/metamodel_builder/mm_multiple.rb0000644000175000017500000000065012243455557020710 0ustar ssmssm 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.6.6/lib/rgen/metamodel_builder/intermediate/0000755000175000017500000000000012243455557020510 5ustar ssmssmrgen-0.6.6/lib/rgen/metamodel_builder/intermediate/feature.rb0000644000175000017500000000662012243455557022474 0ustar ssmssmrequire '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, 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.6.6/lib/rgen/metamodel_builder/intermediate/annotation.rb0000644000175000017500000000127012243455557023207 0ustar ssmssmmodule 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.6.6/lib/rgen/metamodel_builder/data_types.rb0000644000175000017500000000371612243455557020527 0ustar ssmssmmodule 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]) end end end rgen-0.6.6/lib/rgen/metamodel_builder/constant_order_helper.rb0000644000175000017500000000664112243455557022755 0ustar ssmssmmodule 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.6.6/lib/rgen/metamodel_builder/builder_runtime.rb0000644000175000017500000000434112243455557021556 0ustar ssmssm# 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 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 def _set_container(container, containing_feature_name) @_container = container @_containing_feature_name = containing_feature_name 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.6.6/lib/rgen/metamodel_builder/builder_extensions.rb0000644000175000017500000005313612243455557022300 0ustar ssmssm# 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 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.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.6.6/lib/rgen/metamodel_builder.rb0000644000175000017500000001712512243455557016371 0ustar ssmssm# 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.6.6/lib/rgen/instantiator/0000755000175000017500000000000012243455557015100 5ustar ssmssmrgen-0.6.6/lib/rgen/instantiator/xmi11_instantiator.rb0000644000175000017500000001144712243455557021172 0ustar ssmssmrequire '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 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.6.6/lib/rgen/instantiator/resolution_helper.rb0000644000175000017500000000207312243455557021171 0ustar ssmssmmodule 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.6.6/lib/rgen/instantiator/reference_resolver.rb0000644000175000017500000001114412243455557021305 0ustar ssmssmrequire '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.6.6/lib/rgen/instantiator/qualified_name_resolver.rb0000644000175000017500000000554512243455557022322 0ustar ssmssmrequire '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.6.6/lib/rgen/instantiator/nodebased_xml_instantiator.rb0000644000175000017500000000676212243455557023043 0ustar ssmssmrequire '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.6.6/lib/rgen/instantiator/json_parser.y0000644000175000017500000000411312243455557017616 0ustar ssmssmclass 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.6.6/lib/rgen/instantiator/json_parser.rb0000644000175000017500000001562512243455557017763 0ustar ssmssm# # 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.6.6/lib/rgen/instantiator/json_instantiator.rb0000644000175000017500000001015412243455557021176 0ustar ssmssmrequire '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.6.6/lib/rgen/instantiator/ecore_xml_instantiator.rb0000644000175000017500000001201312243455557022176 0ustar ssmssmrequire '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 @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 "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.6.6/lib/rgen/instantiator/default_xml_instantiator.rb0000644000175000017500000000563012243455557022534 0ustar ssmssmrequire '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.6.6/lib/rgen/instantiator/abstract_xml_instantiator.rb0000644000175000017500000000376012243455557022715 0ustar ssmssmrequire '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.6.6/lib/rgen/instantiator/abstract_instantiator.rb0000644000175000017500000000327512243455557022036 0ustar ssmssmmodule 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.6.6/lib/rgen/fragment/0000755000175000017500000000000012243455557014164 5ustar ssmssmrgen-0.6.6/lib/rgen/fragment/model_fragment.rb0000644000175000017500000002417412243455557017504 0ustar ssmssmrequire '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 all_child_elements(e, @elements) 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 all_child_elements(element, childs) containment_references(element.class).each do |r| element.getGenericAsArray(r.name).each do |c| childs << c all_child_elements(c, childs) end end end def containment_references(clazz) @@containment_references_cache ||= {} @@containment_references_cache[clazz] ||= clazz.ecore.eAllReferences.select{|r| r.containment} 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.6.6/lib/rgen/fragment/fragmented_model.rb0000644000175000017500000001034512243455557020010 0ustar ssmssmrequire '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.6.6/lib/rgen/fragment/dump_file_cache.rb0000644000175000017500000000355512243455557017610 0ustar ssmssmmodule 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.6.6/lib/rgen/environment.rb0000644000175000017500000000563212243455557015260 0ustar ssmssmmodule 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.6.6/lib/rgen/ecore/0000755000175000017500000000000012243455557013456 5ustar ssmssmrgen-0.6.6/lib/rgen/ecore/ruby_to_ecore.rb0000644000175000017500000000613212243455557016645 0ustar ssmssmrequire '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.6.6/lib/rgen/ecore/ecore_to_ruby.rb0000644000175000017500000001006012243455557016640 0ustar ssmssmrequire '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.6.6/lib/rgen/ecore/ecore_interface.rb0000644000175000017500000000240312243455557017117 0ustar ssmssmmodule 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.6.6/lib/rgen/ecore/ecore_ext.rb0000644000175000017500000000266712243455557015773 0ustar ssmssmrequire '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.6.6/lib/rgen/ecore/ecore_builder_methods.rb0000644000175000017500000000545212243455557020337 0ustar ssmssmmodule 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.6.6/lib/rgen/ecore/ecore.rb0000644000175000017500000002031112243455557015075 0ustar ssmssmrequire '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 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"} 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") 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.6.6/lib/rgen/array_extensions.rb0000644000175000017500000000302412243455557016302 0ustar ssmssm# 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.6.6/lib/mmgen/0000755000175000017500000000000012243455557012531 5ustar ssmssmrgen-0.6.6/lib/mmgen/templates/0000755000175000017500000000000012243455557014527 5ustar ssmssmrgen-0.6.6/lib/mmgen/templates/metamodel_generator.tpl0000644000175000017500000001546112243455557021274 0ustar ssmssm <% 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.6.6/lib/mmgen/templates/annotations.tpl0000644000175000017500000000235312243455557017610 0ustar ssmssm<% 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.6.6/lib/mmgen/mmgen.rb0000644000175000017500000000134612243455557014165 0ustar ssmssm$:.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.6.6/lib/mmgen/mm_ext/0000755000175000017500000000000012243455557014022 5ustar ssmssmrgen-0.6.6/lib/mmgen/mm_ext/ecore_mmgen_ext.rb0000644000175000017500000000473312243455557017516 0ustar ssmssmrequire '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.6.6/lib/mmgen/metamodel_generator.rb0000644000175000017500000000104412243455557017072 0ustar ssmssmrequire '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.6.6/lib/metamodels/0000755000175000017500000000000012243455557013560 5ustar ssmssmrgen-0.6.6/lib/metamodels/uml13_metamodel_ext.rb0000644000175000017500000000116412243455557017757 0ustar ssmssm# 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.6.6/lib/metamodels/uml13_metamodel.rb0000644000175000017500000004545112243455557017106 0ustar ssmssmrequire '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.6.6/lib/ea_support/0000755000175000017500000000000012243455557013607 5ustar ssmssmrgen-0.6.6/lib/ea_support/uml13_to_uml13_ea.rb0000644000175000017500000000605712243455557017275 0ustar ssmssmrequire '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.6.6/lib/ea_support/uml13_ea_to_uml13.rb0000644000175000017500000000635512243455557017276 0ustar ssmssmrequire '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.6.6/lib/ea_support/uml13_ea_metamodel_generator.rb0000644000175000017500000000362312243455557021643 0ustar ssmssmrequire '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.6.6/lib/ea_support/uml13_ea_metamodel_ext.rb0000644000175000017500000000220312243455557020446 0ustar ssmssmmodule 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.6.6/lib/ea_support/uml13_ea_metamodel.rb0000644000175000017500000005205512243455557017600 0ustar ssmssmrequire '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.6.6/lib/ea_support/id_store.rb0000644000175000017500000000117612243455557015751 0ustar ssmssmrequire '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.6.6/lib/ea_support/ea_support.rb0000644000175000017500000000332412243455557016317 0ustar ssmssmrequire '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 end